From 91c69cf5550caf4751d2a55db42bd637265e93fa Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 22 Aug 2015 11:47:37 +0100 Subject: [PATCH 001/191] fixed . instead of , --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 648716ac2..ecf08a120 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ var WebSocket = require( 'ws' ); var Internal = require( "./lib/internal.js" ).Internal; var TokenManager = require( "./lib/TokenManager.js" ).TokenManager; -var serverCreateRequests = [].globalLoginTime = Date.now(); +var serverCreateRequests = [], globalLoginTime = Date.now(); function tp( time ) { return Date.now() - time; From d3d4c68b5ef9ab6b93276a7f228cd7b82e5d8270 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 22 Aug 2015 12:01:15 +0100 Subject: [PATCH 002/191] added user tracking --- index.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/index.js b/index.js index ecf08a120..da7de29ed 100644 --- a/index.js +++ b/index.js @@ -550,6 +550,24 @@ exports.Client.prototype.connectWebsocket = function( cb ) { self.user = newUsr; } + } else if (dat.t === "GUILD_MEMBER_ADD"){ + + var srv = self.getServer( dat.d.guild_id ); + if(srv){ + var usr = new User(dat.d.user); + srv.members.add( usr ); + self.triggerEvent("serverMemberAdd", [usr]); + } + + } else if (dat.t === "GUILD_MEMBER_REMOVE"){ + + var srv = self.getServer( dat.d.guild_id ); + if(srv){ + var usr = new User(dat.d.user); + srv.members.removeElement( usr ); + self.triggerEvent("serverMemberRemove", [usr]); + } + } break; From 6a9905308f91ccff4be610f050caf4e9d35eb237 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 22 Aug 2015 12:45:39 +0100 Subject: [PATCH 003/191] edited out edit listener --- hydrabot/hydrabot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hydrabot/hydrabot.js b/hydrabot/hydrabot.js index 4e3f287f8..4f010266d 100644 --- a/hydrabot/hydrabot.js +++ b/hydrabot/hydrabot.js @@ -64,7 +64,7 @@ hydrabot.on("messageDelete", function(message){ }) hydrabot.on("messageUpdate", function(former, edit){ - + /* if(former){ if(former.author.equals(this.user) || former.content === edit.content){ @@ -77,7 +77,7 @@ hydrabot.on("messageUpdate", function(former, edit){ hydrabot.sendMessage(channel, "**"+former.author.username + "** (edit from message "+seconds+" seconds ago):\n " + former.content); } - + */ }) hydrabot.on( "message", function( message ) { From c42b95aad14b3775921af9f12c911e385df9d8dd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 22 Aug 2015 18:28:31 +0100 Subject: [PATCH 004/191] Switched to VSCode, reformatted --- index.js | 1329 +++++++++++++++++++++++++++--------------------------- 1 file changed, 665 insertions(+), 664 deletions(-) diff --git a/index.js b/index.js index da7de29ed..d8b9a1560 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,21 @@ -var request = require( "superagent" ); -var Endpoints = require( "./lib/endpoints.js" ); -var Server = require( "./lib/server.js" ).Server; -var Message = require( "./lib/message.js" ).Message; -var User = require( "./lib/user.js" ).User; -var Channel = require( "./lib/channel.js" ).Channel; -var List = require( "./lib/list.js" ).List; -var Invite = require( "./lib/invite.js" ).Invite; -var PMChannel = require( "./lib/PMChannel.js" ).PMChannel; -var WebSocket = require( 'ws' ); -var Internal = require( "./lib/internal.js" ).Internal; -var TokenManager = require( "./lib/TokenManager.js" ).TokenManager; +var request = require("superagent"); +var Endpoints = require("./lib/endpoints.js"); +var Server = require("./lib/server.js").Server; +var Message = require("./lib/message.js").Message; +var User = require("./lib/user.js").User; +var Channel = require("./lib/channel.js").Channel; +var List = require("./lib/list.js").List; +var Invite = require("./lib/invite.js").Invite; +var PMChannel = require("./lib/PMChannel.js").PMChannel; +var WebSocket = require('ws'); +var Internal = require("./lib/internal.js").Internal; +var TokenManager = require("./lib/TokenManager.js").TokenManager; -var serverCreateRequests = [], globalLoginTime = Date.now(); +var serverCreateRequests = [], + globalLoginTime = Date.now(); -function tp( time ) { - return Date.now() - time; +function tp(time) { + return Date.now() - time; } /** @@ -42,71 +43,70 @@ exports.PMChannel = PMChannel; * @param {Number} [options.maxmessage=5000] The maximum amount of messages to be stored per channel. */ -exports.Client = function( options ) { +exports.Client = function (shouldUseTokenManager) { - /** - * Contains the options of the client - * @attribute options - * @type {Object} - */ - this.options = options || {}; - this.options.maxmessage = 5000; - this.tokenManager = new TokenManager( "./", "tokencache.json" ); - /** - * Contains the token used to authorise HTTP requests and WebSocket connection. Received when login was successful. - * @attribute token - * @readonly - * @type {String} - */ - this.token = ""; - /** - * Indicates whether the client is logged in or not. Does not indicate whether the client is ready. - * @attribute loggedIn - * @readonly - * @type {Boolean} - */ - this.loggedIn = false; - /** - * The WebSocket used when receiving message and other event updates. - * @type {WebSocket} - * @attribute websocket - * @readonly - */ - this.websocket = null; - /** - * An Object containing the functions tied to events. These should be set using Client.on(); - * @type {Object} - * @attribute events - */ - this.events = {}; - /** - * The User of the Client class, set when the initial startup is complete. - * @attribute user - * @type {User} - * @readonly - */ - this.user = null; - /** - * Indicates whether the Client is ready and has cached all servers it as aware of. - * @type {Boolean} - * @attribute ready - * @readonly - */ - this.ready = false; - /** - * A List containing all the Servers the Client has access to. - * @attribute serverList - * @type {List} - * @readonly - */ - this.serverList = new List( "id" ); - /** - * A List containing all the PMChannels the Client has access to. - * @attribute PMList - * @type {List} - * @readonly - */ - this.PMList = new List( "id" ); + /** + * Contains the options of the client + * @attribute options + * @type {Object} + */ + if (shouldUseTokenManager) + this.tokenManager = new TokenManager("./", "tokencache.json"); + /** + * Contains the token used to authorise HTTP requests and WebSocket connection. Received when login was successful. + * @attribute token + * @readonly + * @type {String} + */ + this.token = ""; + /** + * Indicates whether the client is logged in or not. Does not indicate whether the client is ready. + * @attribute loggedIn + * @readonly + * @type {Boolean} + */ + this.loggedIn = false; + /** + * The WebSocket used when receiving message and other event updates. + * @type {WebSocket} + * @attribute websocket + * @readonly + */ + this.websocket = null; + /** + * An Object containing the functions tied to events. These should be set using Client.on(); + * @type {Object} + * @attribute events + */ + this.events = {}; + /** + * The User of the Client class, set when the initial startup is complete. + * @attribute user + * @type {User} + * @readonly + */ + this.user = null; + /** + * Indicates whether the Client is ready and has cached all servers it as aware of. + * @type {Boolean} + * @attribute ready + * @readonly + */ + this.ready = false; + /** + * A List containing all the Servers the Client has access to. + * @attribute serverList + * @type {List} + * @readonly + */ + this.serverList = new List("id"); + /** + * A List containing all the PMChannels the Client has access to. + * @attribute PMList + * @type {List} + * @readonly + */ + this.PMList = new List("id"); } @@ -116,8 +116,8 @@ exports.Client = function( options ) { * @method getServers * @return {List} ServerList */ -exports.Client.prototype.getServers = function() { - return this.serverList; +exports.Client.prototype.getServers = function () { + return this.serverList; } /** @@ -125,8 +125,8 @@ exports.Client.prototype.getServers = function() { * @method getChannels * @return {List} Channelist */ -exports.Client.prototype.getChannels = function() { - return this.serverList.concatSublists( "channels", "id" ); +exports.Client.prototype.getChannels = function () { + return this.serverList.concatSublists("channels", "id"); } /** @@ -135,8 +135,8 @@ exports.Client.prototype.getChannels = function() { * @param {String/Number} id The ID of the Server * @return {Server} The Server matching the ID */ -exports.Client.prototype.getServer = function( id ) { - return this.getServers().filter( "id", id, true ); +exports.Client.prototype.getServer = function (id) { + return this.getServers().filter("id", id, true); } /** @@ -145,8 +145,8 @@ exports.Client.prototype.getServer = function( id ) { * @param {String/Number} id The ID of the Channel * @return {Server} The Channel matching the ID */ -exports.Client.prototype.getChannel = function( id ) { - return this.getChannels().filter( "id", id, true ); +exports.Client.prototype.getChannel = function (id) { + return this.getChannels().filter("id", id, true); } /** @@ -155,8 +155,8 @@ exports.Client.prototype.getChannel = function( id ) { * @param {String/Number} name The Name of the Channel * @return {Server} The Channel matching the Name */ -exports.Client.prototype.getChannelByName = function( name ) { - return this.getChannels().filter( "name", name, true ); +exports.Client.prototype.getChannelByName = function (name) { + return this.getChannels().filter("name", name, true); } /** @@ -167,18 +167,18 @@ exports.Client.prototype.getChannelByName = function( name ) { * @method triggerEvent * @private */ -exports.Client.prototype.triggerEvent = function( event, args ) { +exports.Client.prototype.triggerEvent = function (event, args) { - if ( !this.ready && event !== "raw" && event !== "disconnected" && event !== "debug" ) { //if we're not even loaded yet, don't try doing anything because it always ends badly! - return false; - } + if (!this.ready && event !== "raw" && event !== "disconnected" && event !== "debug") { //if we're not even loaded yet, don't try doing anything because it always ends badly! + return false; + } - if ( this.events[ event ] ) { - this.events[ event ].apply( this, args ); - return true; - } else { - return false; - } + if (this.events[event]) { + this.events[event].apply(this, args); + return true; + } else { + return false; + } } @@ -188,8 +188,8 @@ exports.Client.prototype.triggerEvent = function( event, args ) { * @param {Function} fn The function that should be bound to the event. * @method on */ -exports.Client.prototype.on = function( name, fn ) { - this.events[ name ] = fn; +exports.Client.prototype.on = function (name, fn) { + this.events[name] = fn; } /** @@ -197,66 +197,66 @@ exports.Client.prototype.on = function( name, fn ) { * @param {String} name The event name which should be cleared * @method off */ -exports.Client.prototype.off = function( name ) { - this.events[ name ] = function() {}; +exports.Client.prototype.off = function (name) { + this.events[name] = function () { }; } -exports.Client.prototype.cacheServer = function( id, cb, members ) { - var self = this; - var serverInput = {}; +exports.Client.prototype.cacheServer = function (id, cb, members) { + var self = this; + var serverInput = {}; - if ( typeof id === 'string' || id instanceof String ) { - //actually an ID + if (typeof id === 'string' || id instanceof String) { + //actually an ID - if ( this.serverList.filter( "id", id ).length > 0 ) { - return; - } + if (this.serverList.filter("id", id).length > 0) { + return; + } - Internal.XHR.getServer( self.token, id, function( err, data ) { - if ( !err ) { - makeServer( data ); - } - } ) + Internal.XHR.getServer(self.token, id, function (err, data) { + if (!err) { + makeServer(data); + } + }) - } else { - // got objects because SPEEEDDDD + } else { + // got objects because SPEEEDDDD - if ( this.serverList.filter( "id", id.id ).length > 0 ) { - return; - } - serverInput = id; - id = id.id; - makeServer( serverInput ); + if (this.serverList.filter("id", id.id).length > 0) { + return; + } + serverInput = id; + id = id.id; + makeServer(serverInput); - } + } - function channelsFromHTTP() { - Internal.XHR.getChannel( self.token, id, function( err ) { - if ( !err ) - cacheChannels( res.body ); - } ) - } + function channelsFromHTTP() { + Internal.XHR.getChannel(self.token, id, function (err) { + if (!err) + cacheChannels(res.body); + }) + } - var server; + var server; - function makeServer( dat ) { - server = new Server( dat.region, dat.owner_id, dat.name, id, serverInput.members || dat.members, dat.icon, dat.afk_timeout, dat.afk_channel_id ); - if ( dat.channels ) - cacheChannels( dat.channels ); - else - channelsFromHTTP(); - } + function makeServer(dat) { + server = new Server(dat.region, dat.owner_id, dat.name, id, serverInput.members || dat.members, dat.icon, dat.afk_timeout, dat.afk_channel_id); + if (dat.channels) + cacheChannels(dat.channels); + else + channelsFromHTTP(); + } - function cacheChannels( dat ) { + function cacheChannels(dat) { - var channelList = dat; - for ( channel of channelList ) { - server.channels.add( new Channel( channel, server ) ); - } - self.serverList.add( server ); + var channelList = dat; + for (var channel of channelList) { + server.channels.add(new Channel(channel, server)); + } + self.serverList.add(server); - cb( server ); - } + cb(server); + } } @@ -273,61 +273,62 @@ exports.Client.prototype.cacheServer = function( id, cb, members ) { * @param {Object} callback.error.error The raw XHR error. * @param {String} callback.token The token received when logging in */ -exports.Client.prototype.login = function( email, password, callback, noCache ) { +exports.Client.prototype.login = function (email, password, callback, noCache) { - globalLoginTime = Date.now(); + globalLoginTime = Date.now(); - this.debug( "login called at " + globalLoginTime ); + this.debug("login called at " + globalLoginTime); - var self = this; - callback = callback || function() {}; + var self = this; + callback = callback || function () { }; - if ( noCache == undefined || noCache == null ) { - noCache = false; - } + if (noCache == undefined || noCache == null) { + noCache = false; + } - self.connectWebsocket(); + self.connectWebsocket(); - if ( this.tokenManager.exists( email ) && !noCache ) { + if (this.tokenManager) { + if (this.tokenManager.exists(email) && !noCache) { - var token = this.tokenManager.getToken( email, password ); - if ( !token.match( /[^\w.-]+/g ) ) { - done( this.tokenManager.getToken( email, password ) ); - self.debug( "loaded token from caches in " + tp( globalLoginTime ) ); - return; - } else { - self.debug( "error getting token from caches, using default auth" ); - } - } + var token = this.tokenManager.getToken(email, password); + if (!token.match(/[^\w.-]+/g)) { + done(this.tokenManager.getToken(email, password)); + self.debug("loaded token from caches in " + tp(globalLoginTime)); + return; + } else { + self.debug("error getting token from caches, using default auth"); + } + } + } + var time = Date.now(); + Internal.XHR.login(email, password, function (err, token) { + if (err) { + self.triggerEvent("disconnected", [{ + reason: "failed to log in", + error: err + }]); + self.websocket.close(); + self.debug("failed to login in " + tp(globalLoginTime)); + } else { + if (!noCache) { + self.tokenManager.addToken(email, token, password); + } + self.debug("loaded token from auth servers in " + tp(globalLoginTime)); + done(token); + } - var time = Date.now(); - Internal.XHR.login( email, password, function( err, token ) { - if ( err ) { - self.triggerEvent( "disconnected", [ { - reason: "failed to log in", - error: err - } ] ); - self.websocket.close(); - self.debug( "failed to login in " + tp( globalLoginTime ) ); - } else { - if ( !noCache ) { - self.tokenManager.addToken( email, token, password ); - } - self.debug( "loaded token from auth servers in " + tp( globalLoginTime ) ); - done( token ); - } + }); - } ); - - function done( token ) { - self.email = email; - self.password = password; - self.debug( "using token " + token ); - self.token = token; - self.websocket.sendData(); - self.loggedIn = true; - callback( null, token ); - } + function done(token) { + self.email = email; + self.password = password; + self.debug("using token " + token); + self.token = token; + self.websocket.sendData(); + self.loggedIn = true; + callback(null, token); + } } /** @@ -341,278 +342,278 @@ exports.Client.prototype.login = function( email, password, callback, noCache ) * @param {Object} options see sendMessage(options) * @method reply */ -exports.Client.prototype.reply = function( destination, toSend, callback, options ) { +exports.Client.prototype.reply = function (destination, toSend, callback, options) { - if ( toSend instanceof Array ) { - toSend = toSend.join( "\n" ); - } + if (toSend instanceof Array) { + toSend = toSend.join("\n"); + } - toSend = destination.author.mention() + ", " + toSend; + toSend = destination.author.mention() + ", " + toSend; - this.sendMessage( destination, toSend, callback, options ); + this.sendMessage(destination, toSend, callback, options); } -exports.Client.prototype.connectWebsocket = function( cb ) { +exports.Client.prototype.connectWebsocket = function (cb) { - var self = this; + var self = this; - var sentInitData = false; + var sentInitData = false; - this.websocket = new WebSocket( Endpoints.WEBSOCKET_HUB ); - this.websocket.onclose = function( e ) { - self.triggerEvent( "disconnected", [ { - reason: "websocket disconnected", - error: e - } ] ); - }; - this.websocket.onmessage = function( e ) { + this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + this.websocket.onclose = function (e) { + self.triggerEvent("disconnected", [{ + reason: "websocket disconnected", + error: e + }]); + }; + this.websocket.onmessage = function (e) { - self.triggerEvent( "raw", [ e ] ); + self.triggerEvent("raw", [e]); - var dat = JSON.parse( e.data ); - var webself = this; + var dat = JSON.parse(e.data); + var webself = this; - switch ( dat.op ) { + switch (dat.op) { - case 0: - if ( dat.t === "READY" ) { + case 0: + if (dat.t === "READY") { - self.debug( "got ready packet" ); + self.debug("got ready packet"); - var data = dat.d; + var data = dat.d; - self.user = new User( data.user ); + self.user = new User(data.user); - var _servers = data.guilds, - servers = []; + var _servers = data.guilds, + servers = []; - var cached = 0, - toCache = _servers.length; + var cached = 0, + toCache = _servers.length; - for ( x in data.private_channels ) { - self.PMList.add( new PMChannel( data.private_channels[ x ].recipient, data.private_channels[ x ].id ) ); - } + for (x in data.private_channels) { + self.PMList.add(new PMChannel(data.private_channels[x].recipient, data.private_channels[x].id)); + } - for ( x in _servers ) { - _server = _servers[ x ]; + for (x in _servers) { + _server = _servers[x]; - self.cacheServer( _server, function( server ) { - cached++; - if ( cached === toCache ) { - self.ready = true; - self.triggerEvent( "ready" ); - self.debug( "ready triggered" ); - } - } ); - } + self.cacheServer(_server, function (server) { + cached++; + if (cached === toCache) { + self.ready = true; + self.triggerEvent("ready"); + self.debug("ready triggered"); + } + }); + } - setInterval( function() { - webself.keepAlive.apply( webself ); - }, data.heartbeat_interval ); + setInterval(function () { + webself.keepAlive.apply(webself); + }, data.heartbeat_interval); - } else if ( dat.t === "MESSAGE_CREATE" ) { - var data = dat.d; + } else if (dat.t === "MESSAGE_CREATE") { + var data = dat.d; - var channel = self.getChannel( data.channel_id ); - var message = new Message( data, channel ); - self.triggerEvent( "message", [ message ] ); - if ( channel.messages ) - channel.messages.add( message ); + var channel = self.getChannel(data.channel_id); + var message = new Message(data, channel); + self.triggerEvent("message", [message]); + if (channel.messages) + channel.messages.add(message); - } else if ( dat.t === "MESSAGE_DELETE" ) { - var data = dat.d; + } else if (dat.t === "MESSAGE_DELETE") { + var data = dat.d; - var channel = self.getChannel( data.channel_id ); + var channel = self.getChannel(data.channel_id); - if ( !channel.messages ) - return; + if (!channel.messages) + return; - var _msg = channel.messages.filter( "id", data.id, true ); + var _msg = channel.messages.filter("id", data.id, true); - if ( _msg ) { - self.triggerEvent( "messageDelete", [ _msg ] ); - channel.messages.removeElement( _msg ); - } + if (_msg) { + self.triggerEvent("messageDelete", [_msg]); + channel.messages.removeElement(_msg); + } - } else if ( dat.t === "MESSAGE_UPDATE" ) { + } else if (dat.t === "MESSAGE_UPDATE") { - var data = dat.d; - if ( !self.ready ) - return; + var data = dat.d; + if (!self.ready) + return; - var formerMessage = false; + var formerMessage = false; - var channel = self.getChannel( data.channel_id ); + var channel = self.getChannel(data.channel_id); - if ( channel ) { + if (channel) { - formerMessage = channel.messages.filter( "id", data.id, true ); - var newMessage; + formerMessage = channel.messages.filter("id", data.id, true); + var newMessage; - data.author = data.author || formerMessage.author; - data.timestamp = data.time || formerMessage.time; - data.content = data.content || formerMessage.content; - data.channel = data.channel || formerMessage.channel; - data.id = data.id || formerMessage.id; - data.mentions = data.mentions || formerMessage.mentions; - data.mention_everyone = data.mention_everyone || formerMessage.everyoneMentioned; - data.embeds = data.embeds || formerMessage.embeds; + data.author = data.author || formerMessage.author; + data.timestamp = data.time || formerMessage.time; + data.content = data.content || formerMessage.content; + data.channel = data.channel || formerMessage.channel; + data.id = data.id || formerMessage.id; + data.mentions = data.mentions || formerMessage.mentions; + data.mention_everyone = data.mention_everyone || formerMessage.everyoneMentioned; + data.embeds = data.embeds || formerMessage.embeds; - try { - newMessage = new Message( data, channel ); - } catch ( e ) { - self.debug( "dropped a message update packet" ); - return; - } + try { + newMessage = new Message(data, channel); + } catch (e) { + self.debug("dropped a message update packet"); + return; + } - self.triggerEvent( "messageUpdate", [ formerMessage, newMessage ] ); + self.triggerEvent("messageUpdate", [formerMessage, newMessage]); - if ( formerMessage ) - channel.messages.updateElement( formerMessage, newMessage ); - else - channel.messages.add( newMessage ); + if (formerMessage) + channel.messages.updateElement(formerMessage, newMessage); + else + channel.messages.add(newMessage); - } + } - } else if ( dat.t === "PRESENCE_UPDATE" ) { + } else if (dat.t === "PRESENCE_UPDATE") { - var data = dat.d; - var getUser = self.getUser( data.user.id ); - if ( getUser ) { - //user already exists - var usr = new User( data.user ); - if ( usr.equalsStrict( getUser ) ) { - //no changes, actually a presence. - } else { - if ( self.updateUserReferences( data.user.id, getUser, new User( data.user ) ) ) { - self.triggerEvent( "userupdate", [ getUser, usr ] ); - } - } - } - self.triggerEvent( "presence", [ new User( data.user ), data.status, self.serverList.filter( "id", data.guild_id, true ) ] ); + var data = dat.d; + var getUser = self.getUser(data.user.id); + if (getUser) { + //user already exists + var usr = new User(data.user); + if (usr.equalsStrict(getUser)) { + //no changes, actually a presence. + } else { + if (self.updateUserReferences(data.user.id, getUser, new User(data.user))) { + self.triggerEvent("userupdate", [getUser, usr]); + } + } + } + self.triggerEvent("presence", [new User(data.user), data.status, self.serverList.filter("id", data.guild_id, true)]); - } else if ( dat.t === "GUILD_DELETE" ) { + } else if (dat.t === "GUILD_DELETE") { - var deletedServer = self.serverList.filter( "id", dat.d.id, true ); + var deletedServer = self.serverList.filter("id", dat.d.id, true); - if ( deletedServer ) { - self.triggerEvent( "serverDelete", [ deletedServer ] ); - } + if (deletedServer) { + self.triggerEvent("serverDelete", [deletedServer]); + } - } else if ( dat.t === "CHANNEL_DELETE" ) { + } else if (dat.t === "CHANNEL_DELETE") { - var delServer = self.serverList.filter( "id", dat.d.guild_id, true ); + var delServer = self.serverList.filter("id", dat.d.guild_id, true); - if ( delServer ) { - var channel = delServer.channels.filter( "id", dat.d.id, true ); + if (delServer) { + var channel = delServer.channels.filter("id", dat.d.id, true); - if ( channel ) { - self.triggerEvent( "channelDelete", [ channel ] ); - } - } + if (channel) { + self.triggerEvent("channelDelete", [channel]); + } + } - } else if ( dat.t === "GUILD_CREATE" ) { + } else if (dat.t === "GUILD_CREATE") { - if ( !self.serverList.filter( "id", dat.d.id, true ) ) { - self.cacheServer( dat.d, function( server ) { - if ( serverCreateRequests[ server.id ] ) { - serverCreateRequests[ server.id ]( null, server ); - serverCreateRequests[ server.id ] = null; - } else { - self.triggerEvent( "serverJoin", [ server ] ); - } - } ); - } + if (!self.serverList.filter("id", dat.d.id, true)) { + self.cacheServer(dat.d, function (server) { + if (serverCreateRequests[server.id]) { + serverCreateRequests[server.id](null, server); + serverCreateRequests[server.id] = null; + } else { + self.triggerEvent("serverJoin", [server]); + } + }); + } - } else if ( dat.t === "CHANNEL_CREATE" ) { + } else if (dat.t === "CHANNEL_CREATE") { - var srv = self.serverList.filter( "id", dat.d.guild_id, true ); + var srv = self.serverList.filter("id", dat.d.guild_id, true); - if ( srv ) { + if (srv) { - if ( !srv.channels.filter( "id", dat.d.d, true ) ) { + if (!srv.channels.filter("id", dat.d.d, true)) { - var chann = new Channel( dat.d, srv ); + var chann = new Channel(dat.d, srv); - srv.channels.add( new Channel( dat.d, srv ) ); - self.triggerEvent( "channelCreate", [ chann ] ); + srv.channels.add(new Channel(dat.d, srv)); + self.triggerEvent("channelCreate", [chann]); - } + } - } + } - } else if ( dat.t === "USER_UPDATE" ) { + } else if (dat.t === "USER_UPDATE") { - if ( dat.d.id === self.user.id ) { - var newUsr = new User( dat.d ); - self.triggerEvent( "userupdate", [ self.user, newUsr ] ); - self.user = newUsr; - } - - } else if (dat.t === "GUILD_MEMBER_ADD"){ - - var srv = self.getServer( dat.d.guild_id ); - if(srv){ - var usr = new User(dat.d.user); - srv.members.add( usr ); - self.triggerEvent("serverMemberAdd", [usr]); - } + if (dat.d.id === self.user.id) { + var newUsr = new User(dat.d); + self.triggerEvent("userupdate", [self.user, newUsr]); + self.user = newUsr; + } + + } else if (dat.t === "GUILD_MEMBER_ADD") { + + var srv = self.getServer(dat.d.guild_id); + if (srv) { + var usr = new User(dat.d.user); + srv.members.add(usr); + self.triggerEvent("serverMemberAdd", [usr]); + } - } else if (dat.t === "GUILD_MEMBER_REMOVE"){ + } else if (dat.t === "GUILD_MEMBER_REMOVE") { - var srv = self.getServer( dat.d.guild_id ); - if(srv){ - var usr = new User(dat.d.user); - srv.members.removeElement( usr ); - self.triggerEvent("serverMemberRemove", [usr]); - } + var srv = self.getServer(dat.d.guild_id); + if (srv) { + var usr = new User(dat.d.user); + srv.members.removeElement(usr); + self.triggerEvent("serverMemberRemove", [usr]); + } - } - break; + } + break; - } + } - }; - this.websocket.sendPacket = function( p ) { - this.send( JSON.stringify( p ) ); - } - this.websocket.keepAlive = function() { + }; + this.websocket.sendPacket = function (p) { + this.send(JSON.stringify(p)); + } + this.websocket.keepAlive = function () { - if ( this.readyState !== 1 ) - return false; + if (this.readyState !== 1) + return false; - this.sendPacket( { - op: 1, - d: Date.now() - } ); + this.sendPacket({ + op: 1, + d: Date.now() + }); - } - this.websocket.onopen = function() { + } + this.websocket.onopen = function () { - self.debug( "websocket conn open" ); - this.sendData( "onopen" ); + self.debug("websocket conn open"); + this.sendData("onopen"); - } - this.websocket.sendData = function( why ) { - if ( this.readyState == 1 && !sentInitData && self.token ) { - sentInitData = true; - var connDat = { - op: 2, - d: { - token: self.token, - v: 2 - } - }; + } + this.websocket.sendData = function (why) { + if (this.readyState == 1 && !sentInitData && self.token) { + sentInitData = true; + var connDat = { + op: 2, + d: { + token: self.token, + v: 2 + } + }; - connDat.d.properties = Internal.WebSocket.properties; - this.sendPacket( connDat ); - } - } + connDat.d.properties = Internal.WebSocket.properties; + this.sendPacket(connDat); + } + } } -exports.Client.prototype.debug = function( msg ) { - this.triggerEvent( "debug", [ "[SL " + tp( globalLoginTime ) + "] " + msg ] ); +exports.Client.prototype.debug = function (msg) { + this.triggerEvent("debug", ["[SL " + tp(globalLoginTime) + "] " + msg]); } /** @@ -621,19 +622,19 @@ exports.Client.prototype.debug = function( msg ) { * @param {Object} callback.error Null unless there was an error, in which case is an XHR error. * @method logout */ -exports.Client.prototype.logout = function( callback ) { +exports.Client.prototype.logout = function (callback) { - callback = callback || function() {}; + callback = callback || function () { }; - var self = this; + var self = this; - Internal.XHR.logout( self.token, function( err ) { - if ( err ) { - callback( err ); - } - self.loggedIn = false; - self.websocket.close(); - } ); + Internal.XHR.logout(self.token, function (err) { + if (err) { + callback(err); + } + self.loggedIn = false; + self.websocket.close(); + }); } @@ -647,23 +648,23 @@ exports.Client.prototype.logout = function( callback ) { * @method createServer * @async */ -exports.Client.prototype.createServer = function( name, region, cb ) { +exports.Client.prototype.createServer = function (name, region, cb) { - var self = this; + var self = this; - Internal.XHR.createServer( self.token, name, region, function( err, data ) { + Internal.XHR.createServer(self.token, name, region, function (err, data) { - if ( err ) { - cb( err ); - } else { + if (err) { + cb(err); + } else { - self.cacheServer( data, function( server ) { - cb( null, server ); - } ); + self.cacheServer(data, function (server) { + cb(null, server); + }); - } + } - } ); + }); } @@ -676,23 +677,23 @@ exports.Client.prototype.createServer = function( name, region, cb ) { * @method leaveServer * @async */ -exports.Client.prototype.leaveServer = function( server, callback ) { +exports.Client.prototype.leaveServer = function (server, callback) { - var self = this; + var self = this; - // callback is not necessary for this function - callback = callback || function() {}; + // callback is not necessary for this function + callback = callback || function () { }; - Internal.XHR.leaveServer( self.token, server.id, function( err ) { + Internal.XHR.leaveServer(self.token, server.id, function (err) { - if ( err ) { - callback( err ); - } else { - self.serverList.removeElement( server ); - callback( null, server ); - } + if (err) { + callback(err); + } else { + self.serverList.removeElement(server); + callback(null, server); + } - } ); + }); } @@ -709,52 +710,52 @@ exports.Client.prototype.leaveServer = function( server, callback ) { * @param {Invite} callback.invite An invite object representing the created invite. * @method createInvite */ -exports.Client.prototype.createInvite = function( channel, options, callback ) { +exports.Client.prototype.createInvite = function (channel, options, callback) { - var self = this; - var options = options || {}; + var self = this; + var options = options || {}; - // callback is not necessary for this function - callback = callback || function() {}; + // callback is not necessary for this function + callback = callback || function () { }; - if ( channel instanceof Server ) { - channel = channel.getDefaultChannel(); - } + if (channel instanceof Server) { + channel = channel.getDefaultChannel(); + } - options.max_age = options.max_age || 0; - options.max_uses = options.max_uses || 0; - options.temporary = options.temporary || false; - options.xkcdpass = options.xkcd || false; + options.max_age = options.max_age || 0; + options.max_uses = options.max_uses || 0; + options.temporary = options.temporary || false; + options.xkcdpass = options.xkcd || false; - Internal.XHR.createInvite( self.token, channel.id, options, function( err, data ) { + Internal.XHR.createInvite(self.token, channel.id, options, function (err, data) { - if ( err ) { - callback( err ); - } else { - callback( null, new Invite( data ) ); - } + if (err) { + callback(err); + } else { + callback(null, new Invite(data)); + } - } ); + }); } -exports.Client.prototype.startPM = function( user, callback ) { +exports.Client.prototype.startPM = function (user, callback) { - var self = this; + var self = this; - callback = callback || function() {}; + callback = callback || function () { }; - Internal.XHR.startPM( self.token, self.user.id, user.id, function( err, data ) { + Internal.XHR.startPM(self.token, self.user.id, user.id, function (err, data) { - if ( err ) { - callback( err ); - } else { - var channel = new PMChannel( data.recipient, data.id ); - self.PMList.add( channel ); - callback( null, channel ); - } + if (err) { + callback(err); + } else { + var channel = new PMChannel(data.recipient, data.id); + self.PMList.add(channel); + callback(null, channel); + } - } ); + }); } @@ -774,128 +775,128 @@ exports.Client.prototype.startPM = function( user, callback ) { * @method sendMessage */ -exports.Client.prototype.sendFile = function( destination, toSend, fileName, callback, options ) { +exports.Client.prototype.sendFile = function (destination, toSend, fileName, callback, options) { - this.sendMessage( destination, toSend, callback, options, fileName ); + this.sendMessage(destination, toSend, callback, options, fileName); } -exports.Client.prototype.sendMessage = function( destination, toSend, callback, options, fileName ) { +exports.Client.prototype.sendMessage = function (destination, toSend, callback, options, fileName) { - options = options || {}; - callback = callback || function() {}; + options = options || {}; + callback = callback || function () { }; - var channel_id, message, mentions, self = this; + var channel_id, message, mentions, self = this; - channel_id = resolveChannel( destination, self ); - if ( !fileName ) { - message = resolveMessage( toSend ); - mentions = resolveMentions( message, options.mention ); - } + channel_id = resolveChannel(destination, self); + if (!fileName) { + message = resolveMessage(toSend); + mentions = resolveMentions(message, options.mention); + } - if ( channel_id ) { - send(); - } else { - //a channel is being sorted - } + if (channel_id) { + send(); + } else { + //a channel is being sorted + } - function send() { + function send() { - if(fileName){ - Internal.XHR.sendFile( self.token, channel_id, toSend, fileName, function(err){ + if (fileName) { + Internal.XHR.sendFile(self.token, channel_id, toSend, fileName, function (err) { - callback(err); + callback(err); - } ); - return; - } + }); + return; + } - Internal.XHR.sendMessage( self.token, channel_id, { - content: message, - mentions: mentions - }, function( err, data ) { - if ( err ) { - callback( err ); - } else { - var msg = new Message( data, self.getChannel( data.channel_id ) ); - if ( options.selfDestruct ) { - setTimeout( function() { - self.deleteMessage( msg ); - }, options.selfDestruct ); - } - callback( null, msg ); - } - } ); - } + Internal.XHR.sendMessage(self.token, channel_id, { + content: message, + mentions: mentions + }, function (err, data) { + if (err) { + callback(err); + } else { + var msg = new Message(data, self.getChannel(data.channel_id)); + if (options.selfDestruct) { + setTimeout(function () { + self.deleteMessage(msg); + }, options.selfDestruct); + } + callback(null, msg); + } + }); + } - function setChannId( id ) { - channel_id = id; - } + function setChannId(id) { + channel_id = id; + } - function resolveChannel( destination, self ) { - var channel_id = false; - if ( destination instanceof Server ) { - channel_id = destination.getDefaultChannel().id; - } else if ( destination instanceof Channel ) { - channel_id = destination.id; - } else if ( destination instanceof PMChannel ) { - channel_id = destination.id; - } else if ( destination instanceof Message ) { - channel_id = destination.channel.id; - } else if ( destination instanceof User ) { - var destId = self.PMList.deepFilter( [ "user", "id" ], destination.id, true ); + function resolveChannel(destination, self) { + var channel_id = false; + if (destination instanceof Server) { + channel_id = destination.getDefaultChannel().id; + } else if (destination instanceof Channel) { + channel_id = destination.id; + } else if (destination instanceof PMChannel) { + channel_id = destination.id; + } else if (destination instanceof Message) { + channel_id = destination.channel.id; + } else if (destination instanceof User) { + var destId = self.PMList.deepFilter(["user", "id"], destination.id, true); - if ( destId ) { - channel_id = destId.id; - } else { - //start a PM and then get that use that - self.startPM( destination, function( err, channel ) { - if ( err ) { - callback( err ); - } else { - self.PMList.add( new PMChannel( channel.user, channel.id ) ); - setChannId( channel.id ); - send(); - } - } ); - return false; - } - } else { - channel_id = destination; - } - return channel_id; - } + if (destId) { + channel_id = destId.id; + } else { + //start a PM and then get that use that + self.startPM(destination, function (err, channel) { + if (err) { + callback(err); + } else { + self.PMList.add(new PMChannel(channel.user, channel.id)); + setChannId(channel.id); + send(); + } + }); + return false; + } + } else { + channel_id = destination; + } + return channel_id; + } - function resolveMessage( toSend ) { - var message; - if ( typeof toSend === "string" || toSend instanceof String ) - message = toSend; - else if ( toSend instanceof Array ) - message = toSend.join( "\n" ); - else if ( toSend instanceof Message ) - message = toSend.content; - else - message = toSend; - return message.substring( 0, 2000 ); - } + function resolveMessage(toSend) { + var message; + if (typeof toSend === "string" || toSend instanceof String) + message = toSend; + else if (toSend instanceof Array) + message = toSend.join("\n"); + else if (toSend instanceof Message) + message = toSend.content; + else + message = toSend; + return message.substring(0, 2000); + } - function resolveMentions( message, mentionsOpt ) { - var mentions = []; - if ( mentionsOpt === false ) {} else if ( mentionsOpt || mentionsOpt === "auto" || mentionsOpt == null || mentionsOpt == undefined ) { - for ( mention of( message.match( /<@[^>]*>/g ) || [] ) ) { - mentions.push( mention.substring( 2, mention.length - 1 ) ); - } - } else if ( mentionsOpt instanceof Array ) { - for ( mention of mentionsOpt ) { - if ( mention instanceof User ) { - mentions.push( mention.id ); - } else { - mentions.push( mention ); - } - } - } - return mentions; - } + function resolveMentions(message, mentionsOpt) { + var mentions = []; + if (mentionsOpt === false) { } else if (mentionsOpt || mentionsOpt === "auto" || mentionsOpt == null || mentionsOpt == undefined) { + for (mention of (message.match(/<@[^>]*>/g) || [])) { + mentions.push(mention.substring(2, mention.length - 1)); + } + } else if (mentionsOpt instanceof Array) { + for (mention of mentionsOpt) { + if (mention instanceof User) { + mentions.push(mention.id); + } else { + mentions.push(mention); + } + } + } + return mentions; + } } /** @@ -906,181 +907,181 @@ exports.Client.prototype.sendMessage = function( destination, toSend, callback, * @param {Message} callback.message A message object representing the deleted object. * @method deleteMessage */ -exports.Client.prototype.deleteMessage = function( message, callback ) { - callback = callback || function() {}; +exports.Client.prototype.deleteMessage = function (message, callback) { + callback = callback || function () { }; - var self = this; + var self = this; - Internal.XHR.deleteMessage( self.token, message.channel.id, message.id, callback ); + Internal.XHR.deleteMessage(self.token, message.channel.id, message.id, callback); } -exports.Client.prototype.updateMessage = function( oldMessage, newContent, callback, options ) { +exports.Client.prototype.updateMessage = function (oldMessage, newContent, callback, options) { - var self = this; - var channel = oldMessage.channel; - options = options || {}; + var self = this; + var channel = oldMessage.channel; + options = options || {}; - Internal.XHR.updateMessage( self.token, channel.id, oldMessage.id, { - content: newContent, - mentions: [] - }, function( err, data ) { - if ( err ) { - callback( err ); - return; - } - var msg = new Message( data, self.getChannel( data.channel_id ) ); - if ( options.selfDestruct ) { - setTimeout( function() { - self.deleteMessage( msg ); - }, options.selfDestruct ); - } - callback( null, msg ); - } ); + Internal.XHR.updateMessage(self.token, channel.id, oldMessage.id, { + content: newContent, + mentions: [] + }, function (err, data) { + if (err) { + callback(err); + return; + } + var msg = new Message(data, self.getChannel(data.channel_id)); + if (options.selfDestruct) { + setTimeout(function () { + self.deleteMessage(msg); + }, options.selfDestruct); + } + callback(null, msg); + }); } -exports.Client.prototype.setUsername = function( username, callback ) { +exports.Client.prototype.setUsername = function (username, callback) { - var self = this; + var self = this; - Internal.XHR.setUsername( self.token, self.user.avatar, self.email, null, self.password, username, function( err ) { + Internal.XHR.setUsername(self.token, self.user.avatar, self.email, null, self.password, username, function (err) { - callback( err ); + callback(err); - } ); + }); } -exports.Client.prototype.getChannelLogs = function( channel, amount, callback ) { - var self = this; +exports.Client.prototype.getChannelLogs = function (channel, amount, callback) { + var self = this; - Internal.XHR.getChannelLogs( self.token, channel.id, ( amount || 50 ), function( err, data ) { + Internal.XHR.getChannelLogs(self.token, channel.id, (amount || 50), function (err, data) { - if ( err ) { - callback( err ); - return; - } + if (err) { + callback(err); + return; + } - var logs = new List( "id" ); - for ( message of data ) { - logs.add( new Message( message, channel ) ); - } - callback( null, logs ); + var logs = new List("id"); + for (message of data) { + logs.add(new Message(message, channel)); + } + callback(null, logs); - } ); + }); } -exports.Client.prototype.createChannel = function( server, name, type, callback ) { +exports.Client.prototype.createChannel = function (server, name, type, callback) { - var self = this; + var self = this; - Internal.XHR.createChannel( self.token, server.id, name, type, function( err, data ) { + Internal.XHR.createChannel(self.token, server.id, name, type, function (err, data) { - if ( err ) { - callback( err ); - } else { - var chann = new Channel( data, server ); - server.channels.add( chann ); - callback( null, chann ); - } + if (err) { + callback(err); + } else { + var chann = new Channel(data, server); + server.channels.add(chann); + callback(null, chann); + } - } ); + }); } -exports.Client.prototype.deleteChannel = function( channel, callback ) { - var self = this; +exports.Client.prototype.deleteChannel = function (channel, callback) { + var self = this; - Internal.XHR.deleteChannel( self.token, channel.id, function( err ) { + Internal.XHR.deleteChannel(self.token, channel.id, function (err) { - channel.server.channels.removeElement( channel ); - self.triggerEvent( "channelDelete", [ channel ] ); - callback( null ); + channel.server.channels.removeElement(channel); + self.triggerEvent("channelDelete", [channel]); + callback(null); - } ); + }); } -exports.Client.prototype.deleteServer = function( server, callback ) { +exports.Client.prototype.deleteServer = function (server, callback) { - var self = this; + var self = this; - Internal.XHR.deleteServer( self.token, server.id, function( err ) { + Internal.XHR.deleteServer(self.token, server.id, function (err) { - self.serverList.removeElement( server ); - self.triggerEvent( "serverDelete", [ server ] ); - callback( null ); + self.serverList.removeElement(server); + self.triggerEvent("serverDelete", [server]); + callback(null); - } ); + }); } -exports.Client.prototype.joinServer = function( invite, callback ) { +exports.Client.prototype.joinServer = function (invite, callback) { - var self = this; + var self = this; - var code = ( invite instanceof Invite ? invite.code : invite ); + var code = (invite instanceof Invite ? invite.code : invite); - Internal.XHR.acceptInvite( self.token, code, function( err, inviteData ) { + Internal.XHR.acceptInvite(self.token, code, function (err, inviteData) { - if ( err ) { - callback( err ); - } else { - serverCreateRequests[ inviteData.guild.id ] = callback; - } + if (err) { + callback(err); + } else { + serverCreateRequests[inviteData.guild.id] = callback; + } - } ); + }); } -exports.Client.prototype.getServers = function() { - return this.serverList; +exports.Client.prototype.getServers = function () { + return this.serverList; } -exports.Client.prototype.getChannels = function() { - return this.serverList.concatSublists( "channels", "id" ); +exports.Client.prototype.getChannels = function () { + return this.serverList.concatSublists("channels", "id"); } -exports.Client.prototype.getUsers = function() { - return this.getServers().concatSublists( "members", "id" ); +exports.Client.prototype.getUsers = function () { + return this.getServers().concatSublists("members", "id"); } -exports.Client.prototype.getServer = function( id ) { - return this.getServers().filter( "id", id, true ); +exports.Client.prototype.getServer = function (id) { + return this.getServers().filter("id", id, true); } -exports.Client.prototype.getChannel = function( id ) { - var normalChan = this.getChannels().filter( "id", id, true ); - return normalChan || this.PMList.filter( "id", id, true ); +exports.Client.prototype.getChannel = function (id) { + var normalChan = this.getChannels().filter("id", id, true); + return normalChan || this.PMList.filter("id", id, true); } -exports.Client.prototype.getChannelByName = function( name ) { - return this.getChannels().filter( "name", name, true ); +exports.Client.prototype.getChannelByName = function (name) { + return this.getChannels().filter("name", name, true); } -exports.Client.prototype.getUser = function( id ) { - return this.getUsers().filter( "id", id, true ); +exports.Client.prototype.getUser = function (id) { + return this.getUsers().filter("id", id, true); } -exports.isUserID = function( id ) { - return ( ( id + "" ).length === 17 && !isNaN( id ) ); +exports.isUserID = function (id) { + return ((id + "").length === 17 && !isNaN(id)); } -exports.Client.prototype.updateUserReferences = function( id, oldUser, user ) { +exports.Client.prototype.updateUserReferences = function (id, oldUser, user) { - if ( oldUser.equalsStrict( user ) ) { - return false; - } + if (oldUser.equalsStrict(user)) { + return false; + } - for ( server of this.serverList.contents ) { + for (server of this.serverList.contents) { - server.members.updateElement( oldUser, user ); + server.members.updateElement(oldUser, user); - } + } - this.debug( "Updated references to " + oldUser.username + " to " + this.getUser( id ).username ); - return true; + this.debug("Updated references to " + oldUser.username + " to " + this.getUser(id).username); + return true; } -exports.Client.prototype.addPM = function( pm ) { - this.PMList.add( pm ); +exports.Client.prototype.addPM = function (pm) { + this.PMList.add(pm); } From 35b61312b9b173b98da29b66becb0fd0f5dca8fd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 16:55:23 +0100 Subject: [PATCH 005/191] Deleted examples, beginning to write in EC6. Examples and Hydrabot will soon live in a separate repo which is better suited to learning - this is so the main package isn't bloated. --- .settings/settings.json | 3 + .settings/tasks.json | 220 ++++++++ examples/avatar.js | 37 -- examples/formatting.js | 24 - examples/pingpong.js | 32 -- examples/presence.js | 26 - examples/query.js | 61 --- examples/status.js | 24 - hydrabot/.gitignore | 2 - hydrabot/README.md | 19 - hydrabot/authority.js | 37 -- hydrabot/commands.js | 516 ------------------- hydrabot/hydrabot.js | 132 ----- index.js | 1087 --------------------------------------- jsconfig.json | 6 + lib/Client.js | 63 +++ lib/PMChannel.js | 6 +- lib/TokenManager.js | 83 ++- lib/asd.js | 63 +++ lib/channel.js | 15 +- lib/endpoints.js | 24 +- lib/index.js | 23 + lib/internal.js | 386 ++++++-------- lib/invite.js | 14 +- lib/list.js | 294 +++++++---- lib/message.js | 40 +- lib/server.js | 116 ++--- lib/user.js | 32 +- src/Client.js | 69 +++ src/Endpoints.js | 11 + src/PMChannel.js | 6 + src/TokenManager.js | 68 +++ src/channel.js | 28 + src/index.js | 21 + src/internal.js | 277 ++++++++++ src/invite.js | 21 + src/list.js | 248 +++++++++ src/message.js | 39 ++ src/server.js | 106 ++++ src/user.js | 37 ++ 40 files changed, 1830 insertions(+), 2486 deletions(-) create mode 100644 .settings/settings.json create mode 100644 .settings/tasks.json delete mode 100644 examples/avatar.js delete mode 100644 examples/formatting.js delete mode 100644 examples/pingpong.js delete mode 100644 examples/presence.js delete mode 100644 examples/query.js delete mode 100644 examples/status.js delete mode 100644 hydrabot/.gitignore delete mode 100644 hydrabot/README.md delete mode 100644 hydrabot/authority.js delete mode 100644 hydrabot/commands.js delete mode 100644 hydrabot/hydrabot.js delete mode 100644 index.js create mode 100644 jsconfig.json create mode 100644 lib/Client.js create mode 100644 lib/asd.js create mode 100644 lib/index.js create mode 100644 src/Client.js create mode 100644 src/Endpoints.js create mode 100644 src/PMChannel.js create mode 100644 src/TokenManager.js create mode 100644 src/channel.js create mode 100644 src/index.js create mode 100644 src/internal.js create mode 100644 src/invite.js create mode 100644 src/list.js create mode 100644 src/message.js create mode 100644 src/server.js create mode 100644 src/user.js diff --git a/.settings/settings.json b/.settings/settings.json new file mode 100644 index 000000000..20af2f68a --- /dev/null +++ b/.settings/settings.json @@ -0,0 +1,3 @@ +// Place your settings in this file to overwrite default and user settings. +{ +} \ No newline at end of file diff --git a/.settings/tasks.json b/.settings/tasks.json new file mode 100644 index 000000000..95c321163 --- /dev/null +++ b/.settings/tasks.json @@ -0,0 +1,220 @@ +// Available variables which can be used inside of strings. +// ${workspaceRoot}: the root folder of the team +// ${file}: the current opened file +// ${fileBasename}: the current opened file's basename +// ${fileDirname}: the current opened file's dirname +// ${fileExtname}: the current opened file's extension +// ${cwd}: the current working directory of the spawned process + +// A task runner that calls the Typescript compiler (tsc) and +// Compiles a HelloWorld.ts program +{ + "version": "0.1.0", + "command" : "babel", + "isShellCommand": true, + "tasks": [ + { + "taskName": "watch", + "suppressTaskName": true, + "isBuildCommand": true, + "isWatching": true, + "args": [ + "src", "--out-dir", "lib", "-w" + ] + } + ] +} + +// A task runner that calls the Typescript compiler (tsc) and +// compiles based on a tsconfig.json file that is present in +// the root of the folder open in VSCode +/* +{ + "version": "0.1.0", + + // The command is tsc. Assumes that tsc has been installed using npm install -g typescript + "command": "tsc", + + // The command is a shell script + "isShellCommand": true, + + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + + // Tell the tsc compiler to use the tsconfig.json from the open folder. + "args": ["-p", "."], + + // use the standard tsc problem matcher to find compile problems + // in the output. + "problemMatcher": "$tsc" +} +*/ + +// A task runner configuration for gulp. Gulp provides a less task +// which compiles less to css. +/* +{ + "version": "0.1.0", + "command": "gulp", + "isShellCommand": true, + "tasks": [ + { + "taskName": "less", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard less compilation problem matcher. + "problemMatcher": "$lessCompile" + } + ] +} +*/ + +// Uncomment the following section to use gulp in a watching mode that compiles a +// less file. The gulp task prints "[hh:mm:ss] Starting 'clean-styles'" to the console +// when existing css files get deleted and "[hh:mm:ss] Finished 'styles'" when the +// overall less compilation has finished. When the clean pattern is detect internal less +// problems are cleaned. When the finshed pattern is detected in the output less +// problems are published. +/* +{ + "version": "0.1.0", + "command": "gulp", + "isShellCommand": true, + "tasks": [ + { + "taskName": "watch-less", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Task is running in watching mode. + "isWatching": true, + "problemMatcher": { + // Use the standard less compilation problem matcher as the base. + "base": "$lessCompile", + // A regular expression signalling that a watched task begins executing (usually triggered through file watching). + "watchedTaskBeginsRegExp": "^\\[\\d+:\\d+:\\d+\\] Starting 'clean-styles'\\.\\.\\.$", + // A regular expression signalling that a watched tasks ends executing. + "watchedTaskEndsRegExp": "^\\[\\d+:\\d+:\\d+\\] Finished 'styles' after \\d+" + } + } + ] +} +*/ + +// Uncomment the following section to use jake to build a workspace +// cloned from https://github.com/Microsoft/TypeScript.git +/* +{ + "version": "0.1.0", + // Task runner is jake + "command": "jake", + // Need to be executed in shell / cmd + "isShellCommand": true, + "showOutput": "silent", + "tasks": [ + { + // TS build command is local. + "taskName": "local", + // Make this the default build command. + "isBuildCommand": true, + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the redefined Typescript output problem matcher. + "problemMatcher": [ + "$tsc" + ] + } + ] +} +*/ + +// Uncomment the section below to use msbuild and generate problems +// for csc, cpp, tsc and vb. The configuration assumes that msbuild +// is available on the path and a solution file exists in the +// workspace folder root. +/* +{ + "version": "0.1.0", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true" + ], + "taskSelector": "/t:", + "showOutput": "silent", + "tasks": [ + { + "taskName": "build", + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard MS compiler pattern to detect errors, warnings + // and infos in the output. + "problemMatcher": "$msCompile" + } + ] +} +*/ + +// Uncomment the following section to use msbuild which compiles Typescript +// and less files. +/* +{ + "version": "0.1.0", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true" + ], + "taskSelector": "/t:", + "showOutput": "silent", + "tasks": [ + { + "taskName": "build", + // Show the output window only if unrecognized errors occur. + "showOutput": "silent", + // Use the standard MS compiler pattern to detect errors, warnings + // and infos in the output. + "problemMatcher": [ + "$msCompile", + "$lessCompile" + ] + } + ] +} +*/ +// A task runner example that defines a problemMatcher inline instead of using +// a predfined one. +/* +{ + "version": "0.1.0", + "command": "tsc", + "isShellCommand": true, + "args": ["HelloWorld.ts"], + "showOutput": "silent", + "problemMatcher": { + // The problem is owned by the typescript language service. Ensure that the problems + // are merged with problems produced by Visual Studio's language service. + "owner": "typescript", + // The file name for reported problems is relative to the current working directory. + "fileLocation": ["relative", "${cwd}"], + // The actual pattern to match problems in the output. + "pattern": { + // The regular expression. Matches HelloWorld.ts(2,10): error TS2339: Property 'logg' does not exist on type 'Console'. + "regexp": "^([^\\s].*)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$", + // The match group that denotes the file containing the problem. + "file": 1, + // The match group that denotes the problem location. + "location": 2, + // The match group that denotes the problem's severity. Can be omitted. + "severity": 3, + // The match group that denotes the problem code. Can be omitted. + "code": 4, + // The match group that denotes the problem's message. + "message": 5 + } + } +} +*/ \ No newline at end of file diff --git a/examples/avatar.js b/examples/avatar.js deleted file mode 100644 index 32ad48a8f..000000000 --- a/examples/avatar.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * A bot that shows how to mention users in messages and how to - * access user avatars. - */ - -var Discord = require( "../" ); -var myBot = new Discord.Client(); - -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -myBot.on( "message", function( message ) { - // React to all messages with the content "$avatar" - if ( message.content === "$avatar" ) { - // Obtain the user who requested the avatar. - var user = message.author; - - // Check whether the user actually has an avatar. - if ( user.avatar ) { - // Construct the avatar URL from the user ID and the avatar ID. - var url = "https://discordapp.com/api/users/" + user.id + "/avatars/" + user.avatar + ".jpg"; - - // A user can be mentioned in a message by inserting the string obtained - // by user.mention() into the message. - // Note that simply writing "@user" will NOT work. - this.sendMessage( message.channel, message.author.mention() + ", here's your avatar: " + url ); - } else { - // Nothing should be done if the user has not set an avatar. - this.sendMessage( message.channel, message.author.mention() + ", you don't have an avatar!" ); - } - } -} ); diff --git a/examples/formatting.js b/examples/formatting.js deleted file mode 100644 index 02756eaaa..000000000 --- a/examples/formatting.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Discord uses a subset of Markdown for formatting, so adding formatting to - * messages is as simple as inserting the formatting codes into the message. - */ - -var Discord = require( "../" ); -var myBot = new Discord.Client(); - -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -myBot.on( "message", function( message ) { - // React to all messages with the content "$formatting". - if ( message.content === "$formatting" ) { - // Show off formatting by sending a simple message with formatting codes. - this.sendMessage( message.channel, "**bold** ****semibold**** *italic* " + - "_**bold and italic**_ __underline__ ~~strikethrough~~" ); - } -} ); diff --git a/examples/pingpong.js b/examples/pingpong.js deleted file mode 100644 index 51a2664e3..000000000 --- a/examples/pingpong.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * A basic bot that shows how to connect to a Discord account, - * how to listen to messages and how to send messages. - * - * This bot responds to every "ping" message with a "pong". - */ - -var Discord = require( "../" ); - -// Create the bot -var myBot = new Discord.Client(); - -// Login with an example email and password -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// Add a listener to the "message" event, which triggers upon receiving -// any message -myBot.on( "message", function( message ) { - // message.content accesses the content of the message as a string. - // If it is equal to "ping", then the bot should respond with "pong". - if ( message.content === "ping" ) { - // Send a message ("pong") to the channel the message was sent in, - // which is accessed by message.channel. - this.sendMessage( message, "pong" ); - } -} ); diff --git a/examples/presence.js b/examples/presence.js deleted file mode 100644 index 9014feea2..000000000 --- a/examples/presence.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * A bot that shows how to listen to presence update events, such as a user - * joining or leaving. - */ - -var Discord = require( "../" ); -var myBot = new Discord.Client(); - -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// The "presence" event is triggered when a user joins a server, leaves it or -// goes away. -// The status parameter can be "online", "offline" or "idle", respectively. -myBot.on( "presence", function( user, status, server ) { - // Send a message on the default channel of the server, as presence updates - // are not restricted to one channel. - var message = user.mention() + " is " + status + " in " + server.name + "!"; - console.log(message); - this.sendMessage( server.getDefaultChannel(), message ); -} ); diff --git a/examples/query.js b/examples/query.js deleted file mode 100644 index 9341e7e98..000000000 --- a/examples/query.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * A bot that shows how to access and search the logs of a specific channel. - * Specifically, it returns the last message from a given user in the last - * 100 messages. - */ - -var Discord = require( "discord.js" ); -var myBot = new Discord.Client(); - -myBot.login( "hello@example.com", "password1" ); - -myBot.on( "message", function( message ) { - // React to all messages starting with "$query". - if ( message.content.startsWith( "$query" ) ) { - // Obtain the channel for which logs should be accessed. - var channel = message.channel; - - // Find all the arguments to the command. - var arguments = message.content.split( " " ); - - // Get the first argument specifically, as it contains the username - // to be queried for. - var username = arguments.slice( 1 ).join( " " ); - - // Exit the event handler unless the user exists. - if ( !username ) { - myBot.sendMessage( channel, "That user doesn't exist!" ); - return; - } - - // The getChannelLogs() function takes the channel that should be accessed, - // the amount of messages to query and a callback as its arguments. - myBot.getChannelLogs( channel, 100, function( error, messageList ) { - // filter() takes three arguments, the key to be filtered for (in this - // case the username, so "username"), the value to look for, and whether - // only the first finding should be returned (true) or a list of all - // findings (false). - - // Check to see if there is an error, if there isn't this will be null, - // which equates to false in a conditional. - if ( error ) { - // There was an error, so stop proceeding as if there is an error - // retrieving logs, no logs are returned. We should tell the - // users that there was an error retrieving logs and return. - myBot.sendMessage( channel, "There was an error retrieving logs!" ); - return; - } - - var message = messageList.filter( "username", username, true ); - - // Only continue if the message has been found - if ( message ) { - myBot.sendMessage( channel, "The last message from user " + username + - " is: \"" + message.content + "\"." ). - } else { - myBot.sendMessage( "That user has not sent a message " + - "for the last 100 messages!" ) - } - } ); - } -} ); diff --git a/examples/status.js b/examples/status.js deleted file mode 100644 index 9ee2b9a6a..000000000 --- a/examples/status.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * A bot that doesn't interact with Discord, but instead shows how to listen - * to the "ready" and "disconnected" events, that are triggered when the bot - * starts up or shuts down, respectively. - */ - -var Discord = require( "../" ); -var myBot = new Discord.Client(); - -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// The "disconnected" event is triggered after the connection to Discord -// ended. -// It is also triggered when the connection attempt fails, for example due -// to a wrong password. -myBot.on( "disconnected", function(e) { - console.log( "Bot disconnected from Discord -", e.reason ); -} ); diff --git a/hydrabot/.gitignore b/hydrabot/.gitignore deleted file mode 100644 index 070bc70aa..000000000 --- a/hydrabot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -config.json -authority.json diff --git a/hydrabot/README.md b/hydrabot/README.md deleted file mode 100644 index 90aeffc4b..000000000 --- a/hydrabot/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# hydrabot -Hydrabot is an open-source bot made with the intents of demonstrating the capabilities of [discord.js](https://github.com/hydrabolt/discord.js/). - -### Set up -The easiest setup would be to clone the discord.js repo, and then open a terminal/cmd in this directory and run `node hydrabot.js`. - -If you don't want to clone the repo but instead just use this folder, you need to edit `hydrabot.js` to use `require("discord.js")` as opposed to `require("../")`. Cloned directories will always be using the latest **discord.js**. - -### Setting up credentials - -Create `config.json` to use your Discord email and password, and then run `node hydrabot.js`. - -What config.json should look like: -```js -{ - "email" : "your email", - "password" : "your password" -} -``` diff --git a/hydrabot/authority.js b/hydrabot/authority.js deleted file mode 100644 index 1f7c1c4af..000000000 --- a/hydrabot/authority.js +++ /dev/null @@ -1,37 +0,0 @@ -var fs = require( "fs" ); - -var authCache = {}; - -exports.init = function() { - try { - var fd = fs.openSync( "./authority.json", "wx" ); - exports.writeCache(); - } catch ( e ) { - if ( e.errno !== -4075 ){ - throw e; - }else{ - authCache = JSON.parse(fs.readFileSync("./authority.json", "utf8")); - } - } -} - -exports.getLevel = function(user){ - - if(authCache[user.id]) - return authCache[user.id]; - else - return 0; - -} - -exports.setLevel = function(user, level){ - authCache[user.id] = level; - exports.writeCache(); -} - -exports.writeCache = function() { - fs.writeFile( './authority.json', JSON.stringify(authCache), function( err ) { - if ( err ) - console.log("Error saving Authority Caches - " + err.code); - } ); -} diff --git a/hydrabot/commands.js b/hydrabot/commands.js deleted file mode 100644 index b499d9dce..000000000 --- a/hydrabot/commands.js +++ /dev/null @@ -1,516 +0,0 @@ -var Authority = require( "./authority.js" ); -var BotClass = require( "./hydrabot.js" ); -var Discord = BotClass.Discord; - -Commands = []; - -Commands[ "info" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var verbose = hasFlag( params, "verbose" ) || hasFlag( params, "v" ); - var user = getUser( message, params ); - - bot.reply( message, [ - "here's some info on " + user.mention() + ":", - "In channel **#" + message.channel.name + "**" + ( verbose ? " - ID *" + message.channel.id + "*" : "" ), ( message.isPM() ? - "You're in a private conversation with me!" + ( verbose ? " The ID is " + message.channel.id : "" ) : "In the server **" + message.channel.server.name + "**" + ( verbose ? " - ID *" + message.channel.server.id + "*" : "" ) - ), - "User ID is *" + user.id + "*", - "Authority/OP Level to me is **" + Authority.getLevel( user ) + "**" - ], function( err ) { - if ( err ) - console.log( err ); - } ); - - } -} - -Commands[ "loading" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var progress = 0; - var currentMessage; - var bars = 20; - - function getM() { - var before = progress; - var after = bars - progress; - var ret = ""; - for ( x = 0; x < before; x++ ) { - ret += "-"; - } - ret += "**#**"; - for ( y = 0; y < after; y++ ) { - ret += "-"; - } - return ret; - } - - function doProg() { - if ( progress === ( bars + 1 ) ) { - progress = 0; - } - - if ( currentMessage ) { - bot.updateMessage( currentMessage, getM(), function( err, msg ) { - if ( !err ) - currentMessage = msg; - } ); - progress++; - } - - } - - bot.sendMessage( message.channel, getM(), function( err, message ) { - currentMessage = message; - setInterval( doProg, 200 ); - } ); - - } -} - -Commands[ "flashy" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var phase = 0; - var msg; - - var textToSay = getKey( params, "m", "FLASH" ); - var speed = parseInt( getKey( params, "s", "500" ) ); - - function change() { - if ( msg ) { - - var highlighting = ( ( phase % 2 ) === 0 ? "**" : "" ); - phase++; - bot.updateMessage( msg, highlighting + textToSay + highlighting, function( err, message ) { - if ( !err ) { - msg = message; - } - } ); - } - } - - bot.sendMessage( message.channel, textToSay, function( err, message ) { - msg = message; - setInterval( change, speed ); - } ); - - } -} - -Commands[ "echo" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - bot.sendMessage( message, params.join( " " ), function( err, msg ) { - if ( err ) { - bot.sendMessage( message, "Unable to echo!" ); - console.log( err ); - } - } ); - - } -} - -Commands[ "auth" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var level = getKey( params, "level", "0" ); - var method = hasFlag( params, "set" ) ? "set" : "get"; - var user = getUser( message, params ); - - if ( method === "set" ) { - if ( authLevel( message.author ) <= level ) { - bot.reply( message, "that authority level is too high for you to set!" ); - } else if ( user.equals( message.author ) ) { - bot.reply( message, "you can't alter your own authority level!" ); - } else if ( authLevel( user ) >= authLevel( message.author ) ) { - bot.reply( message, "that user has a higher or equal OP level to you!" ); - } else if ( level < 0 ) { - bot.reply( message, "that level's a bit too low :P" ); - } else { - setAuthLevel( user, level ); - bot.reply( message, "I set the authority of " + user.mention() + " to **" + level + "**" ); - } - } else { - bot.reply( message, user.equals( message.author ) ? "Your authority level is **" + authLevel( user ) + "**" : "The authority level of " + user.mention() + " is **" + authLevel( user ) + "**" ); - } - - } -} - -Commands[ "clear" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - if ( !message.isPM() ) { - if ( authLevel( message.author ) < 1 ) { - bot.reply( message, BotClass.AUTH_ERROR ); - return; - } - } - - var initMessage = false, - cleared = false; - - bot.getChannelLogs( message.channel, 250, function( err, logs ) { - - if ( err ) { - bot.sendMessage( "Couldn't grab logs to delete messages." ); - } else { - - var deletedCount = 0, - failedCount = 0, - todo = logs.length(); - for ( msg of logs.contents ) { - if ( msg.author.equals( bot.user ) ) { - bot.deleteMessage( msg, function( err ) { - todo--; - if ( err ) - failedCount++; - else - deletedCount++; - - if ( todo === 0 ) { - bot.reply( - message, - "Done! " + deletedCount + " message(s) were deleted, with " + failedCount + " error(s).", - false, { - selfDestruct: 5000 - } - ); - cleared = true; - deleteInitMessage(); - } - } ); - } else { - todo--; - } - } - - } - - } ); - - bot.reply( message, "clearing up my messages...", function( err, msg ) { - if ( !err ) { - initMessage = msg; - if ( cleared ) - deleteInitMessage(); - } - } ); - - function deleteInitMessage() { - if ( initMessage ) { - bot.deleteMessage( initMessage ); - } - } - - } -} - -Commands[ "leave" ] = { - oplevel: 3, - fn: function( bot, params, message ) { - - var silent = hasFlag( params, "s" ) || hasFlag( params, "silent" ); - - if ( message.isPM() ) { - bot.reply( message, "Umm... I can't leave PMs... How awkward..." ); - } else { - - if ( !silent ) - bot.reply( message, "Ok ;( I'm leaving!" ); - - bot.leaveServer( message.channel.server, function( err ) { - if ( err ) { - bot.reply( message, "There was an error leaving... how awkward." ); - } - } ); - } - } -} - -Commands[ "avatar" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var user = getUser( message, params, bot ); - - if ( !user.avatar ) { - bot.sendMessage( message.channel, user.mention() + " does not have an avatar!" ); - } else { - bot.reply( message, user.getAvatarURL() ); - } - } -} - -Commands[ "setusername" ] = { - oplevel: 3, - fn: function( bot, params, message ) { - - var name = getKey( params, "name", "Boris Johnson" ); - - bot.setUsername( name, function( err ) { - if ( err ) - bot.reply( message, err ); - } ) - - } -} - -Commands[ "cat" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var http = require( "http" ); - var request = require( 'request' ); - - bot.sendFile( message, request("http://thecatapi.com/api/images/get?type=jpg"), "cat.jpg", function( err ) { - if(err) - bot.reply( message, err ); - } ); - - } -} - -Commands[ "icon" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - if ( message.isPM() ) { - bot.reply( message, "PMs don't have avatars!" ); - return; - } - - if ( !message.channel.server.icon ) { - bot.reply( message, "this server does not have an icon!" ); - return; - } - - bot.reply( message, message.channel.server.getIconURL() ); - - } -} - -Commands[ "avataritup" ] = { - oplevel: 2, - fn: function( bot, params, message ) { - - console.log( message.channel ); - bot.sendMessage( message, message.channel.server.members.getValues( "avatar" ).join( "\n" ) ); - - } -} - -Commands[ "feedback" ] = { - - oplevel: 0, - fn: function( bot, params, message ) { - - var amount = getKey( params, "amount" ) || getKey( params, "n" ) || 1000; - - bot.getChannelLogs( message.channel, amount, function( err, logs ) { - - console.log( logs ); - - if ( err ) { - bot.reply( message, "an error occurred when grabbing the logs.", false, { - selfDestruct: 3000 - } ); - } else { - - var found = []; - for ( msg of logs.contents ) { - - if ( ~msg.content.indexOf( "[request" ) || ~msg.content.indexOf( "[feature" || ~msg.content.indexOf( "[suggestion" ) ) ) { - if ( msg.content.length > 10 ) { - found.push( msg ); - } - } - - } - - bot.sendMessage( message.author, "Ok, here's a rundown of all feature requests so far:", function( err, ms ) { - - if ( !err ) - gothroughit(); - - } ); - - bot.reply( message, "I found " + found.length + " result(s) that matched this. I'll send it to you in a PM.", false, { - selfDestruct: 3000 - } ); - - function gothroughit() { - for ( msg of found ) { - - bot.sendMessage( message.author, "**" + msg.author.username + "** said:\n " + msg.content ); - - } - } - } - } ); - - } - -} - -Commands[ "acceptinvite" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var inv = getKey( params, "i" ); - - bot.joinServer( inv, function( err, server ) { - if ( err ) { - bot.reply( message, "I couldn't join that server :(" ); - } else { - bot.reply( message, "I joined **" + server.name + "**, a server with " + server.channels.length() + " channels and " + server.members.length() + " members." ); - } - } ); - - } -} - -Commands[ "filtertest" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - console.log( message.channel.server.members.filter( "username", "HYDRABOLT" ) ); - console.log( message.channel.server.members.filter( "username", "HYDRABOLT", false, true ) ); - } -} - -Commands[ "test" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - console.log( message.channel.server.channels.filter( "name", "a", true ) ); - - } -} - -Commands[ "remind" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var time = parseInt( getKey( params, "t" ) || getKey( params, "time" ) ) * 1000 || 21000; - var msg = getKey( params, "m" ) || getKey( params, "msg" ) || getKey( params, "message" ); - - bot.reply( message, "I'll remind you to *" + msg + "* in *" + time / 1000 + "* seconds.", false, true, { - selfDestruct: time - } ); - - setTimeout( send, time ); - - function send() { - bot.sendMessage( message.author, time + " seconds are up! **" + msg + "**." ); - } - - } -} - -Commands[ "annoy" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var user = getUser( message, params ); - - bot.sendMessage( user, "Ha I'm annoying you on " + message.author.mention() + "'s request!" ); - - } -} - -Commands[ "activity" ] = { - oplevel: 0, - fn: function( bot, params, message ) { - - var amount = getKey( params, "amount" ) || getKey( params, "n" ) || 250; - var limit = getKey( params, "limit" ) || getKey( params, "l" ) || 10; - - bot.getChannelLogs( message.channel, amount, function( err, logs ) { - - if ( err ) { - bot.reply( message, "error gettings logs." ); - } else { - - var activity = {}, - count = 0; - for ( msg of logs.contents ) { - - count = logs.length(); - - if ( !activity[ msg.author.id ] ) - activity[ msg.author.id ] = 0; - activity[ msg.author.id ]++; - } - - var report = "here's a list of activity over the last " + count + " messages :\n\n"; - - var usernames = {}; - for ( id in activity ) { - usernames[ id ] = bot.getUser( id ).username; - } - - for ( id in activity ) { - report += usernames[ id ] + " | " + activity[ id ] + " | **" + Math.round( ( activity[ id ] / count ) * 100 ) + "%**.\n"; - } - - bot.reply( message, report, false, false ); - } - - } ); - - } -} - -exports.Commands = Commands; - -function hasFlag( array, flag ) { - return ~array.indexOf( flag ); -} - -function getKey( array, key, def ) { - - for ( element of array ) { - var chunks = element.split( "=" ); - if ( chunks.length > 1 ) { - if ( chunks[ 0 ] == key ) { - return chunks[ 1 ]; - } - } - } - - return def; - -} - -function authLevel( user ) { - return Authority.getLevel( user ); -} - -function setAuthLevel( user, level ) { - Authority.setLevel( user, level ); -} - -function getUser( message, params, bot ) { - var usr = false; - if ( !message.isPM() ) { - var wantedUser = getKey( params, "user", false ) || getKey( params, "u", false ); - if ( wantedUser ) { - if ( bot ) { - console.log( bot.getUsers().length() ); - return bot.getUsers().filter( "username", wantedUser, true ); - } - usr = message.channel.server.members.filter( Discord.isUserID( wantedUser ) ? "id" : "username", wantedUser, true ); - } - } - if ( !usr ) - usr = message.author; - return usr; -} diff --git a/hydrabot/hydrabot.js b/hydrabot/hydrabot.js deleted file mode 100644 index 4f010266d..000000000 --- a/hydrabot/hydrabot.js +++ /dev/null @@ -1,132 +0,0 @@ -// If you did not clone discord.js, change the require parameter to `discord.js` -// and then run `npm install --save discord.js` in the same directory as this -// file. The bot should then run. -var Discord = require( "../" ); -exports.Discord = Discord; - -// Load the config file. If you have not already, make one that follows the -// structure : { "email" : "discordEmail", "password" : "discordPassword" } -var BotConfig = require( "./config.json" ); - -// Load the commands file -var Commands = require( "./commands.js" ).Commands; - -// Load the Authority handler -var Authority = require( "./authority.js" ); - -// Initialise it -Authority.init(); - -// Create a new Discord Client -var hydrabot = new Discord.Client(); - -// An array of single character prefixes the bot will respond to -var commandPrefixes = [ "$", "£", "`" ]; - -// Log the client in using the auth details in config.json - -hydrabot.on("debug", function(m){ - console.log("debug", m); -}) - -console.time("hydrabotbenchmark"); -hydrabot.login( BotConfig.email, BotConfig.password ); -var time = Date.now(); - -// When the bot is ready to go, output to the console -hydrabot.on( "ready", function() { - console.timeEnd("hydrabotbenchmark"); -} ); - -hydrabot.on("userupdate", function(ol, ne){ - - var serversInvolved = hydrabot.getServers().deepFilter(["members", "id"], ol.id); - - for(server of serversInvolved.contents){ - hydrabot.sendMessage(server.getDefaultChannel(), "Just sayin', "+ol.username+" changed their name to "+ne.username+". I know. Disgraceful.", function(err){ - console.log(err); - }, { - selfDestruct: 5000 - }); - } - -}); - -// When the bot gets disconnected, exit. -hydrabot.on( "disconnected", function( obj ) { - // Say we couldn't connect and then exit - console.log( "Disconnected - " + obj.reason ); - process.exit( 0 ); -} ); - -hydrabot.on("messageDelete", function(message){ - console.log(message); -}) - -hydrabot.on("messageUpdate", function(former, edit){ - /* - if(former){ - - if(former.author.equals(this.user) || former.content === edit.content){ - return; - } - - var seconds = Math.round((Date.now() - former.time) / 1000); - - var channel = former.channel; - hydrabot.sendMessage(channel, "**"+former.author.username + "** (edit from message "+seconds+" seconds ago):\n " + former.content); - - } - */ -}) - -hydrabot.on( "message", function( message ) { - - // if the message doesn't begin with a valid command prefix exit - - if ( commandPrefixes.indexOf( message.content.charAt( 0 ) ) == -1 ) - return; - - var command = "", - params = []; //set the message details - - // remove the prefix from the start of the message - message.content = message.content.substr( 1 ); - - // split the message by slashes. This will yield something - // like: ["command", "a", "b", "c"]. - var chunks = message.content.split( "/" ); - - for ( key in chunks ) { //loop through the chunks and trim them - chunks[ key ] = chunks[ key ].trim(); - } - - command = chunks[ 0 ]; //the first param will be the command - params = chunks.slice( 1 ); - - // it's less messy if we outsource to another function - handleMessage( command, params, message ); - -} ); - -function handleMessage( command, params, message ) { - - if ( Commands[ command ] ) { - - if ( Authority.getLevel( message.author ) >= Commands[ command ].oplevel ) { - //user has authority to do this - Commands[ command ].fn( hydrabot, params, message ); - - } else { - //user doesn't have authority - hydrabot.reply( message, exports.AUTH_ERROR ); - } - - } else { - hydrabot.reply( message, exports.NOT_FOUND ); - } - -} - -exports.AUTH_ERROR = "you don't have authority to do this!"; -exports.NOT_FOUND = "that command was not found!"; diff --git a/index.js b/index.js deleted file mode 100644 index d8b9a1560..000000000 --- a/index.js +++ /dev/null @@ -1,1087 +0,0 @@ -var request = require("superagent"); -var Endpoints = require("./lib/endpoints.js"); -var Server = require("./lib/server.js").Server; -var Message = require("./lib/message.js").Message; -var User = require("./lib/user.js").User; -var Channel = require("./lib/channel.js").Channel; -var List = require("./lib/list.js").List; -var Invite = require("./lib/invite.js").Invite; -var PMChannel = require("./lib/PMChannel.js").PMChannel; -var WebSocket = require('ws'); -var Internal = require("./lib/internal.js").Internal; -var TokenManager = require("./lib/TokenManager.js").TokenManager; - -var serverCreateRequests = [], - globalLoginTime = Date.now(); - -function tp(time) { - return Date.now() - time; -} - -/** - * The wrapper module for the Discord Client, also provides some helpful objects. - * - * @module Discord - */ -exports; - -exports.Endpoints = Endpoints; -exports.Server = Server; -exports.Message = Message; -exports.User = User; -exports.Channel = Channel; -exports.List = List; -exports.Invite = Invite; -exports.PMChannel = PMChannel; - -/** - * The Discord Client used to interface with the Discord API. Instantiate this to start writing code - * with discord.js - * @class Client - * @constructor - * @param {Object} [options] An object containing configurable options. - * @param {Number} [options.maxmessage=5000] The maximum amount of messages to be stored per channel. - */ - -exports.Client = function (shouldUseTokenManager) { - - /** - * Contains the options of the client - * @attribute options - * @type {Object} - */ - if (shouldUseTokenManager) - this.tokenManager = new TokenManager("./", "tokencache.json"); - /** - * Contains the token used to authorise HTTP requests and WebSocket connection. Received when login was successful. - * @attribute token - * @readonly - * @type {String} - */ - this.token = ""; - /** - * Indicates whether the client is logged in or not. Does not indicate whether the client is ready. - * @attribute loggedIn - * @readonly - * @type {Boolean} - */ - this.loggedIn = false; - /** - * The WebSocket used when receiving message and other event updates. - * @type {WebSocket} - * @attribute websocket - * @readonly - */ - this.websocket = null; - /** - * An Object containing the functions tied to events. These should be set using Client.on(); - * @type {Object} - * @attribute events - */ - this.events = {}; - /** - * The User of the Client class, set when the initial startup is complete. - * @attribute user - * @type {User} - * @readonly - */ - this.user = null; - /** - * Indicates whether the Client is ready and has cached all servers it as aware of. - * @type {Boolean} - * @attribute ready - * @readonly - */ - this.ready = false; - /** - * A List containing all the Servers the Client has access to. - * @attribute serverList - * @type {List} - * @readonly - */ - this.serverList = new List("id"); - /** - * A List containing all the PMChannels the Client has access to. - * @attribute PMList - * @type {List} - * @readonly - */ - this.PMList = new List("id"); - -} - -/** - * Returns a list of all servers that the Discord Client has access to. - * - * @method getServers - * @return {List} ServerList - */ -exports.Client.prototype.getServers = function () { - return this.serverList; -} - -/** - * Returns a list of all servers that the Discord Client has access to. - * @method getChannels - * @return {List} Channelist - */ -exports.Client.prototype.getChannels = function () { - return this.serverList.concatSublists("channels", "id"); -} - -/** - * Returns a Server matching the given id, or false if not found. Will return false if the server is not cached or not available. - * @method getServer - * @param {String/Number} id The ID of the Server - * @return {Server} The Server matching the ID - */ -exports.Client.prototype.getServer = function (id) { - return this.getServers().filter("id", id, true); -} - -/** - * Returns a Channel matching the given id, or false if not found. Will return false if the Channel is not cached or not available. - * @method getChannel - * @param {String/Number} id The ID of the Channel - * @return {Server} The Channel matching the ID - */ -exports.Client.prototype.getChannel = function (id) { - return this.getChannels().filter("id", id, true); -} - -/** - * Returns a Channel matching the given name, or false if not found. Will return false if the Channel is not cached or not available. - * @method getChannelByName - * @param {String/Number} name The Name of the Channel - * @return {Server} The Channel matching the Name - */ -exports.Client.prototype.getChannelByName = function (name) { - return this.getChannels().filter("name", name, true); -} - -/** - * Triggers an .on() event. - * @param {String} event The event to be triggered - * @param {Array} args The arguments to be passed onto the method - * @return {Boolean} whether the event was triggered successfully. - * @method triggerEvent - * @private - */ -exports.Client.prototype.triggerEvent = function (event, args) { - - if (!this.ready && event !== "raw" && event !== "disconnected" && event !== "debug") { //if we're not even loaded yet, don't try doing anything because it always ends badly! - return false; - } - - if (this.events[event]) { - this.events[event].apply(this, args); - return true; - } else { - return false; - } - -} - -/** - * Binds a function to an event - * @param {String} name The event name which the function should be bound to. - * @param {Function} fn The function that should be bound to the event. - * @method on - */ -exports.Client.prototype.on = function (name, fn) { - this.events[name] = fn; -} - -/** - * Unbinds a function from an event - * @param {String} name The event name which should be cleared - * @method off - */ -exports.Client.prototype.off = function (name) { - this.events[name] = function () { }; -} - -exports.Client.prototype.cacheServer = function (id, cb, members) { - var self = this; - var serverInput = {}; - - if (typeof id === 'string' || id instanceof String) { - //actually an ID - - if (this.serverList.filter("id", id).length > 0) { - return; - } - - Internal.XHR.getServer(self.token, id, function (err, data) { - if (!err) { - makeServer(data); - } - }) - - } else { - // got objects because SPEEEDDDD - - if (this.serverList.filter("id", id.id).length > 0) { - return; - } - serverInput = id; - id = id.id; - makeServer(serverInput); - - } - - function channelsFromHTTP() { - Internal.XHR.getChannel(self.token, id, function (err) { - if (!err) - cacheChannels(res.body); - }) - } - - var server; - - function makeServer(dat) { - server = new Server(dat.region, dat.owner_id, dat.name, id, serverInput.members || dat.members, dat.icon, dat.afk_timeout, dat.afk_channel_id); - if (dat.channels) - cacheChannels(dat.channels); - else - channelsFromHTTP(); - } - - function cacheChannels(dat) { - - var channelList = dat; - for (var channel of channelList) { - server.channels.add(new Channel(channel, server)); - } - self.serverList.add(server); - - cb(server); - } - -} - -/** - * Logs the Client in with the specified credentials and begins initialising it. - * @async - * @method login - * @param {String} email The Discord email. - * @param {String} password The Discord password. - * @param {Function} [callback] Called when received reply from authentication server. - * @param {Object} callback.error Set to null if there was no error logging in, otherwise is an Object that - * can be evaluated as true. - * @param {String} callback.error.reason The reason why there was an error - * @param {Object} callback.error.error The raw XHR error. - * @param {String} callback.token The token received when logging in - */ -exports.Client.prototype.login = function (email, password, callback, noCache) { - - globalLoginTime = Date.now(); - - this.debug("login called at " + globalLoginTime); - - var self = this; - callback = callback || function () { }; - - if (noCache == undefined || noCache == null) { - noCache = false; - } - - self.connectWebsocket(); - - if (this.tokenManager) { - if (this.tokenManager.exists(email) && !noCache) { - - var token = this.tokenManager.getToken(email, password); - if (!token.match(/[^\w.-]+/g)) { - done(this.tokenManager.getToken(email, password)); - self.debug("loaded token from caches in " + tp(globalLoginTime)); - return; - } else { - self.debug("error getting token from caches, using default auth"); - } - } - } - var time = Date.now(); - Internal.XHR.login(email, password, function (err, token) { - if (err) { - self.triggerEvent("disconnected", [{ - reason: "failed to log in", - error: err - }]); - self.websocket.close(); - self.debug("failed to login in " + tp(globalLoginTime)); - } else { - if (!noCache) { - self.tokenManager.addToken(email, token, password); - } - self.debug("loaded token from auth servers in " + tp(globalLoginTime)); - done(token); - } - - }); - - function done(token) { - self.email = email; - self.password = password; - self.debug("using token " + token); - self.token = token; - self.websocket.sendData(); - self.loggedIn = true; - callback(null, token); - } -} - -/** - * Replies to a message with a given message - * @param {Message/User/Channel/Server/String} destination Where the message should be sent. Channel IDs can also be used here. - * @param {String/Message/Array} toSend If a message, the message's content will be sent. If an array, a message will be sent of - * the array seperated by a newline. If a String, the string will be sent. - * @param {Function} callback Called when a response from the API has been received, the message has either been sent or not. - * @param {Object} callback.error If there was an error, this would be an XHR Error object. Otherwise, it will be null. - * @param {Message} callback.message If there were no errors, this will be the sent message in Message form. - * @param {Object} options see sendMessage(options) - * @method reply - */ -exports.Client.prototype.reply = function (destination, toSend, callback, options) { - - if (toSend instanceof Array) { - toSend = toSend.join("\n"); - } - - toSend = destination.author.mention() + ", " + toSend; - - this.sendMessage(destination, toSend, callback, options); - -} - -exports.Client.prototype.connectWebsocket = function (cb) { - - var self = this; - - var sentInitData = false; - - this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); - this.websocket.onclose = function (e) { - self.triggerEvent("disconnected", [{ - reason: "websocket disconnected", - error: e - }]); - }; - this.websocket.onmessage = function (e) { - - self.triggerEvent("raw", [e]); - - var dat = JSON.parse(e.data); - var webself = this; - - switch (dat.op) { - - case 0: - if (dat.t === "READY") { - - self.debug("got ready packet"); - - var data = dat.d; - - self.user = new User(data.user); - - var _servers = data.guilds, - servers = []; - - var cached = 0, - toCache = _servers.length; - - for (x in data.private_channels) { - self.PMList.add(new PMChannel(data.private_channels[x].recipient, data.private_channels[x].id)); - } - - for (x in _servers) { - _server = _servers[x]; - - self.cacheServer(_server, function (server) { - cached++; - if (cached === toCache) { - self.ready = true; - self.triggerEvent("ready"); - self.debug("ready triggered"); - } - }); - } - - setInterval(function () { - webself.keepAlive.apply(webself); - }, data.heartbeat_interval); - - } else if (dat.t === "MESSAGE_CREATE") { - var data = dat.d; - - var channel = self.getChannel(data.channel_id); - var message = new Message(data, channel); - self.triggerEvent("message", [message]); - if (channel.messages) - channel.messages.add(message); - - } else if (dat.t === "MESSAGE_DELETE") { - var data = dat.d; - - var channel = self.getChannel(data.channel_id); - - if (!channel.messages) - return; - - var _msg = channel.messages.filter("id", data.id, true); - - if (_msg) { - self.triggerEvent("messageDelete", [_msg]); - channel.messages.removeElement(_msg); - } - - } else if (dat.t === "MESSAGE_UPDATE") { - - var data = dat.d; - if (!self.ready) - return; - - var formerMessage = false; - - var channel = self.getChannel(data.channel_id); - - if (channel) { - - formerMessage = channel.messages.filter("id", data.id, true); - var newMessage; - - data.author = data.author || formerMessage.author; - data.timestamp = data.time || formerMessage.time; - data.content = data.content || formerMessage.content; - data.channel = data.channel || formerMessage.channel; - data.id = data.id || formerMessage.id; - data.mentions = data.mentions || formerMessage.mentions; - data.mention_everyone = data.mention_everyone || formerMessage.everyoneMentioned; - data.embeds = data.embeds || formerMessage.embeds; - - try { - newMessage = new Message(data, channel); - } catch (e) { - self.debug("dropped a message update packet"); - return; - } - - self.triggerEvent("messageUpdate", [formerMessage, newMessage]); - - if (formerMessage) - channel.messages.updateElement(formerMessage, newMessage); - else - channel.messages.add(newMessage); - - } - - } else if (dat.t === "PRESENCE_UPDATE") { - - var data = dat.d; - var getUser = self.getUser(data.user.id); - if (getUser) { - //user already exists - var usr = new User(data.user); - if (usr.equalsStrict(getUser)) { - //no changes, actually a presence. - } else { - if (self.updateUserReferences(data.user.id, getUser, new User(data.user))) { - self.triggerEvent("userupdate", [getUser, usr]); - } - } - } - self.triggerEvent("presence", [new User(data.user), data.status, self.serverList.filter("id", data.guild_id, true)]); - - } else if (dat.t === "GUILD_DELETE") { - - var deletedServer = self.serverList.filter("id", dat.d.id, true); - - if (deletedServer) { - self.triggerEvent("serverDelete", [deletedServer]); - } - - } else if (dat.t === "CHANNEL_DELETE") { - - var delServer = self.serverList.filter("id", dat.d.guild_id, true); - - if (delServer) { - var channel = delServer.channels.filter("id", dat.d.id, true); - - if (channel) { - self.triggerEvent("channelDelete", [channel]); - } - } - - } else if (dat.t === "GUILD_CREATE") { - - if (!self.serverList.filter("id", dat.d.id, true)) { - self.cacheServer(dat.d, function (server) { - if (serverCreateRequests[server.id]) { - serverCreateRequests[server.id](null, server); - serverCreateRequests[server.id] = null; - } else { - self.triggerEvent("serverJoin", [server]); - } - }); - } - - } else if (dat.t === "CHANNEL_CREATE") { - - var srv = self.serverList.filter("id", dat.d.guild_id, true); - - if (srv) { - - if (!srv.channels.filter("id", dat.d.d, true)) { - - var chann = new Channel(dat.d, srv); - - srv.channels.add(new Channel(dat.d, srv)); - self.triggerEvent("channelCreate", [chann]); - - } - - } - - } else if (dat.t === "USER_UPDATE") { - - if (dat.d.id === self.user.id) { - var newUsr = new User(dat.d); - self.triggerEvent("userupdate", [self.user, newUsr]); - self.user = newUsr; - } - - } else if (dat.t === "GUILD_MEMBER_ADD") { - - var srv = self.getServer(dat.d.guild_id); - if (srv) { - var usr = new User(dat.d.user); - srv.members.add(usr); - self.triggerEvent("serverMemberAdd", [usr]); - } - - } else if (dat.t === "GUILD_MEMBER_REMOVE") { - - var srv = self.getServer(dat.d.guild_id); - if (srv) { - var usr = new User(dat.d.user); - srv.members.removeElement(usr); - self.triggerEvent("serverMemberRemove", [usr]); - } - - } - break; - - } - - }; - this.websocket.sendPacket = function (p) { - this.send(JSON.stringify(p)); - } - this.websocket.keepAlive = function () { - - if (this.readyState !== 1) - return false; - - this.sendPacket({ - op: 1, - d: Date.now() - }); - - } - this.websocket.onopen = function () { - - self.debug("websocket conn open"); - this.sendData("onopen"); - - } - this.websocket.sendData = function (why) { - if (this.readyState == 1 && !sentInitData && self.token) { - sentInitData = true; - var connDat = { - op: 2, - d: { - token: self.token, - v: 2 - } - }; - - connDat.d.properties = Internal.WebSocket.properties; - this.sendPacket(connDat); - } - } -} - -exports.Client.prototype.debug = function (msg) { - this.triggerEvent("debug", ["[SL " + tp(globalLoginTime) + "] " + msg]); -} - -/** - * Logs the current Client out of Discord and closes any connections. - * @param {Function} callback Called after a response is obtained. - * @param {Object} callback.error Null unless there was an error, in which case is an XHR error. - * @method logout - */ -exports.Client.prototype.logout = function (callback) { - - callback = callback || function () { }; - - var self = this; - - Internal.XHR.logout(self.token, function (err) { - if (err) { - callback(err); - } - self.loggedIn = false; - self.websocket.close(); - }); - -} - -/** - * Creates a server with the specified name and region and returns it - * @param {String} name The name of the server - * @param {String} region The region of the server - * @param {Function} callback Called when the request is made. - * @param {Object} callback.error An XHR error or null if there were no errors. - * @param {Server} callback.server A Server object representing the created server. - * @method createServer - * @async - */ -exports.Client.prototype.createServer = function (name, region, cb) { - - var self = this; - - Internal.XHR.createServer(self.token, name, region, function (err, data) { - - if (err) { - cb(err); - } else { - - self.cacheServer(data, function (server) { - cb(null, server); - }); - - } - - }); - -} - -/** - * Makes the Client leave the Server - * @param {Server} server A server object. The server you want to leave. - * @param {Function} callback Called when the leave request is made. - * @param {Object} callback.error An XHR error or null if there were no errors. - * @param {Server} callback.server A Server object representing the deleted server. - * @method leaveServer - * @async - */ -exports.Client.prototype.leaveServer = function (server, callback) { - - var self = this; - - // callback is not necessary for this function - callback = callback || function () { }; - - Internal.XHR.leaveServer(self.token, server.id, function (err) { - - if (err) { - callback(err); - } else { - self.serverList.removeElement(server); - callback(null, server); - } - - }); - -} - -/** - * Creates an Invite to the specified channel/server with the specified options - * @param {Channel/Server} channel The channel/server the invite is to be made to. - * @param {Object} [options] The options for the invite - * @param {Number} [options.max_age=0] When the invite will expire in seconds - * @param {Number} [options.max_uses=0] How many uses the invite has - * @param {Boolean} [options.temporary=false] Whether the invite is temporary - * @param {Boolean} [options.xkcdpass=false] Whether the invite's code should be composed of words. - * @param {Function} callback Called when the invite request has been made - * @param {Object} callback.error An XHR Error or null if there were no errors. - * @param {Invite} callback.invite An invite object representing the created invite. - * @method createInvite - */ -exports.Client.prototype.createInvite = function (channel, options, callback) { - - var self = this; - var options = options || {}; - - // callback is not necessary for this function - callback = callback || function () { }; - - if (channel instanceof Server) { - channel = channel.getDefaultChannel(); - } - - options.max_age = options.max_age || 0; - options.max_uses = options.max_uses || 0; - options.temporary = options.temporary || false; - options.xkcdpass = options.xkcd || false; - - Internal.XHR.createInvite(self.token, channel.id, options, function (err, data) { - - if (err) { - callback(err); - } else { - callback(null, new Invite(data)); - } - - }); - -} - -exports.Client.prototype.startPM = function (user, callback) { - - var self = this; - - callback = callback || function () { }; - - Internal.XHR.startPM(self.token, self.user.id, user.id, function (err, data) { - - if (err) { - callback(err); - } else { - var channel = new PMChannel(data.recipient, data.id); - self.PMList.add(channel); - callback(null, channel); - } - - }); - -} - -/** - * Sends a message to the specified destination. - * @param {Server/Channel/PMChannel/Message/User/String} destination Where the message should be sent. If this is a String, the String should be a channel ID. - * @param {String/Array/Message} toSend The message to send. If an array, the array will be seperated into new lines and then sent. - * @param {Function} callback Called when the message has been sent. - * @param {Object} error An XHR Error or null if there were no errors. - * @param {Message} message A message object representing the sent object. - * @param {Object} [options] An object containing options for the message. - * @param {Array/Boolean/String} [options.mentions=true] If an Array, it should be an array of User IDs. If a boolean, false will - * notify no-one, and true will figure out who should be mentioned based on the message. If a String, should be a User - * ID. - * @param {Number} [options.selfDestruct=false] If specified, should be the amount of milliseconds at which the message should - * delete itself after being sent. - * @method sendMessage - */ - -exports.Client.prototype.sendFile = function (destination, toSend, fileName, callback, options) { - - this.sendMessage(destination, toSend, callback, options, fileName); - -} - -exports.Client.prototype.sendMessage = function (destination, toSend, callback, options, fileName) { - - options = options || {}; - callback = callback || function () { }; - - var channel_id, message, mentions, self = this; - - channel_id = resolveChannel(destination, self); - if (!fileName) { - message = resolveMessage(toSend); - mentions = resolveMentions(message, options.mention); - } - - if (channel_id) { - send(); - } else { - //a channel is being sorted - } - - function send() { - - if (fileName) { - Internal.XHR.sendFile(self.token, channel_id, toSend, fileName, function (err) { - - callback(err); - - }); - return; - } - - Internal.XHR.sendMessage(self.token, channel_id, { - content: message, - mentions: mentions - }, function (err, data) { - if (err) { - callback(err); - } else { - var msg = new Message(data, self.getChannel(data.channel_id)); - if (options.selfDestruct) { - setTimeout(function () { - self.deleteMessage(msg); - }, options.selfDestruct); - } - callback(null, msg); - } - }); - } - - function setChannId(id) { - channel_id = id; - } - - function resolveChannel(destination, self) { - var channel_id = false; - if (destination instanceof Server) { - channel_id = destination.getDefaultChannel().id; - } else if (destination instanceof Channel) { - channel_id = destination.id; - } else if (destination instanceof PMChannel) { - channel_id = destination.id; - } else if (destination instanceof Message) { - channel_id = destination.channel.id; - } else if (destination instanceof User) { - var destId = self.PMList.deepFilter(["user", "id"], destination.id, true); - - if (destId) { - channel_id = destId.id; - } else { - //start a PM and then get that use that - self.startPM(destination, function (err, channel) { - if (err) { - callback(err); - } else { - self.PMList.add(new PMChannel(channel.user, channel.id)); - setChannId(channel.id); - send(); - } - }); - return false; - } - } else { - channel_id = destination; - } - return channel_id; - } - - function resolveMessage(toSend) { - var message; - if (typeof toSend === "string" || toSend instanceof String) - message = toSend; - else if (toSend instanceof Array) - message = toSend.join("\n"); - else if (toSend instanceof Message) - message = toSend.content; - else - message = toSend; - return message.substring(0, 2000); - } - - function resolveMentions(message, mentionsOpt) { - var mentions = []; - if (mentionsOpt === false) { } else if (mentionsOpt || mentionsOpt === "auto" || mentionsOpt == null || mentionsOpt == undefined) { - for (mention of (message.match(/<@[^>]*>/g) || [])) { - mentions.push(mention.substring(2, mention.length - 1)); - } - } else if (mentionsOpt instanceof Array) { - for (mention of mentionsOpt) { - if (mention instanceof User) { - mentions.push(mention.id); - } else { - mentions.push(mention); - } - } - } - return mentions; - } -} - -/** - * Deletes the specified message if the bot has authority - * @param {Message} message The message to delete - * @param {Function} callback Called after the message deletion request is sent. - * @param {Object} callback.error If there was an error, this would be an XHR Error object. Otherwise, it will be null. - * @param {Message} callback.message A message object representing the deleted object. - * @method deleteMessage - */ -exports.Client.prototype.deleteMessage = function (message, callback) { - callback = callback || function () { }; - - var self = this; - - Internal.XHR.deleteMessage(self.token, message.channel.id, message.id, callback); -} - -exports.Client.prototype.updateMessage = function (oldMessage, newContent, callback, options) { - - var self = this; - var channel = oldMessage.channel; - options = options || {}; - - Internal.XHR.updateMessage(self.token, channel.id, oldMessage.id, { - content: newContent, - mentions: [] - }, function (err, data) { - if (err) { - callback(err); - return; - } - var msg = new Message(data, self.getChannel(data.channel_id)); - if (options.selfDestruct) { - setTimeout(function () { - self.deleteMessage(msg); - }, options.selfDestruct); - } - callback(null, msg); - }); - -} - -exports.Client.prototype.setUsername = function (username, callback) { - - var self = this; - - Internal.XHR.setUsername(self.token, self.user.avatar, self.email, null, self.password, username, function (err) { - - callback(err); - - }); - -} - -exports.Client.prototype.getChannelLogs = function (channel, amount, callback) { - var self = this; - - Internal.XHR.getChannelLogs(self.token, channel.id, (amount || 50), function (err, data) { - - if (err) { - callback(err); - return; - } - - var logs = new List("id"); - for (message of data) { - logs.add(new Message(message, channel)); - } - callback(null, logs); - - }); -} - -exports.Client.prototype.createChannel = function (server, name, type, callback) { - - var self = this; - - Internal.XHR.createChannel(self.token, server.id, name, type, function (err, data) { - - if (err) { - callback(err); - } else { - var chann = new Channel(data, server); - server.channels.add(chann); - callback(null, chann); - } - - }); -} - -exports.Client.prototype.deleteChannel = function (channel, callback) { - var self = this; - - Internal.XHR.deleteChannel(self.token, channel.id, function (err) { - - channel.server.channels.removeElement(channel); - self.triggerEvent("channelDelete", [channel]); - callback(null); - - }); -} - -exports.Client.prototype.deleteServer = function (server, callback) { - - var self = this; - - Internal.XHR.deleteServer(self.token, server.id, function (err) { - - self.serverList.removeElement(server); - self.triggerEvent("serverDelete", [server]); - callback(null); - - }); - -} - -exports.Client.prototype.joinServer = function (invite, callback) { - - var self = this; - - var code = (invite instanceof Invite ? invite.code : invite); - - Internal.XHR.acceptInvite(self.token, code, function (err, inviteData) { - - if (err) { - callback(err); - } else { - serverCreateRequests[inviteData.guild.id] = callback; - } - - }); - -} - -exports.Client.prototype.getServers = function () { - return this.serverList; -} - -exports.Client.prototype.getChannels = function () { - return this.serverList.concatSublists("channels", "id"); -} - -exports.Client.prototype.getUsers = function () { - return this.getServers().concatSublists("members", "id"); -} - -exports.Client.prototype.getServer = function (id) { - return this.getServers().filter("id", id, true); -} - -exports.Client.prototype.getChannel = function (id) { - var normalChan = this.getChannels().filter("id", id, true); - return normalChan || this.PMList.filter("id", id, true); -} - -exports.Client.prototype.getChannelByName = function (name) { - return this.getChannels().filter("name", name, true); -} - -exports.Client.prototype.getUser = function (id) { - return this.getUsers().filter("id", id, true); -} - -exports.isUserID = function (id) { - return ((id + "").length === 17 && !isNaN(id)); -} - -exports.Client.prototype.updateUserReferences = function (id, oldUser, user) { - - if (oldUser.equalsStrict(user)) { - return false; - } - - for (server of this.serverList.contents) { - - server.members.updateElement(oldUser, user); - - } - - this.debug("Updated references to " + oldUser.username + " to " + this.getUser(id).username); - return true; - -} - -exports.Client.prototype.addPM = function (pm) { - this.PMList.add(pm); -} diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 000000000..0438b79f6 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js new file mode 100644 index 000000000..c74b5e209 --- /dev/null +++ b/lib/Client.js @@ -0,0 +1,63 @@ +"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 request = require("superagent"); + +var defaultOptions = { + cache_tokens: false +}; + +var Client = (function () { + function Client() { + var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; + var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; + + _classCallCheck(this, Client); + + /* + When created, if a token is specified the Client will + try connecting with it. If the token is incorrect, no + further efforts will be made to connect. + */ + this.options = options; + this.token = token; + this.state = 0; + this.websocket = null; + this.events = new Map(); + this.user = null; + /* + State values: + 0 - idle + 1 - logging in + 2 - logged in + 3 - ready + 4 - disconnected + */ + } + + _createClass(Client, [{ + key: "login", + + //def login + value: function login() { + var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; + var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; + + if (this.state === 0 || this.state === 4) { + + this.state = 1; + request.post(); + } + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }]); + + return Client; +})(); \ No newline at end of file diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 1bfe3c155..31911a4d3 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -1,6 +1,8 @@ +"use strict"; + var User = require("./user.js").User; -exports.PMChannel = function(user, id){ +exports.PMChannel = function (user, id) { this.user = new User(user); this.id = id; -} +}; \ No newline at end of file diff --git a/lib/TokenManager.js b/lib/TokenManager.js index ceeed9ded..22732a462 100644 --- a/lib/TokenManager.js +++ b/lib/TokenManager.js @@ -1,68 +1,67 @@ -var fs = require( "fs" ); -var crypto = require( "crypto" ); -var md5 = require( "md5" ); +"use strict"; + +var fs = require("fs"); +var crypto = require("crypto"); +var md5 = require("md5"); var tokens = {}; -exports.TokenManager = function( folder, file ) { +exports.TokenManager = function (folder, file) { this.path = folder + file; var self = this; try { - var fd = fs.openSync( self.path, "wx" ); + var fd = fs.openSync(self.path, "wx"); self.writeTokens(); - } catch ( e ) { + } catch (e) { self.readTokens(); } +}; -} - -exports.TokenManager.prototype.addToken = function( id, token, pass ) { - tokens[ md5( id ) ] = encrypt( token, pass ); +exports.TokenManager.prototype.addToken = function (id, token, pass) { + tokens[md5(id)] = encrypt(token, pass); this.writeTokens(); -} +}; -exports.TokenManager.prototype.readTokens = function() { - tokens = JSON.parse( fs.readFileSync( this.path, "utf8" ) ); - for ( tkn in tokens ) { - tokens[ tkn ] = decrypt( tokens[ tkn ], tkn ); +exports.TokenManager.prototype.readTokens = function () { + tokens = JSON.parse(fs.readFileSync(this.path, "utf8")); + for (tkn in tokens) { + tokens[tkn] = decrypt(tokens[tkn], tkn); } -} +}; -exports.TokenManager.prototype.writeTokens = function() { +exports.TokenManager.prototype.writeTokens = function () { var tkn = {}; - for ( token in tokens ) { - tkn[ token ] = encrypt( tokens[ token ], token ); + for (token in tokens) { + tkn[token] = encrypt(tokens[token], token); } - fs.writeFile( this.path, JSON.stringify( tkn ), function( err ) { + fs.writeFile(this.path, JSON.stringify(tkn), function (err) {}); +}; - } ); -} +exports.TokenManager.prototype.exists = function (id) { + return tokens[md5(id)]; +}; -exports.TokenManager.prototype.exists = function( id ) { - return tokens[ md5( id ) ]; -} +exports.TokenManager.prototype.getToken = function (id, pass) { + try { + return decrypt(tokens[md5(id)], pass); + } catch (e) { + return false; + } +}; -exports.TokenManager.prototype.getToken = function( id, pass ) { - try{ - return decrypt( tokens[ md5( id ) ], pass ); - }catch(e){ - return false; - } -} - -function encrypt( string, password ) { - var cipher = crypto.createCipher( "aes-256-ctr", password ) - var crypted = cipher.update( string, 'utf8', 'hex' ) - crypted += cipher.final( 'hex' ); +function encrypt(string, password) { + var cipher = crypto.createCipher("aes-256-ctr", password); + var crypted = cipher.update(string, 'utf8', 'hex'); + crypted += cipher.final('hex'); return crypted; } -function decrypt( string, password ) { - var decipher = crypto.createDecipher( "aes-256-ctr", password ) - var dec = decipher.update( string, 'hex', 'utf8' ) - dec += decipher.final( 'utf8' ); +function decrypt(string, password) { + var decipher = crypto.createDecipher("aes-256-ctr", password); + var dec = decipher.update(string, 'hex', 'utf8'); + dec += decipher.final('utf8'); return dec; -} +} \ No newline at end of file diff --git a/lib/asd.js b/lib/asd.js new file mode 100644 index 000000000..c74b5e209 --- /dev/null +++ b/lib/asd.js @@ -0,0 +1,63 @@ +"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 request = require("superagent"); + +var defaultOptions = { + cache_tokens: false +}; + +var Client = (function () { + function Client() { + var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; + var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; + + _classCallCheck(this, Client); + + /* + When created, if a token is specified the Client will + try connecting with it. If the token is incorrect, no + further efforts will be made to connect. + */ + this.options = options; + this.token = token; + this.state = 0; + this.websocket = null; + this.events = new Map(); + this.user = null; + /* + State values: + 0 - idle + 1 - logging in + 2 - logged in + 3 - ready + 4 - disconnected + */ + } + + _createClass(Client, [{ + key: "login", + + //def login + value: function login() { + var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; + var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; + + if (this.state === 0 || this.state === 4) { + + this.state = 1; + request.post(); + } + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }]); + + return Client; +})(); \ No newline at end of file diff --git a/lib/channel.js b/lib/channel.js index 16a8e4a51..a6c4f5280 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -1,8 +1,11 @@ +"use strict"; + var List = require("./list.js").List; -exports.Channel = function(name, server, type, id, isPrivate){ +exports.Channel = function (name, server, type, id, isPrivate) { - if(!type){ //there's no second argument + if (!type) { + //there's no second argument var channel = name; name = channel.name; server = server; @@ -17,12 +20,12 @@ exports.Channel = function(name, server, type, id, isPrivate){ this.id = id; this.isPrivate = isPrivate; this.messages = new List("id", 5000); -} +}; -exports.Channel.equals = function(otherChannel){ - if(otherChannel.id === this.id){ +exports.Channel.equals = function (otherChannel) { + if (otherChannel.id === this.id) { return true; } else { return false; } -} +}; \ No newline at end of file diff --git a/lib/endpoints.js b/lib/endpoints.js index 46ca08090..fe87bf57f 100644 --- a/lib/endpoints.js +++ b/lib/endpoints.js @@ -1,15 +1,13 @@ -var base = "https://discordapp.com/"; -var apibase = base + "api"; +"use strict"; -exports.API = apibase; +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; -exports.WEBSOCKET_HUB = "wss://discordapp.com/hub" - -exports.USERS = apibase + "/users"; - -exports.LOGIN = apibase + "/auth/login"; -exports.LOGOUT = apibase + "/auth/logout"; - -exports.SERVERS = apibase + "/guilds"; - -exports.CHANNELS = apibase + "/channels"; +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGIN = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 000000000..4c50da911 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,23 @@ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./lib/endpoints.js"); +var Server = require("./lib/server.js").Server; +var Message = require("./lib/message.js").Message; +var User = require("./lib/user.js").User; +var Channel = require("./lib/channel.js").Channel; +var List = require("./lib/list.js").List; +var Invite = require("./lib/invite.js").Invite; +var PMChannel = require("./lib/PMChannel.js").PMChannel; +var WebSocket = require('ws'); +var Internal = require("./lib/internal.js").Internal; +var TokenManager = require("./lib/TokenManager.js").TokenManager; + +exports.Endpoints = Endpoints; +exports.Server = Server; +exports.Message = Message; +exports.User = User; +exports.Channel = Channel; +exports.List = List; +exports.Invite = Invite; +exports.PMChannel = PMChannel; \ No newline at end of file diff --git a/lib/internal.js b/lib/internal.js index 42d0dc689..3acf5940b 100644 --- a/lib/internal.js +++ b/lib/internal.js @@ -1,5 +1,7 @@ -var request = require( "superagent" ); -var Endpoints = require( "./endpoints.js" ); +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./endpoints.js"); var Internal = {}; @@ -14,264 +16,188 @@ Internal.WebSocket.properties = { "$referring_domain": "" }; -Internal.XHR.login = function( email, password, callback ) { +Internal.XHR.login = function (email, password, callback) { - request - .post( Endpoints.LOGIN ) - .send( { - email: email, - password: password - } ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body.token ); - } - } ); + request.post(Endpoints.LOGIN).send({ + email: email, + password: password + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body.token); + } + }); +}; -} +Internal.XHR.logout = function (token, callback) { -Internal.XHR.logout = function( token, callback ) { + request.post(Endpoints.LOGOUT).end(function (err, res) { - request - .post( Endpoints.LOGOUT ) - .end( function( err, res ) { + err ? callback(err) : callback(null); + }); +}; - err ? callback( err ) : callback( null ); +Internal.XHR.createServer = function (token, name, region, callback) { - } ); + request.post(Endpoints.SERVERS).set("authorization", token).send({ + name: name, + region: region + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; -} +Internal.XHR.leaveServer = function (token, serverId, callback) { -Internal.XHR.createServer = function( token, name, region, callback ) { + request.del(Endpoints.SERVERS + "/" + serverId).set("authorization", token).end(function (err, res) { - request - .post( Endpoints.SERVERS ) - .set( "authorization", token ) - .send( { - name: name, - region: region - } ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - } ); -} + err ? callback(err) : callback(null); + }); +}; -Internal.XHR.leaveServer = function( token, serverId, callback ) { +Internal.XHR.createInvite = function (token, channelId, options, callback) { + request.post(Endpoints.CHANNELS + "/" + channelId + "/invites").set("authorization", token).send(options).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; - request - .del( Endpoints.SERVERS + "/" + serverId ) - .set( "authorization", token ) - .end( function( err, res ) { +Internal.XHR.startPM = function (token, selfID, userID, callback) { - err ? callback( err ) : callback( null ); + request.post(Endpoints.USERS + "/" + selfID + "/channels").set("authorization", token).send({ + recipient_id: userID + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; - } ); +Internal.XHR.sendMessage = function (token, channelID, messageParameters, callback) { + request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).send(messageParameters).end(function (err, res) { -} + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; -Internal.XHR.createInvite = function( token, channelId, options, callback ) { - request - .post( Endpoints.CHANNELS + "/" + channelId + "/invites" ) - .set( "authorization", token ) - .send( options ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - } ) -} +Internal.XHR.sendFile = function (token, channelID, file, fileName, callback) { + request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).attach("file", file, fileName).end(function (err, res) { -Internal.XHR.startPM = function( token, selfID, userID, callback ) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; - request - .post( Endpoints.USERS + "/" + selfID + "/channels" ) - .set( "authorization", token ) - .send( { - recipient_id: userID - } ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - } ); +Internal.XHR.deleteMessage = function (token, channelID, messageID, callback) { + request.del(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; -} +Internal.XHR.updateMessage = function (token, channelID, messageID, messageParameters, callback) { -Internal.XHR.sendMessage = function( token, channelID, messageParameters, callback ) { - request - .post( Endpoints.CHANNELS + "/" + channelID + "/messages" ) - .set( "authorization", token ) - .send( messageParameters ) - .end( function( err, res ) { + request.patch(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).send(messageParameters).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } +Internal.XHR.getChannelLogs = function (token, channelID, amount, callback) { + request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", token).end(function (err, res) { - } ); + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; -} +Internal.XHR.createChannel = function (token, serverID, name, type, callback) { + request.post(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).send({ + name: name, + type: type + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; -Internal.XHR.sendFile = function( token, channelID, file, fileName, callback ) { - request - .post( Endpoints.CHANNELS + "/" + channelID + "/messages" ) - .set( "authorization", token ) - .attach("file", file, fileName) - .end( function( err, res ) { +Internal.XHR.deleteChannel = function (token, channelID, callback) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } + request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; +Internal.XHR.deleteServer = function (token, serverID, callback) { + request.del(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; - } ); -} +Internal.XHR.getChannels = function (token, serverID, callback) { + request.get(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; -Internal.XHR.deleteMessage = function( token, channelID, messageID, callback ) { - request - .del( Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID ) - .set( "authorization", token ) - .end( function( err ) { - err ? callback( err ) : callback( null ); - } ); -} +Internal.XHR.getServer = function (token, serverID, callback) { -Internal.XHR.updateMessage = function( token, channelID, messageID, messageParameters, callback ) { + request.get(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err, res) { - request - .patch( Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID ) - .set( "authorization", token ) - .send( messageParameters ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - } ); -} + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; -Internal.XHR.getChannelLogs = function( token, channelID, amount, callback ) { - request - .get( Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount ) - .set( "authorization", token ) - .end( function( err, res ) { +Internal.XHR.acceptInvite = function (token, inviteID, callback) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } + request.post(Endpoints.API + "/invite/" + inviteID).set("authorization", token).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; - } ); -} +Internal.XHR.setUsername = function (token, avatar, email, newPassword, password, username, callback) { -Internal.XHR.createChannel = function( token, serverID, name, type, callback ) { - request - .post( Endpoints.SERVERS + "/" + serverID + "/channels" ) - .set( "authorization", token ) - .send( { - name: name, - type: type - } ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - } ); -} + request.patch(Endpoints.API + "/users/@me").set("authorization", token).send({ + avatar: avatar, + email: email, + new_password: newPassword, + password: password, + username: username + }).end(function (err) { + callback(err); + }); +}; -Internal.XHR.deleteChannel = function( token, channelID, callback ) { - - request - .del( Endpoints.CHANNELS + "/" + channelID ) - .set( "authorization", token ) - .end( function( err ) { - err ? callback( err ) : callback( null ); - } ); - -} -Internal.XHR.deleteServer = function( token, serverID, callback ) { - request - .del( Endpoints.SERVERS + "/" + serverID ) - .set( "authorization", token ) - .end( function( err ) { - err ? callback( err ) : callback( null ); - } ); -} - -Internal.XHR.getChannels = function( token, serverID, callback ) { - request - .get( Endpoints.SERVERS + "/" + serverID + "/channels" ) - .set( "authorization", token ) - .end( function( err ) { - err ? callback( err ) : callback( null ); - } ); -} - -Internal.XHR.getServer = function( token, serverID, callback ) { - - request - .get( Endpoints.SERVERS + "/" + serverID ) - .set( "authorization", token ) - .end( function( err, res ) { - - if ( err ) { - callback( err ); - } else { - callback( null, res.body ); - } - - } ); - -} - -Internal.XHR.acceptInvite = function( token, inviteID, callback ) { - - request - .post( Endpoints.API + "/invite/" + inviteID ) - .set( "authorization", token ) - .end( function( err, res ) { - if ( err ) { - callback( err ); - } else { - callback( null, res.body ) - } - } ); - -} - -Internal.XHR.setUsername = function( token, avatar, email, newPassword, password, username, callback ) { - - request - .patch( Endpoints.API + "/users/@me" ) - .set( "authorization", token ) - .send( { - avatar: avatar, - email: email, - new_password: newPassword, - password: password, - username: username - } ) - .end( function( err ) { - callback( err ); - } ); - -} - -exports.Internal = Internal; +exports.Internal = Internal; \ No newline at end of file diff --git a/lib/invite.js b/lib/invite.js index f2e10077a..359ac512b 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -1,6 +1,8 @@ +"use strict"; + var User = require("./user.js").User; -exports.Invite = function(json){ +exports.Invite = function (json) { this.max_age = json.max_age; this.code = json.code; @@ -13,9 +15,9 @@ exports.Invite = function(json){ this.inviter = new User(json.inviter); this.xkcdpass = json.xkcdpass; this.channel = json.channel; -} +}; -exports.Invite.prototype.generateInviteURL = function(xkcd){ - var code = (xkcd ? this.xkcdpass : this.code); - return "https://discord.gg/"+code; -} +exports.Invite.prototype.generateInviteURL = function (xkcd) { + var code = xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; +}; \ No newline at end of file diff --git a/lib/list.js b/lib/list.js index 5ad268523..df07cad86 100644 --- a/lib/list.js +++ b/lib/list.js @@ -4,27 +4,29 @@ * when created. Generally "ID" * @class List */ -exports.List = function( discriminator, cap ) { +"use strict"; + +exports.List = function (discriminator, cap) { /** - * What to use to distringuish duplicates - * @attribute discriminator - * @type {String} - */ + * What to use to distringuish duplicates + * @attribute discriminator + * @type {String} + */ this.discriminator = discriminator; /** - * The maximum amount of elements allowed in the list. - * @default Infinity - * @attribute cap - * @type {Number} - */ + * The maximum amount of elements allowed in the list. + * @default Infinity + * @attribute cap + * @type {Number} + */ this.cap = cap || Number.MAX_SAFE_INTEGER; /** - * The Array version of the List. - * @type {Array} - * @attribute contents - */ + * The Array version of the List. + * @type {Array} + * @attribute contents + */ this.contents = []; -} +}; /** * Adds an element to the list if it isn't already there. @@ -34,40 +36,59 @@ exports.List = function( discriminator, cap ) { * List.add( obj ); * List.add( [ obj, obj, obj ] ); */ -exports.List.prototype.add = function( child ) { +exports.List.prototype.add = function (child) { var self = this; - if ( child.constructor === Array ) { + if (child.constructor === Array) { children = child; - for ( child of children ) { - addChild( child ); - } + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + try { + for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + child = _step.value; + + addChild(child); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } } else { - addChild( child ); + addChild(child); } - function addChild( child ) { + function addChild(child) { - if ( self.length() > self.cap ) { - self.splice( 0, 1 ); + if (self.length() > self.cap) { + self.splice(0, 1); } - if ( self.filter( self.discriminator, child[ self.discriminator ] ).length() === 0 ) - self.contents.push( child ); + if (self.filter(self.discriminator, child[self.discriminator]).length() === 0) self.contents.push(child); } -} +}; /** * Returns the length of the List * @method length * @return {Number} */ -exports.List.prototype.length = function() { +exports.List.prototype.length = function () { return this.contents.length; -} +}; /** * Gets the index of an element in the List or defaults to false @@ -75,30 +96,28 @@ exports.List.prototype.length = function() { * @return {Number/Boolean} The index if the object is in the list, or false. * @method getIndex */ -exports.List.prototype.getIndex = function( object ) { +exports.List.prototype.getIndex = function (object) { var index = false; - for ( elementIndex in this.contents ) { - var element = this.contents[ elementIndex ]; - if ( element[ this.discriminator ] == object[ this.discriminator ] ) { + for (elementIndex in this.contents) { + var element = this.contents[elementIndex]; + if (element[this.discriminator] == object[this.discriminator]) { return elementIndex; } - } return index; - -} +}; /** * Removes an element at the specified index * @param {Number} index * @method removeIndex */ -exports.List.prototype.removeIndex = function( index ) { - this.contents.splice( index, 1 ); -} +exports.List.prototype.removeIndex = function (index) { + this.contents.splice(index, 1); +}; /** * Removes an element from the list @@ -106,18 +125,18 @@ exports.List.prototype.removeIndex = function( index ) { * @method removeElement * @return {Boolean} whether the operation was successful or not. */ -exports.List.prototype.removeElement = function( child ) { +exports.List.prototype.removeElement = function (child) { - for ( _element in this.contents ) { - var element = this.contents[ _element ]; - if ( child[ this.discriminator ] == element[ this.discriminator ] ) { - this.removeIndex( _element, 1 ); + for (_element in this.contents) { + var element = this.contents[_element]; + if (child[this.discriminator] == element[this.discriminator]) { + this.removeIndex(_element, 1); return true; } } return false; -} +}; /** * Replaces an element in the list with a specified element @@ -126,123 +145,206 @@ exports.List.prototype.removeElement = function( child ) { * @param {Object} newElement New Element * @return {Boolean} whether the operation was successful or not. */ -exports.List.prototype.updateElement = function( child, newChild ) { +exports.List.prototype.updateElement = function (child, newChild) { - for ( _element in this.contents ) { - var element = this.contents[ _element ]; - if ( child[ this.discriminator ] == element[ this.discriminator ] ) { - this.contents[ _element ] = newChild; + for (_element in this.contents) { + var element = this.contents[_element]; + if (child[this.discriminator] == element[this.discriminator]) { + this.contents[_element] = newChild; return true; } } return false; +}; -} - -exports.List.prototype.concatSublists = function( whereList, discriminator ) { +exports.List.prototype.concatSublists = function (whereList, discriminator) { //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values. - var concatList = new exports.List( discriminator ); + var concatList = new exports.List(discriminator); - for ( item of this.contents ) { - var itemList = item[ whereList ]; - concatList.add( itemList.contents ); + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.contents[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + item = _step2.value; + + var itemList = item[whereList]; + concatList.add(itemList.contents); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } } return concatList; -} +}; -exports.List.prototype.filter = function( key, value, onlyOne, caseInsen ) { +exports.List.prototype.filter = function (key, value, onlyOne, caseInsen) { var results = []; - value = change( value ); + value = change(value); - for ( index in this.contents ) { - var child = this.contents[ index ]; - if ( change( child[ key ] ) == value ) { - if ( onlyOne ) { + for (index in this.contents) { + var child = this.contents[index]; + if (change(child[key]) == value) { + if (onlyOne) { return child; } else { - results.push( child ); + results.push(child); } } } - function change( val ) { - if ( caseInsen ) { + function change(val) { + if (caseInsen) { val = val.toUpperCase(); } return val; } - if ( onlyOne ) { + if (onlyOne) { return false; } - var retList = new exports.List( this.discriminator ); + var retList = new exports.List(this.discriminator); retList.contents = results; return retList; -} +}; -exports.List.prototype.getValues = function( key ){ +exports.List.prototype.getValues = function (key) { var valList = []; - for( child of this.contents){ - valList.push( child[key] ); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.contents[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + child = _step3.value; + + valList.push(child[key]); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } } + return valList; +}; -} - -exports.List.prototype.deepFilter = function( keys, value, onlyOne, caseInsen ) { +exports.List.prototype.deepFilter = function (keys, value, onlyOne, caseInsen) { var results = []; - value = change( value ); + value = change(value); - for ( index in this.contents ) { - var child = this.contents[ index ]; + for (index in this.contents) { + var child = this.contents[index]; var buffer = child; - for ( key of keys ) { - if(buffer instanceof exports.List){ - buffer = buffer.contents; - } - if(buffer instanceof Array){ - for(elem of buffer){ - if( change(elem[key]) == value ){ - buffer = elem; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = keys[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + key = _step4.value; + + if (buffer instanceof exports.List) { + buffer = buffer.contents; + } + if (buffer instanceof Array) { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = buffer[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + elem = _step5.value; + + if (change(elem[key]) == value) { + buffer = elem; + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } } } + buffer = buffer[key]; + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } } - buffer = buffer[ key ]; } - if ( change( buffer ) == value ) { - if ( onlyOne ) { + if (change(buffer) == value) { + if (onlyOne) { return child; } else { - results.push( child ); + results.push(child); } } } - function change( val ) { - if ( caseInsen ) { + function change(val) { + if (caseInsen) { val = val.toUpperCase(); } return val; } - if ( onlyOne ) { + if (onlyOne) { return false; } - var retList = new exports.List( this.discriminator ); + var retList = new exports.List(this.discriminator); retList.contents = results; return retList; -} +}; \ No newline at end of file diff --git a/lib/message.js b/lib/message.js index 121bbf5dd..af9ce1f4b 100644 --- a/lib/message.js +++ b/lib/message.js @@ -1,10 +1,12 @@ -var User = require( "./user.js" ).User; -var List = require( "./list.js" ).List; -var PMChannel = require( "./PMChannel.js" ).PMChannel; +"use strict"; -exports.Message = function( time, author, content, channel, id, mentions, everyoneMentioned, embeds ) { +var User = require("./user.js").User; +var List = require("./list.js").List; +var PMChannel = require("./PMChannel.js").PMChannel; - if ( !content ) { +exports.Message = function (time, author, content, channel, id, mentions, everyoneMentioned, embeds) { + + if (!content) { message = time; channel = author; time = message.timestamp; @@ -16,24 +18,24 @@ exports.Message = function( time, author, content, channel, id, mentions, everyo embeds = message.embeds; } - this.time = Date.parse( time ); - this.author = new User( author ); - this.content = content.replace( /\s+/g, ' ' ).trim(); //content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); + this.time = Date.parse(time); + this.author = new User(author); + this.content = content.replace(/\s+/g, ' ').trim(); //content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); this.channel = channel; this.id = id; - this.mentions = new List( "id" ); + this.mentions = new List("id"); this.everyoneMentioned = everyoneMentioned; this.embeds = embeds; - for ( x in mentions ) { - var _mention = mentions[ x ]; - this.mentions.add( new User( _mention ) ); + for (x in mentions) { + var _mention = mentions[x]; + this.mentions.add(new User(_mention)); } -} +}; -exports.Message.prototype.isPM = function() { - return ( this.channel instanceof PMChannel ); -} +exports.Message.prototype.isPM = function () { + return this.channel instanceof PMChannel; +}; -exports.Message.prototype.isMentioned = function( user ) { - return ( this.mentions.filter( "id", user.id ).length > 0 ); -} +exports.Message.prototype.isMentioned = function (user) { + return this.mentions.filter("id", user.id).length > 0; +}; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index a5cfaab6a..57ca54c21 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,106 +1,104 @@ -var User = require( "./user.js" ).User; -var List = require( "./list.js" ).List; +"use strict"; + +var User = require("./user.js").User; +var List = require("./list.js").List; /** * A wrapper for Server information, contains channels and users too. Developers should not instantiate the class, instead they should * manipulate Server objects given to them. * @class Server * @param {String} region The region of the server */ -exports.Server = function( region, ownerID, name, id, members, icon, afkTimeout, afkChannelId ) { +exports.Server = function (region, ownerID, name, id, members, icon, afkTimeout, afkChannelId) { /** - * The region of the Server - * @type {String} - * @attribute region - */ + * The region of the Server + * @type {String} + * @attribute region + */ this.region = region; /** - * The ID of the owner of the Server (not a User!) - * @type {String} - * @attribute ownerID - */ + * The ID of the owner of the Server (not a User!) + * @type {String} + * @attribute ownerID + */ this.ownerID = ownerID; /** - * The name of the Server - * @type {String} - * @attribute name - */ + * The name of the Server + * @type {String} + * @attribute name + */ this.name = name; /** - * The ID of the Server - * @type {String} - * @attribute id - */ + * The ID of the Server + * @type {String} + * @attribute id + */ this.id = id; /** - * List containing members of the Server - * @param {List} - * @attribute members - */ - this.members = new List( "id" ); + * List containing members of the Server + * @param {List} + * @attribute members + */ + this.members = new List("id"); /** - * List containing channelss of the Server - * @param {List} - * @attribute channels - */ - this.channels = new List( "id" ); + * List containing channelss of the Server + * @param {List} + * @attribute channels + */ + this.channels = new List("id"); /** - * ID of the Icon of the Server - * @param {String} - * @attribute icon - */ + * ID of the Icon of the Server + * @param {String} + * @attribute icon + */ this.icon = icon; /** - * The amount of seconds that should pass before the user is - * @type {Number} - * @attribute afkTimeout - */ + * The amount of seconds that should pass before the user is + * @type {Number} + * @attribute afkTimeout + */ this.afkTimeout = afkTimeout; /** - * The ID of the AFK Channel, evaluates to false if doesn't exist. - * @type {String} - * @attribute afkChannelId - */ + * The ID of the AFK Channel, evaluates to false if doesn't exist. + * @type {String} + * @attribute afkChannelId + */ this.afkChannelId = afkChannelId; - for ( x in members ) { - var member = members[ x ].user; - this.members.add( new User( member ) ); + for (x in members) { + var member = members[x].user; + this.members.add(new User(member)); } -} +}; /** * Returns a valid URL pointing towards the server's icon if it has one. * @method getIconURL * @return {String/Boolean} If there is an icon, a URL is returned. If not, false is returned. */ -exports.Server.prototype.getIconURL = function(){ - if(!this.icon) - return false; - return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg"; -} +exports.Server.prototype.getIconURL = function () { + if (!this.icon) return false; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; +}; /** * Returns the AFK Channel if a server has one * @method getAFKChannel * @return {Channel/Boolean} If there is an AFK Channel, a Channel is returned. If not, false is returned. */ -exports.Server.prototype.getAFKChannel = function(){ +exports.Server.prototype.getAFKChannel = function () { - if(!this.afkChannelId) - return false; + if (!this.afkChannelId) return false; return this.channels.filter("id", this.afkChannelId, true); - -} +}; /** * Returns the #general channel of the server. * @method getDefaultChannel * @return {Channel} Returns the #general channel of the Server. */ -exports.Server.prototype.getDefaultChannel = function() { +exports.Server.prototype.getDefaultChannel = function () { - return this.channels.filter( "name", "general", true ); - -} + return this.channels.filter("name", "general", true); +}; \ No newline at end of file diff --git a/lib/user.js b/lib/user.js index 2bf3cc51b..44bb6ce7d 100644 --- a/lib/user.js +++ b/lib/user.js @@ -1,6 +1,9 @@ -exports.User = function( username, id, discriminator, avatar ) { +"use strict"; - if ( !id ) { //there's no second argument +exports.User = function (username, id, discriminator, avatar) { + + if (!id) { + //there's no second argument var user = username; username = user.username; id = user.id; @@ -12,26 +15,23 @@ exports.User = function( username, id, discriminator, avatar ) { this.discriminator = discriminator; this.id = id; this.avatar = avatar; -} +}; -exports.User.prototype.getAvatarURL = function() { - if ( !this.avatar ) - return false; +exports.User.prototype.getAvatarURL = function () { + if (!this.avatar) return false; return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; -} +}; -exports.User.prototype.mention = function() { +exports.User.prototype.mention = function () { return "<@" + this.id + ">"; -} +}; -exports.User.prototype.equals = function( otherUser ) { +exports.User.prototype.equals = function (otherUser) { return otherUser.id === this.id; +}; -} +exports.User.prototype.equalsStrict = function (otherUser) { -exports.User.prototype.equalsStrict = function( otherUser ) { - - return ( this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar ); - -} + return this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar; +}; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js new file mode 100644 index 000000000..5aa87b72d --- /dev/null +++ b/src/Client.js @@ -0,0 +1,69 @@ +//discord.js modules +var Endpoints = require("./Endpoints.js"); + +//node modules +var request = require("superagent"); + +var defaultOptions = { + cache_tokens: false +} + +class Client { + + constructor(options = defaultOptions, token = undefined) { + /* + When created, if a token is specified the Client will + try connecting with it. If the token is incorrect, no + further efforts will be made to connect. + */ + this.options = options; + this.token = token; + this.state = 0; + this.websocket = null; + this.events = new Map(); + this.user = null; + /* + State values: + 0 - idle + 1 - logging in + 2 - logged in + 3 - ready + 4 - disconnected + */ + } + + get ready() { + return this.state === 3; + } + + //def login + login(email = "foo@bar.com", password = "pass1234s", callback = function(){}) { + + var self = this; + + if (this.state === 0 || this.state === 4) { + + this.state = 1; //set the state to logging in + + request + .post(Endpoints.LOGIN) + .send({ + email : email, + password : password + }).end(function(err, res){ + + if(err){ + self.state = 4; //set state to disconnected + callback(err); + }else{ + self.state = 2; //set state to logged in (not yet ready) + self.token = res.body.token; + } + + }); + + } + + } + +} \ No newline at end of file diff --git a/src/Endpoints.js b/src/Endpoints.js new file mode 100644 index 000000000..00d8667ae --- /dev/null +++ b/src/Endpoints.js @@ -0,0 +1,11 @@ +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = `https://${exports.BASE_DOMAIN}`; +exports.WEBSOCKET_HUB = `wss://${exports.BASE_DOMAIN}/hub`; + +exports.API = `${exports.BASE}/api`; +exports.AUTH = `${exports.API}/auth`; +exports.LOGIN = `${exports.AUTH}/login`; +exports.LOGIN = `${exports.AUTH}/logout`; +exports.USERS = `${exports.API}/users`; +exports.SERVERS = `${exports.API}/guilds`; +exports.CHANNELS = `${exports.API}/channels`; \ No newline at end of file diff --git a/src/PMChannel.js b/src/PMChannel.js new file mode 100644 index 000000000..1bfe3c155 --- /dev/null +++ b/src/PMChannel.js @@ -0,0 +1,6 @@ +var User = require("./user.js").User; + +exports.PMChannel = function(user, id){ + this.user = new User(user); + this.id = id; +} diff --git a/src/TokenManager.js b/src/TokenManager.js new file mode 100644 index 000000000..ceeed9ded --- /dev/null +++ b/src/TokenManager.js @@ -0,0 +1,68 @@ +var fs = require( "fs" ); +var crypto = require( "crypto" ); +var md5 = require( "md5" ); + +var tokens = {}; + +exports.TokenManager = function( folder, file ) { + + this.path = folder + file; + + var self = this; + + try { + var fd = fs.openSync( self.path, "wx" ); + self.writeTokens(); + } catch ( e ) { + self.readTokens(); + } + +} + +exports.TokenManager.prototype.addToken = function( id, token, pass ) { + tokens[ md5( id ) ] = encrypt( token, pass ); + this.writeTokens(); +} + +exports.TokenManager.prototype.readTokens = function() { + tokens = JSON.parse( fs.readFileSync( this.path, "utf8" ) ); + for ( tkn in tokens ) { + tokens[ tkn ] = decrypt( tokens[ tkn ], tkn ); + } +} + +exports.TokenManager.prototype.writeTokens = function() { + var tkn = {}; + for ( token in tokens ) { + tkn[ token ] = encrypt( tokens[ token ], token ); + } + fs.writeFile( this.path, JSON.stringify( tkn ), function( err ) { + + } ); +} + +exports.TokenManager.prototype.exists = function( id ) { + return tokens[ md5( id ) ]; +} + +exports.TokenManager.prototype.getToken = function( id, pass ) { + try{ + return decrypt( tokens[ md5( id ) ], pass ); + }catch(e){ + return false; + } +} + +function encrypt( string, password ) { + var cipher = crypto.createCipher( "aes-256-ctr", password ) + var crypted = cipher.update( string, 'utf8', 'hex' ) + crypted += cipher.final( 'hex' ); + return crypted; +} + +function decrypt( string, password ) { + var decipher = crypto.createDecipher( "aes-256-ctr", password ) + var dec = decipher.update( string, 'hex', 'utf8' ) + dec += decipher.final( 'utf8' ); + return dec; +} diff --git a/src/channel.js b/src/channel.js new file mode 100644 index 000000000..16a8e4a51 --- /dev/null +++ b/src/channel.js @@ -0,0 +1,28 @@ +var List = require("./list.js").List; + +exports.Channel = function(name, server, type, id, isPrivate){ + + if(!type){ //there's no second argument + var channel = name; + name = channel.name; + server = server; + type = channel.type; + id = channel.id; + isPrivate = channel.is_private; + } + + this.name = name; + this.server = server; + this.type = type; + this.id = id; + this.isPrivate = isPrivate; + this.messages = new List("id", 5000); +} + +exports.Channel.equals = function(otherChannel){ + if(otherChannel.id === this.id){ + return true; + } else { + return false; + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 000000000..ba14989f3 --- /dev/null +++ b/src/index.js @@ -0,0 +1,21 @@ +var request = require("superagent"); +var Endpoints = require("./lib/endpoints.js"); +var Server = require("./lib/server.js").Server; +var Message = require("./lib/message.js").Message; +var User = require("./lib/user.js").User; +var Channel = require("./lib/channel.js").Channel; +var List = require("./lib/list.js").List; +var Invite = require("./lib/invite.js").Invite; +var PMChannel = require("./lib/PMChannel.js").PMChannel; +var WebSocket = require('ws'); +var Internal = require("./lib/internal.js").Internal; +var TokenManager = require("./lib/TokenManager.js").TokenManager; + +exports.Endpoints = Endpoints; +exports.Server = Server; +exports.Message = Message; +exports.User = User; +exports.Channel = Channel; +exports.List = List; +exports.Invite = Invite; +exports.PMChannel = PMChannel; \ No newline at end of file diff --git a/src/internal.js b/src/internal.js new file mode 100644 index 000000000..42d0dc689 --- /dev/null +++ b/src/internal.js @@ -0,0 +1,277 @@ +var request = require( "superagent" ); +var Endpoints = require( "./endpoints.js" ); + +var Internal = {}; + +Internal.XHR = {}; +Internal.WebSocket = {}; + +Internal.WebSocket.properties = { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" +}; + +Internal.XHR.login = function( email, password, callback ) { + + request + .post( Endpoints.LOGIN ) + .send( { + email: email, + password: password + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body.token ); + } + } ); + +} + +Internal.XHR.logout = function( token, callback ) { + + request + .post( Endpoints.LOGOUT ) + .end( function( err, res ) { + + err ? callback( err ) : callback( null ); + + } ); + +} + +Internal.XHR.createServer = function( token, name, region, callback ) { + + request + .post( Endpoints.SERVERS ) + .set( "authorization", token ) + .send( { + name: name, + region: region + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); +} + +Internal.XHR.leaveServer = function( token, serverId, callback ) { + + request + .del( Endpoints.SERVERS + "/" + serverId ) + .set( "authorization", token ) + .end( function( err, res ) { + + err ? callback( err ) : callback( null ); + + } ); + +} + +Internal.XHR.createInvite = function( token, channelId, options, callback ) { + request + .post( Endpoints.CHANNELS + "/" + channelId + "/invites" ) + .set( "authorization", token ) + .send( options ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ) +} + +Internal.XHR.startPM = function( token, selfID, userID, callback ) { + + request + .post( Endpoints.USERS + "/" + selfID + "/channels" ) + .set( "authorization", token ) + .send( { + recipient_id: userID + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); + +} + +Internal.XHR.sendMessage = function( token, channelID, messageParameters, callback ) { + request + .post( Endpoints.CHANNELS + "/" + channelID + "/messages" ) + .set( "authorization", token ) + .send( messageParameters ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); + +} + +Internal.XHR.sendFile = function( token, channelID, file, fileName, callback ) { + request + .post( Endpoints.CHANNELS + "/" + channelID + "/messages" ) + .set( "authorization", token ) + .attach("file", file, fileName) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); +} + +Internal.XHR.deleteMessage = function( token, channelID, messageID, callback ) { + request + .del( Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.updateMessage = function( token, channelID, messageID, messageParameters, callback ) { + + request + .patch( Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID ) + .set( "authorization", token ) + .send( messageParameters ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); +} + +Internal.XHR.getChannelLogs = function( token, channelID, amount, callback ) { + request + .get( Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount ) + .set( "authorization", token ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); +} + +Internal.XHR.createChannel = function( token, serverID, name, type, callback ) { + request + .post( Endpoints.SERVERS + "/" + serverID + "/channels" ) + .set( "authorization", token ) + .send( { + name: name, + type: type + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); +} + +Internal.XHR.deleteChannel = function( token, channelID, callback ) { + + request + .del( Endpoints.CHANNELS + "/" + channelID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); + +} +Internal.XHR.deleteServer = function( token, serverID, callback ) { + request + .del( Endpoints.SERVERS + "/" + serverID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.getChannels = function( token, serverID, callback ) { + request + .get( Endpoints.SERVERS + "/" + serverID + "/channels" ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.getServer = function( token, serverID, callback ) { + + request + .get( Endpoints.SERVERS + "/" + serverID ) + .set( "authorization", token ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); + +} + +Internal.XHR.acceptInvite = function( token, inviteID, callback ) { + + request + .post( Endpoints.API + "/invite/" + inviteID ) + .set( "authorization", token ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ) + } + } ); + +} + +Internal.XHR.setUsername = function( token, avatar, email, newPassword, password, username, callback ) { + + request + .patch( Endpoints.API + "/users/@me" ) + .set( "authorization", token ) + .send( { + avatar: avatar, + email: email, + new_password: newPassword, + password: password, + username: username + } ) + .end( function( err ) { + callback( err ); + } ); + +} + +exports.Internal = Internal; diff --git a/src/invite.js b/src/invite.js new file mode 100644 index 000000000..f2e10077a --- /dev/null +++ b/src/invite.js @@ -0,0 +1,21 @@ +var User = require("./user.js").User; + +exports.Invite = function(json){ + + this.max_age = json.max_age; + this.code = json.code; + this.server = json.guild; + this.revoked = json.revoked; + this.created_at = Date.parse(json.created_at); + this.temporary = json.temporary; + this.uses = json.uses; + this.max_uses = json.uses; + this.inviter = new User(json.inviter); + this.xkcdpass = json.xkcdpass; + this.channel = json.channel; +} + +exports.Invite.prototype.generateInviteURL = function(xkcd){ + var code = (xkcd ? this.xkcdpass : this.code); + return "https://discord.gg/"+code; +} diff --git a/src/list.js b/src/list.js new file mode 100644 index 000000000..5ad268523 --- /dev/null +++ b/src/list.js @@ -0,0 +1,248 @@ +/** + * Similar to a Java set. Contains no duplicate elements and includes filter + * functions. Discriminates between elements based on a discriminator passed + * when created. Generally "ID" + * @class List + */ +exports.List = function( discriminator, cap ) { + /** + * What to use to distringuish duplicates + * @attribute discriminator + * @type {String} + */ + this.discriminator = discriminator; + /** + * The maximum amount of elements allowed in the list. + * @default Infinity + * @attribute cap + * @type {Number} + */ + this.cap = cap || Number.MAX_SAFE_INTEGER; + /** + * The Array version of the List. + * @type {Array} + * @attribute contents + */ + this.contents = []; +} + +/** + * Adds an element to the list if it isn't already there. + * @method add + * @param {Object/Array} element The element(s) to add + * @example + * List.add( obj ); + * List.add( [ obj, obj, obj ] ); + */ +exports.List.prototype.add = function( child ) { + + var self = this; + + if ( child.constructor === Array ) { + + children = child; + for ( child of children ) { + addChild( child ); + } + + } else { + addChild( child ); + } + + function addChild( child ) { + + if ( self.length() > self.cap ) { + self.splice( 0, 1 ); + } + + if ( self.filter( self.discriminator, child[ self.discriminator ] ).length() === 0 ) + self.contents.push( child ); + } +} + +/** + * Returns the length of the List + * @method length + * @return {Number} + */ +exports.List.prototype.length = function() { + return this.contents.length; +} + +/** + * Gets the index of an element in the List or defaults to false + * @param {Object} object The element we want to get the index of + * @return {Number/Boolean} The index if the object is in the list, or false. + * @method getIndex + */ +exports.List.prototype.getIndex = function( object ) { + + var index = false; + + for ( elementIndex in this.contents ) { + var element = this.contents[ elementIndex ]; + if ( element[ this.discriminator ] == object[ this.discriminator ] ) { + return elementIndex; + } + + } + + return index; + +} + +/** + * Removes an element at the specified index + * @param {Number} index + * @method removeIndex + */ +exports.List.prototype.removeIndex = function( index ) { + this.contents.splice( index, 1 ); +} + +/** + * Removes an element from the list + * @param {Object} element + * @method removeElement + * @return {Boolean} whether the operation was successful or not. + */ +exports.List.prototype.removeElement = function( child ) { + + for ( _element in this.contents ) { + var element = this.contents[ _element ]; + if ( child[ this.discriminator ] == element[ this.discriminator ] ) { + this.removeIndex( _element, 1 ); + return true; + } + } + + return false; +} + +/** + * Replaces an element in the list with a specified element + * @method updateElement + * @param {Object} element Element to update. + * @param {Object} newElement New Element + * @return {Boolean} whether the operation was successful or not. + */ +exports.List.prototype.updateElement = function( child, newChild ) { + + for ( _element in this.contents ) { + var element = this.contents[ _element ]; + if ( child[ this.discriminator ] == element[ this.discriminator ] ) { + this.contents[ _element ] = newChild; + return true; + } + } + + return false; + +} + +exports.List.prototype.concatSublists = function( whereList, discriminator ) { + //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values. + + var concatList = new exports.List( discriminator ); + + for ( item of this.contents ) { + var itemList = item[ whereList ]; + concatList.add( itemList.contents ); + } + + return concatList; +} + +exports.List.prototype.filter = function( key, value, onlyOne, caseInsen ) { + + var results = []; + + value = change( value ); + + for ( index in this.contents ) { + var child = this.contents[ index ]; + if ( change( child[ key ] ) == value ) { + if ( onlyOne ) { + return child; + } else { + results.push( child ); + } + } + } + + function change( val ) { + if ( caseInsen ) { + val = val.toUpperCase(); + } + return val; + } + + if ( onlyOne ) { + return false; + } + + var retList = new exports.List( this.discriminator ); + retList.contents = results; + + return retList; +} + +exports.List.prototype.getValues = function( key ){ + + var valList = []; + for( child of this.contents){ + valList.push( child[key] ); + } + return valList; + +} + +exports.List.prototype.deepFilter = function( keys, value, onlyOne, caseInsen ) { + + var results = []; + + value = change( value ); + + for ( index in this.contents ) { + var child = this.contents[ index ]; + var buffer = child; + + for ( key of keys ) { + if(buffer instanceof exports.List){ + buffer = buffer.contents; + } + if(buffer instanceof Array){ + for(elem of buffer){ + if( change(elem[key]) == value ){ + buffer = elem; + } + } + } + buffer = buffer[ key ]; + } + + if ( change( buffer ) == value ) { + if ( onlyOne ) { + return child; + } else { + results.push( child ); + } + } + } + + function change( val ) { + if ( caseInsen ) { + val = val.toUpperCase(); + } + return val; + } + + if ( onlyOne ) { + return false; + } + + var retList = new exports.List( this.discriminator ); + retList.contents = results; + + return retList; +} diff --git a/src/message.js b/src/message.js new file mode 100644 index 000000000..121bbf5dd --- /dev/null +++ b/src/message.js @@ -0,0 +1,39 @@ +var User = require( "./user.js" ).User; +var List = require( "./list.js" ).List; +var PMChannel = require( "./PMChannel.js" ).PMChannel; + +exports.Message = function( time, author, content, channel, id, mentions, everyoneMentioned, embeds ) { + + if ( !content ) { + message = time; + channel = author; + time = message.timestamp; + author = message.author; + content = message.content; + id = message.id; + mentions = message.mentions; + everyoneMentioned = message.mention_everyone; + embeds = message.embeds; + } + + this.time = Date.parse( time ); + this.author = new User( author ); + this.content = content.replace( /\s+/g, ' ' ).trim(); //content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); + this.channel = channel; + this.id = id; + this.mentions = new List( "id" ); + this.everyoneMentioned = everyoneMentioned; + this.embeds = embeds; + for ( x in mentions ) { + var _mention = mentions[ x ]; + this.mentions.add( new User( _mention ) ); + } +} + +exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); +} + +exports.Message.prototype.isMentioned = function( user ) { + return ( this.mentions.filter( "id", user.id ).length > 0 ); +} diff --git a/src/server.js b/src/server.js new file mode 100644 index 000000000..a5cfaab6a --- /dev/null +++ b/src/server.js @@ -0,0 +1,106 @@ +var User = require( "./user.js" ).User; +var List = require( "./list.js" ).List; +/** + * A wrapper for Server information, contains channels and users too. Developers should not instantiate the class, instead they should + * manipulate Server objects given to them. + * @class Server + * @param {String} region The region of the server + */ +exports.Server = function( region, ownerID, name, id, members, icon, afkTimeout, afkChannelId ) { + + /** + * The region of the Server + * @type {String} + * @attribute region + */ + this.region = region; + /** + * The ID of the owner of the Server (not a User!) + * @type {String} + * @attribute ownerID + */ + this.ownerID = ownerID; + /** + * The name of the Server + * @type {String} + * @attribute name + */ + this.name = name; + /** + * The ID of the Server + * @type {String} + * @attribute id + */ + this.id = id; + /** + * List containing members of the Server + * @param {List} + * @attribute members + */ + this.members = new List( "id" ); + /** + * List containing channelss of the Server + * @param {List} + * @attribute channels + */ + this.channels = new List( "id" ); + /** + * ID of the Icon of the Server + * @param {String} + * @attribute icon + */ + this.icon = icon; + /** + * The amount of seconds that should pass before the user is + * @type {Number} + * @attribute afkTimeout + */ + this.afkTimeout = afkTimeout; + /** + * The ID of the AFK Channel, evaluates to false if doesn't exist. + * @type {String} + * @attribute afkChannelId + */ + this.afkChannelId = afkChannelId; + + for ( x in members ) { + var member = members[ x ].user; + this.members.add( new User( member ) ); + } +} + +/** + * Returns a valid URL pointing towards the server's icon if it has one. + * @method getIconURL + * @return {String/Boolean} If there is an icon, a URL is returned. If not, false is returned. + */ +exports.Server.prototype.getIconURL = function(){ + if(!this.icon) + return false; + return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg"; +} + +/** + * Returns the AFK Channel if a server has one + * @method getAFKChannel + * @return {Channel/Boolean} If there is an AFK Channel, a Channel is returned. If not, false is returned. + */ +exports.Server.prototype.getAFKChannel = function(){ + + if(!this.afkChannelId) + return false; + + return this.channels.filter("id", this.afkChannelId, true); + +} + +/** + * Returns the #general channel of the server. + * @method getDefaultChannel + * @return {Channel} Returns the #general channel of the Server. + */ +exports.Server.prototype.getDefaultChannel = function() { + + return this.channels.filter( "name", "general", true ); + +} diff --git a/src/user.js b/src/user.js new file mode 100644 index 000000000..2bf3cc51b --- /dev/null +++ b/src/user.js @@ -0,0 +1,37 @@ +exports.User = function( username, id, discriminator, avatar ) { + + if ( !id ) { //there's no second argument + var user = username; + username = user.username; + id = user.id; + discriminator = user.discriminator; + avatar = user.avatar; + } + + this.username = username; + this.discriminator = discriminator; + this.id = id; + this.avatar = avatar; +} + +exports.User.prototype.getAvatarURL = function() { + if ( !this.avatar ) + return false; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; +} + +exports.User.prototype.mention = function() { + return "<@" + this.id + ">"; +} + +exports.User.prototype.equals = function( otherUser ) { + + return otherUser.id === this.id; + +} + +exports.User.prototype.equalsStrict = function( otherUser ) { + + return ( this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar ); + +} From a9bd6cd59c46f9faa71ece8aceaa11b602dc8ef1 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 17:14:19 +0100 Subject: [PATCH 006/191] added basic methods --- src/Client.js | 67 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/Client.js b/src/Client.js index 5aa87b72d..bc783c45b 100644 --- a/src/Client.js +++ b/src/Client.js @@ -3,6 +3,7 @@ var Endpoints = require("./Endpoints.js"); //node modules var request = require("superagent"); +var WebSocket = require("ws"); var defaultOptions = { cache_tokens: false @@ -22,6 +23,7 @@ class Client { this.websocket = null; this.events = new Map(); this.user = null; + this.alreadySentData = false; /* State values: 0 - idle @@ -35,35 +37,80 @@ class Client { get ready() { return this.state === 3; } + + debug(message) { + + } //def login - login(email = "foo@bar.com", password = "pass1234s", callback = function(){}) { + login(email = "foo@bar.com", password = "pass1234s", callback = function () { }) { var self = this; if (this.state === 0 || this.state === 4) { - + this.state = 1; //set the state to logging in request .post(Endpoints.LOGIN) .send({ - email : email, - password : password - }).end(function(err, res){ - - if(err){ + email: email, + password: password + }).end(function (err, res) { + + if (err) { self.state = 4; //set state to disconnected callback(err); - }else{ + } else { self.state = 2; //set state to logged in (not yet ready) - self.token = res.body.token; + self.token = res.body.token; //set our token + self.trySendConnData(); + callback(null, self.token); } - + }); } } + + //def createws + createws() { + if (this.websocket) + return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + } + + //def trySendConnData + trySendConnData() { + + if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } } \ No newline at end of file From 344f8d73a4dd20a578c8ef0ba92c329f0eb36397 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 19:33:52 +0100 Subject: [PATCH 007/191] Added User Class --- lib/Client.js | 145 +++++++++++++++++++++++++++++++++++++++++++++-- lib/endpoints.js | 2 +- lib/index.js | 21 +------ lib/server.js | 85 +++------------------------ lib/user.js | 72 +++++++++++++---------- src/Client.js | 72 ++++++++++++++++++++++- src/Endpoints.js | 2 +- src/index.js | 21 +------ src/server.js | 89 ++++------------------------- src/user.js | 66 +++++++++++---------- test/bot.js | 7 +++ 11 files changed, 320 insertions(+), 262 deletions(-) create mode 100644 test/bot.js diff --git a/lib/Client.js b/lib/Client.js index c74b5e209..58b6e636b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1,10 +1,16 @@ +//discord.js modules "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 Endpoints = require("./Endpoints.js"); +var User = require("./User.js"); + +//node modules var request = require("superagent"); +var WebSocket = require("ws"); var defaultOptions = { cache_tokens: false @@ -28,6 +34,7 @@ var Client = (function () { this.websocket = null; this.events = new Map(); this.user = null; + this.alreadySentData = false; /* State values: 0 - idle @@ -36,20 +43,148 @@ var Client = (function () { 3 - ready 4 - disconnected */ + + this.userCache = new Map(); + this.channelCache = new Map(); + this.serverCache = new Map(); } _createClass(Client, [{ - key: "login", + key: "debug", + + //def debug + value: function debug(message) { + console.log(message); + } + + //def trigger + }, { + key: "trigger", + value: function trigger(event) {} //def login + }, { + key: "login", value: function login() { var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; + var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2]; + + var self = this; + + this.createws(); if (this.state === 0 || this.state === 4) { - this.state = 1; - request.post(); + this.state = 1; //set the state to logging in + + request.post(Endpoints.LOGIN).send({ + email: email, + password: password + }).end(function (err, res) { + + if (err) { + self.state = 4; //set state to disconnected + self.trigger("disconnected"); + self.websocket.close(); + callback(err); + } else { + self.state = 2; //set state to logged in (not yet ready) + self.token = res.body.token; //set our token + self.trySendConnData(); + callback(null, self.token); + } + }); + } + } + + //def createws + }, { + key: "createws", + value: function createws() { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = false; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + break; + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.userCache.has(data.id)) { + this.userCache.set(data.id, new User(data)); + } + return this.userCache.get(data.id); + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); } } }, { @@ -60,4 +195,6 @@ var Client = (function () { }]); return Client; -})(); \ No newline at end of file +})(); + +module.exports = Client; \ No newline at end of file diff --git a/lib/endpoints.js b/lib/endpoints.js index fe87bf57f..271b465eb 100644 --- a/lib/endpoints.js +++ b/lib/endpoints.js @@ -7,7 +7,7 @@ exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; exports.API = exports.BASE + "/api"; exports.AUTH = exports.API + "/auth"; exports.LOGIN = exports.AUTH + "/login"; -exports.LOGIN = exports.AUTH + "/logout"; +exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 4c50da911..fa2343ae4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,23 +1,8 @@ "use strict"; var request = require("superagent"); -var Endpoints = require("./lib/endpoints.js"); -var Server = require("./lib/server.js").Server; -var Message = require("./lib/message.js").Message; -var User = require("./lib/user.js").User; -var Channel = require("./lib/channel.js").Channel; -var List = require("./lib/list.js").List; -var Invite = require("./lib/invite.js").Invite; -var PMChannel = require("./lib/PMChannel.js").PMChannel; -var WebSocket = require('ws'); -var Internal = require("./lib/internal.js").Internal; -var TokenManager = require("./lib/TokenManager.js").TokenManager; +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); exports.Endpoints = Endpoints; -exports.Server = Server; -exports.Message = Message; -exports.User = User; -exports.Channel = Channel; -exports.List = List; -exports.Invite = Invite; -exports.PMChannel = PMChannel; \ No newline at end of file +exports.Client = Client; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index 57ca54c21..77adad245 100644 --- a/lib/server.js +++ b/lib/server.js @@ -2,90 +2,28 @@ var User = require("./user.js").User; var List = require("./list.js").List; -/** - * A wrapper for Server information, contains channels and users too. Developers should not instantiate the class, instead they should - * manipulate Server objects given to them. - * @class Server - * @param {String} region The region of the server - */ -exports.Server = function (region, ownerID, name, id, members, icon, afkTimeout, afkChannelId) { - - /** - * The region of the Server - * @type {String} - * @attribute region - */ - this.region = region; - /** - * The ID of the owner of the Server (not a User!) - * @type {String} - * @attribute ownerID - */ - this.ownerID = ownerID; - /** - * The name of the Server - * @type {String} - * @attribute name - */ - this.name = name; - /** - * The ID of the Server - * @type {String} - * @attribute id - */ - this.id = id; - /** - * List containing members of the Server - * @param {List} - * @attribute members - */ - this.members = new List("id"); - /** - * List containing channelss of the Server - * @param {List} - * @attribute channels - */ - this.channels = new List("id"); - /** - * ID of the Icon of the Server - * @param {String} - * @attribute icon - */ - this.icon = icon; - /** - * The amount of seconds that should pass before the user is - * @type {Number} - * @attribute afkTimeout - */ +exports.Server = function (data) { + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Map(); + this.channels = new Map(); + this.icon = data.icon; this.afkTimeout = afkTimeout; - /** - * The ID of the AFK Channel, evaluates to false if doesn't exist. - * @type {String} - * @attribute afkChannelId - */ this.afkChannelId = afkChannelId; - for (x in members) { + for (var x in members) { var member = members[x].user; this.members.add(new User(member)); } }; -/** - * Returns a valid URL pointing towards the server's icon if it has one. - * @method getIconURL - * @return {String/Boolean} If there is an icon, a URL is returned. If not, false is returned. - */ exports.Server.prototype.getIconURL = function () { if (!this.icon) return false; return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; }; -/** - * Returns the AFK Channel if a server has one - * @method getAFKChannel - * @return {Channel/Boolean} If there is an AFK Channel, a Channel is returned. If not, false is returned. - */ exports.Server.prototype.getAFKChannel = function () { if (!this.afkChannelId) return false; @@ -93,11 +31,6 @@ exports.Server.prototype.getAFKChannel = function () { return this.channels.filter("id", this.afkChannelId, true); }; -/** - * Returns the #general channel of the server. - * @method getDefaultChannel - * @return {Channel} Returns the #general channel of the Server. - */ exports.Server.prototype.getDefaultChannel = function () { return this.channels.filter("name", "general", true); diff --git a/lib/user.js b/lib/user.js index 44bb6ce7d..e4b6e682c 100644 --- a/lib/user.js +++ b/lib/user.js @@ -1,37 +1,51 @@ "use strict"; -exports.User = function (username, id, discriminator, avatar) { +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; }; })(); - if (!id) { - //there's no second argument - var user = username; - username = user.username; - id = user.id; - discriminator = user.discriminator; - avatar = user.avatar; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; } - this.username = username; - this.discriminator = discriminator; - this.id = id; - this.avatar = avatar; -}; + // access using user.avatarURL; -exports.User.prototype.getAvatarURL = function () { - if (!this.avatar) return false; - return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; -}; + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); -exports.User.prototype.mention = function () { - return "<@" + this.id + ">"; -}; + return User; +})(); -exports.User.prototype.equals = function (otherUser) { - - return otherUser.id === this.id; -}; - -exports.User.prototype.equalsStrict = function (otherUser) { - - return this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar; -}; \ No newline at end of file +module.exports = User; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index bc783c45b..9b2355969 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1,5 +1,6 @@ //discord.js modules var Endpoints = require("./Endpoints.js"); +var User = require("./User.js"); //node modules var request = require("superagent"); @@ -32,13 +33,24 @@ class Client { 3 - ready 4 - disconnected */ + + this.userCache = new Map(); + this.channelCache = new Map(); + this.serverCache = new Map(); } get ready() { return this.state === 3; } + + //def debug debug(message) { + console.log(message); + } + + //def trigger + trigger(event) { } @@ -47,6 +59,8 @@ class Client { var self = this; + this.createws(); + if (this.state === 0 || this.state === 4) { this.state = 1; //set the state to logging in @@ -60,6 +74,8 @@ class Client { if (err) { self.state = 4; //set state to disconnected + self.trigger("disconnected"); + self.websocket.close(); callback(err); } else { self.state = 2; //set state to logged in (not yet ready) @@ -83,18 +99,66 @@ class Client { //good to go this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + + //open this.websocket.onopen = function () { self.trySendConnData(); //try connecting }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + } + + //message + this.websocket.onmessage = function (e) { + + var dat = false, data = false; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser( data.user ); + + + break; + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + + } + + } + + //def addUser + addUser(data) { + if (!this.userCache.has(data.id)){ + this.userCache.set(data.id, new User(data)); + } + return this.userCache.get(data.id); } //def trySendConnData trySendConnData() { if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { - + this.alreadySentData = true; - + var data = { op: 2, d: { @@ -113,4 +177,6 @@ class Client { } } -} \ No newline at end of file +} + +module.exports = Client; \ No newline at end of file diff --git a/src/Endpoints.js b/src/Endpoints.js index 00d8667ae..450bf0426 100644 --- a/src/Endpoints.js +++ b/src/Endpoints.js @@ -5,7 +5,7 @@ exports.WEBSOCKET_HUB = `wss://${exports.BASE_DOMAIN}/hub`; exports.API = `${exports.BASE}/api`; exports.AUTH = `${exports.API}/auth`; exports.LOGIN = `${exports.AUTH}/login`; -exports.LOGIN = `${exports.AUTH}/logout`; +exports.LOGOUT = `${exports.AUTH}/logout`; exports.USERS = `${exports.API}/users`; exports.SERVERS = `${exports.API}/guilds`; exports.CHANNELS = `${exports.API}/channels`; \ No newline at end of file diff --git a/src/index.js b/src/index.js index ba14989f3..f64a62a7f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,21 +1,6 @@ var request = require("superagent"); -var Endpoints = require("./lib/endpoints.js"); -var Server = require("./lib/server.js").Server; -var Message = require("./lib/message.js").Message; -var User = require("./lib/user.js").User; -var Channel = require("./lib/channel.js").Channel; -var List = require("./lib/list.js").List; -var Invite = require("./lib/invite.js").Invite; -var PMChannel = require("./lib/PMChannel.js").PMChannel; -var WebSocket = require('ws'); -var Internal = require("./lib/internal.js").Internal; -var TokenManager = require("./lib/TokenManager.js").TokenManager; +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); exports.Endpoints = Endpoints; -exports.Server = Server; -exports.Message = Message; -exports.User = User; -exports.Channel = Channel; -exports.List = List; -exports.Invite = Invite; -exports.PMChannel = PMChannel; \ No newline at end of file +exports.Client = Client; \ No newline at end of file diff --git a/src/server.js b/src/server.js index a5cfaab6a..a64a7114d 100644 --- a/src/server.js +++ b/src/server.js @@ -1,90 +1,28 @@ var User = require( "./user.js" ).User; var List = require( "./list.js" ).List; -/** - * A wrapper for Server information, contains channels and users too. Developers should not instantiate the class, instead they should - * manipulate Server objects given to them. - * @class Server - * @param {String} region The region of the server - */ -exports.Server = function( region, ownerID, name, id, members, icon, afkTimeout, afkChannelId ) { +exports.Server = function( data ) { + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Map(); + this.channels = new Map(); + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; - /** - * The region of the Server - * @type {String} - * @attribute region - */ - this.region = region; - /** - * The ID of the owner of the Server (not a User!) - * @type {String} - * @attribute ownerID - */ - this.ownerID = ownerID; - /** - * The name of the Server - * @type {String} - * @attribute name - */ - this.name = name; - /** - * The ID of the Server - * @type {String} - * @attribute id - */ - this.id = id; - /** - * List containing members of the Server - * @param {List} - * @attribute members - */ - this.members = new List( "id" ); - /** - * List containing channelss of the Server - * @param {List} - * @attribute channels - */ - this.channels = new List( "id" ); - /** - * ID of the Icon of the Server - * @param {String} - * @attribute icon - */ - this.icon = icon; - /** - * The amount of seconds that should pass before the user is - * @type {Number} - * @attribute afkTimeout - */ - this.afkTimeout = afkTimeout; - /** - * The ID of the AFK Channel, evaluates to false if doesn't exist. - * @type {String} - * @attribute afkChannelId - */ - this.afkChannelId = afkChannelId; - - for ( x in members ) { + for ( var x in members ) { var member = members[ x ].user; this.members.add( new User( member ) ); } } -/** - * Returns a valid URL pointing towards the server's icon if it has one. - * @method getIconURL - * @return {String/Boolean} If there is an icon, a URL is returned. If not, false is returned. - */ exports.Server.prototype.getIconURL = function(){ if(!this.icon) return false; return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg"; } -/** - * Returns the AFK Channel if a server has one - * @method getAFKChannel - * @return {Channel/Boolean} If there is an AFK Channel, a Channel is returned. If not, false is returned. - */ exports.Server.prototype.getAFKChannel = function(){ if(!this.afkChannelId) @@ -94,11 +32,6 @@ exports.Server.prototype.getAFKChannel = function(){ } -/** - * Returns the #general channel of the server. - * @method getDefaultChannel - * @return {Channel} Returns the #general channel of the Server. - */ exports.Server.prototype.getDefaultChannel = function() { return this.channels.filter( "name", "general", true ); diff --git a/src/user.js b/src/user.js index 2bf3cc51b..b69896534 100644 --- a/src/user.js +++ b/src/user.js @@ -1,37 +1,35 @@ -exports.User = function( username, id, discriminator, avatar ) { - - if ( !id ) { //there's no second argument - var user = username; - username = user.username; - id = user.id; - discriminator = user.discriminator; - avatar = user.avatar; +class User{ + constructor( data ){ + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + } + + // access using user.avatarURL; + get avatarURL(){ + if( !this.avatar ) + return null; + return `https://discordapp.com/api/users/${this.id}/avatars/${this.avatar}.jpg`; + } + + mention(){ + return `<@${this.id}>`; + } + + toString(){ + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + + equals(object){ + return object.id === this.id; } - - this.username = username; - this.discriminator = discriminator; - this.id = id; - this.avatar = avatar; } -exports.User.prototype.getAvatarURL = function() { - if ( !this.avatar ) - return false; - return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; -} - -exports.User.prototype.mention = function() { - return "<@" + this.id + ">"; -} - -exports.User.prototype.equals = function( otherUser ) { - - return otherUser.id === this.id; - -} - -exports.User.prototype.equalsStrict = function( otherUser ) { - - return ( this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar ); - -} +module.exports = User; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js new file mode 100644 index 000000000..e392c7ba2 --- /dev/null +++ b/test/bot.js @@ -0,0 +1,7 @@ +var Discord = require("../lib/index.js"); + +var mybot = new Discord.Client(); + +mybot.login("riftes@outlook.com", "hydrabotsecure", function(err, res){ + console.log(res); +}); \ No newline at end of file From df1519a1810866f12e0b259c4e44b30a201780aa Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 19:55:54 +0100 Subject: [PATCH 008/191] added server caching --- src/server.js | 100 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 35 deletions(-) diff --git a/src/server.js b/src/server.js index a64a7114d..63cdf2ae9 100644 --- a/src/server.js +++ b/src/server.js @@ -1,39 +1,69 @@ -var User = require( "./user.js" ).User; -var List = require( "./list.js" ).List; -exports.Server = function( data ) { - this.region = data.region; - this.ownerID = data.owner_id; - this.name = data.name; - this.id = data.id; - this.members = new Map(); - this.channels = new Map(); - this.icon = data.icon; - this.afkTimeout = data.afk_timeout; - this.afkChannelId = data.afk_channel_id; +class Server { + constructor(data, client) { + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Set(); + this.channels = new Set(); + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; - for ( var x in members ) { - var member = members[ x ].user; - this.members.add( new User( member ) ); + for (var member of data.members) { + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + this.members.add(client.addUser(member)); + + } + + for (var channel of data.channels) { + this.channels.add(client.addChannel(channel)); + } + } + + get iconURL() { + if (!this.icon) + return null; + return `https://discordapp.com/api/guilds/${this.id}/icons/${this.icon}.jpg`; + } + + get afkChannel() { + if (!this.afkChannelId) + return false; + + return this.getChannel("id", this.afkChannelId); + } + + get defaultChannel() { + return this.getChannel("name", "general"); + } + + // get/set + getChannel(key, value) { + for (var channel of this.channels) { + if (channel[key] === value) { + return channel; + } + } + + return null; + } + + getMember(key, value){ + for (var member of this.members) { + if (member[key] === value) { + return member; + } + } + + return null; } } -exports.Server.prototype.getIconURL = function(){ - if(!this.icon) - return false; - return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg"; -} - -exports.Server.prototype.getAFKChannel = function(){ - - if(!this.afkChannelId) - return false; - - return this.channels.filter("id", this.afkChannelId, true); - -} - -exports.Server.prototype.getDefaultChannel = function() { - - return this.channels.filter( "name", "general", true ); - -} +module.exports = Server; \ No newline at end of file From b6506783f399efad677b4908d0e366df1347c72e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 20:30:47 +0100 Subject: [PATCH 009/191] About to start caching finalised classes --- src/Client.js | 30 ++++++++++++++++++++++++++++++ src/channel.js | 39 ++++++++++++++++----------------------- src/server.js | 4 ++++ 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/Client.js b/src/Client.js index 9b2355969..7cfd38bf6 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1,6 +1,8 @@ //discord.js modules var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); +var Server = require("./Server.js"); +var Channel = require("./Channel.js"); //node modules var request = require("superagent"); @@ -151,6 +153,34 @@ class Client { } return this.userCache.get(data.id); } + + //def addChannel + addChannel(data) { + if (!this.channelCache.has(data.id)){ + this.channelCache.set(data.id, new Channel(data, SERVER)); + } + return this.channelCache.get(data.id); + } + + //def addServer + addServer(data){ + if(!this.serverCache.has(data.id)){ + this.serverCache.set(data.id, new Server(data, this)); + } + return this.serverCache.get(data.id); + } + + //def getUser + getUser(key, value){ + for (var userRow of this.userCache) { + var user = userRow[1]; + if (user[key] === value) { + return user; + } + } + + return null; + } //def trySendConnData trySendConnData() { diff --git a/src/channel.js b/src/channel.js index 16a8e4a51..79006f309 100644 --- a/src/channel.js +++ b/src/channel.js @@ -1,28 +1,21 @@ -var List = require("./list.js").List; +class Channel { -exports.Channel = function(name, server, type, id, isPrivate){ - - if(!type){ //there's no second argument - var channel = name; - name = channel.name; - server = server; - type = channel.type; - id = channel.id; - isPrivate = channel.is_private; + constructor(data, server) { + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + get client() { + return this.server.client; + } + + equals(object) { + return object.id === this.id; } - this.name = name; - this.server = server; - this.type = type; - this.id = id; - this.isPrivate = isPrivate; - this.messages = new List("id", 5000); } -exports.Channel.equals = function(otherChannel){ - if(otherChannel.id === this.id){ - return true; - } else { - return false; - } -} +module.exports = Channel; \ No newline at end of file diff --git a/src/server.js b/src/server.js index 63cdf2ae9..7dd2733db 100644 --- a/src/server.js +++ b/src/server.js @@ -44,6 +44,10 @@ class Server { return this.getChannel("name", "general"); } + get owner() { + return this.client.getUser("id", this.ownerID); + } + // get/set getChannel(key, value) { for (var channel of this.channels) { From 0f9c1b8dad27a09232f52537cacff3285fb528b2 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 21:19:48 +0100 Subject: [PATCH 010/191] Finished caching --- lib/Client.js | 193 ++++++++++++++++++++++++++++++++++++++++++++++++- lib/channel.js | 50 +++++++------ lib/server.js | 189 +++++++++++++++++++++++++++++++++++++++++------- src/Client.js | 71 ++++++++++++++++-- src/server.js | 4 +- test/bot.js | 10 ++- 6 files changed, 451 insertions(+), 66 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 58b6e636b..1d665fdc7 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -7,6 +7,8 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); +var Server = require("./Server.js"); +var Channel = require("./Channel.js"); //node modules var request = require("superagent"); @@ -56,18 +58,37 @@ var Client = (function () { value: function debug(message) { console.log(message); } + }, { + key: "on", + value: function on(event, fn) { + this.events.set(event, fn); + } + }, { + key: "off", + value: function off(event, fn) { + this.events["delete"](event); + } //def trigger }, { key: "trigger", - value: function trigger(event) {} + value: function trigger(event) { + var args = []; + for (var arg in arguments) { + args.push(arguments[arg]); + } + var evt = this.events.get(event); + if (evt) { + evt.apply(this, args.slice(1)); + } + } //def login }, { key: "login", value: function login() { var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; - var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; + var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2]; var self = this; @@ -141,6 +162,34 @@ var Client = (function () { self.user = self.addUser(data.user); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.guilds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _server = _step.value; + + self.addServer(_server); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + self.trigger("ready"); + self.debug("cached " + self.serverCache.size + " servers, " + self.channelCache.size + " channels and " + self.userCache.size + " users."); + break; default: self.debug("received unknown packet"); @@ -161,6 +210,131 @@ var Client = (function () { return this.userCache.get(data.id); } + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.channelCache.has(data.id)) { + this.channelCache.set(data.id, new Channel(data, this.getServer("id", serverId))); + } + return this.channelCache.get(data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + if (!this.serverCache.has(data.id)) { + this.serverCache.set(data.id, new Server(data, this)); + } + return this.serverCache.get(data.id); + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.userCache[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var row = _step2.value; + + var obj = row[1]; + if (obj[key] === value) { + return obj; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.channelCache[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var row = _step3.value; + + var obj = row[1]; + if (obj[key] === value) { + return obj; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.serverCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var row = _step4.value; + + var obj = row[1]; + if (obj[key] === value) { + return obj; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -192,6 +366,21 @@ var Client = (function () { get: function get() { return this.state === 3; } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } }]); return Client; diff --git a/lib/channel.js b/lib/channel.js index a6c4f5280..679efb5ff 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -1,31 +1,33 @@ "use strict"; -var List = require("./list.js").List; +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; }; })(); -exports.Channel = function (name, server, type, id, isPrivate) { +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - if (!type) { - //there's no second argument - var channel = name; - name = channel.name; - server = server; - type = channel.type; - id = channel.id; - isPrivate = channel.is_private; +var Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + //this.isPrivate = isPrivate; //not sure about the implementation of this... } - this.name = name; - this.server = server; - this.type = type; - this.id = id; - this.isPrivate = isPrivate; - this.messages = new List("id", 5000); -}; + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); -exports.Channel.equals = function (otherChannel) { - if (otherChannel.id === this.id) { - return true; - } else { - return false; - } -}; \ No newline at end of file + return Channel; +})(); + +module.exports = Channel; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index 77adad245..b9cfbbd7d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,37 +1,172 @@ "use strict"; -var User = require("./user.js").User; -var List = require("./list.js").List; -exports.Server = function (data) { - this.region = data.region; - this.ownerID = data.owner_id; - this.name = data.name; - this.id = data.id; - this.members = new Map(); - this.channels = new Map(); - this.icon = data.icon; - this.afkTimeout = afkTimeout; - this.afkChannelId = afkChannelId; +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; }; })(); - for (var x in members) { - var member = members[x].user; - this.members.add(new User(member)); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Set(); + this.channels = new Set(); + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + this.members.add(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = data.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + this.channels.add(client.addChannel(channel, this.id)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } } -}; -exports.Server.prototype.getIconURL = function () { - if (!this.icon) return false; - return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; -}; + _createClass(Server, [{ + key: "getChannel", -exports.Server.prototype.getAFKChannel = function () { + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; - if (!this.afkChannelId) return false; + try { + for (var _iterator3 = this.channels[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var channel = _step3.value; - return this.channels.filter("id", this.afkChannelId, true); -}; + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } -exports.Server.prototype.getDefaultChannel = function () { + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; - return this.channels.filter("name", "general", true); -}; \ No newline at end of file + try { + for (var _iterator4 = this.members[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var member = _step4.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return null; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index 7cfd38bf6..a9880cf53 100644 --- a/src/Client.js +++ b/src/Client.js @@ -44,6 +44,18 @@ class Client { get ready() { return this.state === 3; } + + get servers() { + return this.serverCache; + } + + get channels() { + return this.channelCache; + } + + get users() { + return this.userCache; + } //def debug @@ -51,13 +63,28 @@ class Client { console.log(message); } + on(event, fn){ + this.events.set(event, fn); + } + + off(event, fn){ + this.events.delete(event); + } + //def trigger trigger(event) { - + var args = []; + for(var arg in arguments){ + args.push(arguments[arg]); + } + var evt = this.events.get(event); + if(evt){ + evt.apply(this, args.slice(1)); + } } //def login - login(email = "foo@bar.com", password = "pass1234s", callback = function () { }) { + login(email = "foo@bar.com", password = "pass1234", callback = function () { }) { var self = this; @@ -133,6 +160,13 @@ class Client { self.user = self.addUser( data.user ); + for(var _server of data.guilds){ + + self.addServer(_server); + + } + self.trigger("ready"); + self.debug(`cached ${self.serverCache.size} servers, ${self.channelCache.size} channels and ${self.userCache.size} users.`); break; default: @@ -155,9 +189,9 @@ class Client { } //def addChannel - addChannel(data) { + addChannel(data, serverId) { if (!this.channelCache.has(data.id)){ - this.channelCache.set(data.id, new Channel(data, SERVER)); + this.channelCache.set(data.id, new Channel(data, this.getServer("id", serverId))); } return this.channelCache.get(data.id); } @@ -172,13 +206,34 @@ class Client { //def getUser getUser(key, value){ - for (var userRow of this.userCache) { - var user = userRow[1]; - if (user[key] === value) { - return user; + for (var row of this.userCache) { + var obj = row[1]; + if (obj[key] === value) { + return obj; } } + return null; + } + //def getChannel + getChannel(key, value){ + for (var row of this.channelCache) { + var obj = row[1]; + if (obj[key] === value) { + return obj; + } + } + return null; + } + + //def getServer + getServer(key, value){ + for (var row of this.serverCache) { + var obj = row[1]; + if (obj[key] === value) { + return obj; + } + } return null; } diff --git a/src/server.js b/src/server.js index 7dd2733db..e09cdb805 100644 --- a/src/server.js +++ b/src/server.js @@ -18,12 +18,12 @@ class Server { // get a user from this server's member list, // it will be identical (unless an async change occurred) // to the client's cache. - this.members.add(client.addUser(member)); + this.members.add(client.addUser(member.user)); } for (var channel of data.channels) { - this.channels.add(client.addChannel(channel)); + this.channels.add(client.addChannel(channel, this.id)); } } diff --git a/test/bot.js b/test/bot.js index e392c7ba2..5c9dbeb95 100644 --- a/test/bot.js +++ b/test/bot.js @@ -2,6 +2,10 @@ var Discord = require("../lib/index.js"); var mybot = new Discord.Client(); -mybot.login("riftes@outlook.com", "hydrabotsecure", function(err, res){ - console.log(res); -}); \ No newline at end of file +mybot.login("email", "pass", function(err, res){ + +}); + +mybot.on("ready", function(){ + console.log("Ready!"); +}) \ No newline at end of file From b104cc93b21292d83e058fbf6ff1ecaae952fcff Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 21:21:51 +0100 Subject: [PATCH 011/191] Fixed credentials ;s --- .gitignore | 1 + test/bot.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 661f8f613..763414655 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules +test/auth.json diff --git a/test/bot.js b/test/bot.js index 5c9dbeb95..8df078e92 100644 --- a/test/bot.js +++ b/test/bot.js @@ -1,8 +1,8 @@ var Discord = require("../lib/index.js"); - +var Auth = require("./auth.json"); var mybot = new Discord.Client(); -mybot.login("email", "pass", function(err, res){ +mybot.login(Auth.email, Auth.password, function(err, res){ }); From 035d3b368ea3687e885a4928ce232ac6dda46e17 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 21:32:54 +0100 Subject: [PATCH 012/191] Updated readme --- .gitignore | 1 + README.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 661f8f613..763414655 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules +test/auth.json diff --git a/README.md b/README.md index 659bc2e8c..b80c65f0d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ The aim of this API is to make it *really* simple to start developing your bots. New update features **big speed boosts** (everything cached and sorted with around 1 second of calling the login function) upon connection and allows editing of messages! +## PLEASE BE AWARE - I'm currently rewriting this _entire_ module in ECMAScript 6 and then using Babel to compile it so it works in node. That means for a few days I won't be adding features, but after that features will come out faster and better than ever! +back to + **[Find the website here.](http://discord-js.github.io)** From 2965a95af9dc1bf85dc67201a64e92d92b6a85d0 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 21:33:07 +0100 Subject: [PATCH 013/191] 2.7.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 43fbfabd0..1b8a533f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "2.7.1", + "version": "2.7.2", "description": "A way to interface with the Discord API", "main": "index.js", "scripts": { From 31a0cba0d1ae00de2ed3ef54e97a8a951fcf7d7e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 22:12:07 +0100 Subject: [PATCH 014/191] added keepalive --- lib/Client.js | 22 +++++++++++++++++- lib/asd.js | 63 --------------------------------------------------- src/Client.js | 17 ++++++++++++++ 3 files changed, 38 insertions(+), 64 deletions(-) delete mode 100644 lib/asd.js diff --git a/lib/Client.js b/lib/Client.js index 1d665fdc7..97900e44b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -52,9 +52,16 @@ var Client = (function () { } _createClass(Client, [{ - key: "debug", + key: "sendPacket", + value: function sendPacket(JSONObject) { + if (this.websocket.readyState === 1) { + this.websocket.send(JSON.stringify(JSONObject)); + } + } //def debug + }, { + key: "debug", value: function debug(message) { console.log(message); } @@ -68,6 +75,15 @@ var Client = (function () { value: function off(event, fn) { this.events["delete"](event); } + }, { + key: "keepAlive", + value: function keepAlive() { + this.debug("keep alive triggered"); + this.sendPacket({ + op: 1, + d: Date.now() + }); + } //def trigger }, { @@ -190,6 +206,10 @@ var Client = (function () { self.trigger("ready"); self.debug("cached " + self.serverCache.size + " servers, " + self.channelCache.size + " channels and " + self.userCache.size + " users."); + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + break; default: self.debug("received unknown packet"); diff --git a/lib/asd.js b/lib/asd.js deleted file mode 100644 index c74b5e209..000000000 --- a/lib/asd.js +++ /dev/null @@ -1,63 +0,0 @@ -"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 request = require("superagent"); - -var defaultOptions = { - cache_tokens: false -}; - -var Client = (function () { - function Client() { - var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; - var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; - - _classCallCheck(this, Client); - - /* - When created, if a token is specified the Client will - try connecting with it. If the token is incorrect, no - further efforts will be made to connect. - */ - this.options = options; - this.token = token; - this.state = 0; - this.websocket = null; - this.events = new Map(); - this.user = null; - /* - State values: - 0 - idle - 1 - logging in - 2 - logged in - 3 - ready - 4 - disconnected - */ - } - - _createClass(Client, [{ - key: "login", - - //def login - value: function login() { - var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; - var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; - - if (this.state === 0 || this.state === 4) { - - this.state = 1; - request.post(); - } - } - }, { - key: "ready", - get: function get() { - return this.state === 3; - } - }]); - - return Client; -})(); \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index a9880cf53..f7b8866f8 100644 --- a/src/Client.js +++ b/src/Client.js @@ -57,6 +57,11 @@ class Client { return this.userCache; } + sendPacket(JSONObject){ + if(this.websocket.readyState === 1){ + this.websocket.send(JSON.stringify(JSONObject)); + } + } //def debug debug(message) { @@ -71,6 +76,14 @@ class Client { this.events.delete(event); } + keepAlive(){ + this.debug("keep alive triggered"); + this.sendPacket({ + op: 1, + d: Date.now() + }); + } + //def trigger trigger(event) { var args = []; @@ -167,6 +180,10 @@ class Client { } self.trigger("ready"); self.debug(`cached ${self.serverCache.size} servers, ${self.channelCache.size} channels and ${self.userCache.size} users.`); + + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); break; default: From 1f77ed226a3211bdef0e69b201b594f4ebd722ee Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 17:07:41 +0100 Subject: [PATCH 015/191] rewriting... woo --- .gitignore | 1 + README.md | 3 + lib/Client.js | 228 +++++++++++++++++++++++++++++++++++++++++++++++-- lib/channel.js | 50 +++++------ lib/server.js | 189 ++++++++++++++++++++++++++++++++++------ package.json | 2 +- src/Client.js | 117 +++++++++++++++++++++++-- src/channel.js | 39 ++++----- src/server.js | 104 ++++++++++++++-------- test/bot.js | 12 ++- 10 files changed, 614 insertions(+), 131 deletions(-) diff --git a/.gitignore b/.gitignore index 661f8f613..763414655 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules +test/auth.json diff --git a/README.md b/README.md index 659bc2e8c..b80c65f0d 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ The aim of this API is to make it *really* simple to start developing your bots. New update features **big speed boosts** (everything cached and sorted with around 1 second of calling the login function) upon connection and allows editing of messages! +## PLEASE BE AWARE - I'm currently rewriting this _entire_ module in ECMAScript 6 and then using Babel to compile it so it works in node. That means for a few days I won't be adding features, but after that features will come out faster and better than ever! +back to + **[Find the website here.](http://discord-js.github.io)** diff --git a/lib/Client.js b/lib/Client.js index 58b6e636b..d5d9bb683 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -7,6 +7,8 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); +var Server = require("./Server.js"); +var Channel = require("./Channel.js"); //node modules var request = require("superagent"); @@ -44,30 +46,65 @@ var Client = (function () { 4 - disconnected */ - this.userCache = new Map(); - this.channelCache = new Map(); - this.serverCache = new Map(); + this.userCache = []; + this.channelCache = []; + this.serverCache = []; } _createClass(Client, [{ - key: "debug", + key: "sendPacket", + value: function sendPacket(JSONObject) { + if (this.websocket.readyState === 1) { + this.websocket.send(JSON.stringify(JSONObject)); + } + } //def debug + }, { + key: "debug", value: function debug(message) { console.log(message); } + }, { + key: "on", + value: function on(event, fn) { + this.events.set(event, fn); + } + }, { + key: "off", + value: function off(event, fn) { + this.events["delete"](event); + } + }, { + key: "keepAlive", + value: function keepAlive() { + this.debug("keep alive triggered"); + this.sendPacket({ + op: 1, + d: Date.now() + }); + } //def trigger }, { key: "trigger", - value: function trigger(event) {} + value: function trigger(event) { + var args = []; + for (var arg in arguments) { + args.push(arguments[arg]); + } + var evt = this.events.get(event); + if (evt) { + evt.apply(this, args.slice(1)); + } + } //def login }, { key: "login", value: function login() { var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; - var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; + var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2]; var self = this; @@ -141,6 +178,40 @@ var Client = (function () { self.user = self.addUser(data.user); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.guilds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _server = _step.value; + + self.addServer(_server); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + self.trigger("ready"); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels and " + self.userCache.length + " users."); + + console.log(self.channelCache[0]); + + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + break; default: self.debug("received unknown packet"); @@ -155,10 +226,134 @@ var Client = (function () { }, { key: "addUser", value: function addUser(data) { - if (!this.userCache.has(data.id)) { - this.userCache.set(data.id, new User(data)); + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); } - return this.userCache.get(data.id); + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + if (!this.getServer("id", data.id)) { + this.serverCache.push(new Server(data, this)); + } + return this.getServer("id", data.id); + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.userCache[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var user = _step2.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.channelCache[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var channel = _step3.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.serverCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var server = _step4.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return null; } //def trySendConnData @@ -192,6 +387,21 @@ var Client = (function () { get: function get() { return this.state === 3; } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } }]); return Client; diff --git a/lib/channel.js b/lib/channel.js index a6c4f5280..679efb5ff 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -1,31 +1,33 @@ "use strict"; -var List = require("./list.js").List; +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; }; })(); -exports.Channel = function (name, server, type, id, isPrivate) { +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - if (!type) { - //there's no second argument - var channel = name; - name = channel.name; - server = server; - type = channel.type; - id = channel.id; - isPrivate = channel.is_private; +var Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + //this.isPrivate = isPrivate; //not sure about the implementation of this... } - this.name = name; - this.server = server; - this.type = type; - this.id = id; - this.isPrivate = isPrivate; - this.messages = new List("id", 5000); -}; + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); -exports.Channel.equals = function (otherChannel) { - if (otherChannel.id === this.id) { - return true; - } else { - return false; - } -}; \ No newline at end of file + return Channel; +})(); + +module.exports = Channel; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index 77adad245..b9cfbbd7d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,37 +1,172 @@ "use strict"; -var User = require("./user.js").User; -var List = require("./list.js").List; -exports.Server = function (data) { - this.region = data.region; - this.ownerID = data.owner_id; - this.name = data.name; - this.id = data.id; - this.members = new Map(); - this.channels = new Map(); - this.icon = data.icon; - this.afkTimeout = afkTimeout; - this.afkChannelId = afkChannelId; +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; }; })(); - for (var x in members) { - var member = members[x].user; - this.members.add(new User(member)); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Set(); + this.channels = new Set(); + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + this.members.add(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = data.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + this.channels.add(client.addChannel(channel, this.id)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } } -}; -exports.Server.prototype.getIconURL = function () { - if (!this.icon) return false; - return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; -}; + _createClass(Server, [{ + key: "getChannel", -exports.Server.prototype.getAFKChannel = function () { + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; - if (!this.afkChannelId) return false; + try { + for (var _iterator3 = this.channels[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var channel = _step3.value; - return this.channels.filter("id", this.afkChannelId, true); -}; + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } -exports.Server.prototype.getDefaultChannel = function () { + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; - return this.channels.filter("name", "general", true); -}; \ No newline at end of file + try { + for (var _iterator4 = this.members[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var member = _step4.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return null; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; \ No newline at end of file diff --git a/package.json b/package.json index 43fbfabd0..1b8a533f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "2.7.1", + "version": "2.7.2", "description": "A way to interface with the Discord API", "main": "index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 9b2355969..8abbcdbb5 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1,6 +1,8 @@ //discord.js modules var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); +var Server = require("./Server.js"); +var Channel = require("./Channel.js"); //node modules var request = require("superagent"); @@ -34,28 +36,68 @@ class Client { 4 - disconnected */ - this.userCache = new Map(); - this.channelCache = new Map(); - this.serverCache = new Map(); + this.userCache = []; + this.channelCache = []; + this.serverCache = []; } get ready() { return this.state === 3; } + + get servers() { + return this.serverCache; + } + + get channels() { + return this.channelCache; + } + + get users() { + return this.userCache; + } + sendPacket(JSONObject){ + if(this.websocket.readyState === 1){ + this.websocket.send(JSON.stringify(JSONObject)); + } + } //def debug debug(message) { console.log(message); } + on(event, fn){ + this.events.set(event, fn); + } + + off(event, fn){ + this.events.delete(event); + } + + keepAlive(){ + this.debug("keep alive triggered"); + this.sendPacket({ + op: 1, + d: Date.now() + }); + } + //def trigger trigger(event) { - + var args = []; + for(var arg in arguments){ + args.push(arguments[arg]); + } + var evt = this.events.get(event); + if(evt){ + evt.apply(this, args.slice(1)); + } } //def login - login(email = "foo@bar.com", password = "pass1234s", callback = function () { }) { + login(email = "foo@bar.com", password = "pass1234", callback = function () { }) { var self = this; @@ -131,6 +173,19 @@ class Client { self.user = self.addUser( data.user ); + for(var _server of data.guilds){ + + self.addServer(_server); + + } + self.trigger("ready"); + self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels and ${self.userCache.length} users.`); + + console.log(self.channelCache[0]); + + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); break; default: @@ -146,10 +201,56 @@ class Client { //def addUser addUser(data) { - if (!this.userCache.has(data.id)){ - this.userCache.set(data.id, new User(data)); + if (!this.getUser("id", data.id)){ + this.userCache.push(new User(data)); } - return this.userCache.get(data.id); + return this.getUser("id", data.id); + } + + //def addChannel + addChannel(data, serverId) { + if (!this.getChannel("id", data.id)){ + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + + //def addServer + addServer(data){ + if(!this.getServer("id", data.id)){ + this.serverCache.push(new Server(data, this)); + } + return this.getServer("id", data.id); + } + + //def getUser + getUser(key, value){ + for(var user of this.userCache){ + if(user[key] === value){ + return user; + } + } + return null; + } + + //def getChannel + getChannel(key, value){ + for(var channel of this.channelCache){ + if(channel[key] === value){ + return channel; + } + } + return null; + } + + //def getServer + getServer(key = "id", value = "abc123"){ + for(var server of this.serverCache){ + if(server[key] === value){ + return server; + } + } + return null; } //def trySendConnData diff --git a/src/channel.js b/src/channel.js index 16a8e4a51..79006f309 100644 --- a/src/channel.js +++ b/src/channel.js @@ -1,28 +1,21 @@ -var List = require("./list.js").List; +class Channel { -exports.Channel = function(name, server, type, id, isPrivate){ - - if(!type){ //there's no second argument - var channel = name; - name = channel.name; - server = server; - type = channel.type; - id = channel.id; - isPrivate = channel.is_private; + constructor(data, server) { + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + get client() { + return this.server.client; + } + + equals(object) { + return object.id === this.id; } - this.name = name; - this.server = server; - this.type = type; - this.id = id; - this.isPrivate = isPrivate; - this.messages = new List("id", 5000); } -exports.Channel.equals = function(otherChannel){ - if(otherChannel.id === this.id){ - return true; - } else { - return false; - } -} +module.exports = Channel; \ No newline at end of file diff --git a/src/server.js b/src/server.js index a64a7114d..e09cdb805 100644 --- a/src/server.js +++ b/src/server.js @@ -1,39 +1,73 @@ -var User = require( "./user.js" ).User; -var List = require( "./list.js" ).List; -exports.Server = function( data ) { - this.region = data.region; - this.ownerID = data.owner_id; - this.name = data.name; - this.id = data.id; - this.members = new Map(); - this.channels = new Map(); - this.icon = data.icon; - this.afkTimeout = data.afk_timeout; - this.afkChannelId = data.afk_channel_id; +class Server { + constructor(data, client) { + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = new Set(); + this.channels = new Set(); + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; - for ( var x in members ) { - var member = members[ x ].user; - this.members.add( new User( member ) ); + for (var member of data.members) { + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + this.members.add(client.addUser(member.user)); + + } + + for (var channel of data.channels) { + this.channels.add(client.addChannel(channel, this.id)); + } + } + + get iconURL() { + if (!this.icon) + return null; + return `https://discordapp.com/api/guilds/${this.id}/icons/${this.icon}.jpg`; + } + + get afkChannel() { + if (!this.afkChannelId) + return false; + + return this.getChannel("id", this.afkChannelId); + } + + get defaultChannel() { + return this.getChannel("name", "general"); + } + + get owner() { + return this.client.getUser("id", this.ownerID); + } + + // get/set + getChannel(key, value) { + for (var channel of this.channels) { + if (channel[key] === value) { + return channel; + } + } + + return null; + } + + getMember(key, value){ + for (var member of this.members) { + if (member[key] === value) { + return member; + } + } + + return null; } } -exports.Server.prototype.getIconURL = function(){ - if(!this.icon) - return false; - return "https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg"; -} - -exports.Server.prototype.getAFKChannel = function(){ - - if(!this.afkChannelId) - return false; - - return this.channels.filter("id", this.afkChannelId, true); - -} - -exports.Server.prototype.getDefaultChannel = function() { - - return this.channels.filter( "name", "general", true ); - -} +module.exports = Server; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index e392c7ba2..8df078e92 100644 --- a/test/bot.js +++ b/test/bot.js @@ -1,7 +1,11 @@ var Discord = require("../lib/index.js"); - +var Auth = require("./auth.json"); var mybot = new Discord.Client(); -mybot.login("riftes@outlook.com", "hydrabotsecure", function(err, res){ - console.log(res); -}); \ No newline at end of file +mybot.login(Auth.email, Auth.password, function(err, res){ + +}); + +mybot.on("ready", function(){ + console.log("Ready!"); +}) \ No newline at end of file From 97a6ff277266e7f5140169d525ad58790f5cb5d3 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 17:30:20 +0100 Subject: [PATCH 016/191] fixed how channels and users are cached --- lib/Client.js | 123 +++++++++++++++++++++++++++++-------------------- lib/channel.js | 79 +++++++++++++++++++++++-------- lib/server.js | 103 ++++++++++++++++------------------------- src/Client.js | 8 ++-- src/channel.js | 17 +++++++ src/server.js | 10 ++-- 6 files changed, 197 insertions(+), 143 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index d5d9bb683..978473d59 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -186,7 +186,32 @@ var Client = (function () { for (var _iterator = data.guilds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _server = _step.value; - self.addServer(_server); + var server = self.addServer(_server); + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = _server.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + server.channels.push(self.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } } } catch (err) { _didIteratorError = true; @@ -206,8 +231,6 @@ var Client = (function () { self.trigger("ready"); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels and " + self.userCache.length + " users."); - console.log(self.channelCache[0]); - setInterval(function () { self.keepAlive.apply(self); }, data.heartbeat_interval); @@ -256,50 +279,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = this.userCache[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var user = _step2.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { - for (var _iterator3 = this.channelCache[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var channel = _step3.value; + for (var _iterator3 = this.userCache[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var user = _step3.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -320,22 +309,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { - for (var _iterator4 = this.serverCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var server = _step4.value; + for (var _iterator4 = this.channelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var channel = _step4.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -356,6 +343,42 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = this.serverCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var server = _step5.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", diff --git a/lib/channel.js b/lib/channel.js index 679efb5ff..8938e594a 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -5,29 +5,70 @@ 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 Channel = (function () { - function Channel(data, server) { - _classCallCheck(this, Channel); + function Channel(data, server) { + _classCallCheck(this, Channel); - this.server = server; - this.name = data.name; - this.type = data.type; - this.id = data.id; - //this.isPrivate = isPrivate; //not sure about the implementation of this... + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - _createClass(Channel, [{ - key: "equals", - value: function equals(object) { - return object.id === this.id; - } - }, { - key: "client", - get: function get() { - return this.server.client; - } - }]); + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; - return Channel; + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); + + return Channel; })(); module.exports = Channel; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index b9cfbbd7d..3549683de 100644 --- a/lib/server.js +++ b/lib/server.js @@ -13,8 +13,8 @@ var Server = (function () { this.ownerID = data.owner_id; this.name = data.name; this.id = data.id; - this.members = new Set(); - this.channels = new Set(); + this.members = []; + this.channels = []; this.icon = data.icon; this.afkTimeout = data.afk_timeout; this.afkChannelId = data.afk_channel_id; @@ -32,7 +32,7 @@ var Server = (function () { // get a user from this server's member list, // it will be identical (unless an async change occurred) // to the client's cache. - this.members.add(client.addUser(member.user)); + this.members.push(client.addUser(member.user)); } } catch (err) { _didIteratorError = true; @@ -48,31 +48,6 @@ var Server = (function () { } } } - - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = data.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var channel = _step2.value; - - this.channels.add(client.addChannel(channel, this.id)); - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } } _createClass(Server, [{ @@ -80,16 +55,48 @@ var Server = (function () { // get/set value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { - for (var _iterator3 = this.channels[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var channel = _step3.value; + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; - if (channel[key] === value) { - return channel; + if (member[key] === value) { + return member; } } } catch (err) { @@ -110,38 +117,6 @@ var Server = (function () { return null; } }, { - key: "getMember", - value: function getMember(key, value) { - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = this.members[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var member = _step4.value; - - if (member[key] === value) { - return member; - } - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - return null; - } - }, { key: "iconURL", get: function get() { if (!this.icon) return null; diff --git a/src/Client.js b/src/Client.js index 8abbcdbb5..6ebddfc12 100644 --- a/src/Client.js +++ b/src/Client.js @@ -175,14 +175,16 @@ class Client { for(var _server of data.guilds){ - self.addServer(_server); + var server = self.addServer(_server); + + for(var channel of _server.channels){ + server.channels.push( self.addChannel(channel, server.id) ); + } } self.trigger("ready"); self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels and ${self.userCache.length} users.`); - console.log(self.channelCache[0]); - setInterval(function () { self.keepAlive.apply(self); }, data.heartbeat_interval); diff --git a/src/channel.js b/src/channel.js index 79006f309..4b92e834b 100644 --- a/src/channel.js +++ b/src/channel.js @@ -5,6 +5,7 @@ class Channel { this.name = data.name; this.type = data.type; this.id = data.id; + this.messages = []; //this.isPrivate = isPrivate; //not sure about the implementation of this... } @@ -15,6 +16,22 @@ class Channel { equals(object) { return object.id === this.id; } + + addMessage(data){ + if(!this.getMessage("id", data.id)){ + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + + getMessage(key, value){ + for(var message of this.messages){ + if(message[key] === value){ + return message; + } + } + return null; + } } diff --git a/src/server.js b/src/server.js index e09cdb805..322db6a44 100644 --- a/src/server.js +++ b/src/server.js @@ -5,8 +5,8 @@ class Server { this.ownerID = data.owner_id; this.name = data.name; this.id = data.id; - this.members = new Set(); - this.channels = new Set(); + this.members = []; + this.channels = []; this.icon = data.icon; this.afkTimeout = data.afk_timeout; this.afkChannelId = data.afk_channel_id; @@ -18,13 +18,9 @@ class Server { // get a user from this server's member list, // it will be identical (unless an async change occurred) // to the client's cache. - this.members.add(client.addUser(member.user)); + this.members.push(client.addUser(member.user)); } - - for (var channel of data.channels) { - this.channels.add(client.addChannel(channel, this.id)); - } } get iconURL() { From 090b9dbcffcf5deba828752c7918245db01eaccf Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 18:13:53 +0100 Subject: [PATCH 017/191] Added message deletion --- lib/Client.js | 174 ++++++++++++++++++++++++++++++++++++------------- lib/message.js | 95 ++++++++++++++++++--------- src/Client.js | 37 +++++++++++ src/message.js | 59 ++++++++--------- test/bot.js | 12 +++- 5 files changed, 270 insertions(+), 107 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index b57a5f31e..47d63ee49 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -9,6 +9,7 @@ var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); var Server = require("./Server.js"); var Channel = require("./Channel.js"); +var Message = require("./Message.js"); //node modules var request = require("superagent"); @@ -237,6 +238,53 @@ var Client = (function () { break; case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + + self.trigger("message", msg); + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; default: self.debug("received unknown packet"); @@ -281,50 +329,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = this.userCache[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var user = _step3.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { - for (var _iterator4 = this.channelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var channel = _step4.value; + for (var _iterator4 = this.userCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var user = _step4.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -345,22 +359,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = this.serverCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var server = _step5.value; + for (var _iterator5 = this.channelCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var channel = _step5.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -381,6 +393,42 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = this.serverCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var server = _step6.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -427,6 +475,38 @@ var Client = (function () { get: function get() { return this.userCache; } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var channel = _step7.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + return msgs; + } }]); return Client; diff --git a/lib/message.js b/lib/message.js index af9ce1f4b..f4b937f02 100644 --- a/lib/message.js +++ b/lib/message.js @@ -1,41 +1,76 @@ "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 User = require("./user.js").User; var List = require("./list.js").List; var PMChannel = require("./PMChannel.js").PMChannel; -exports.Message = function (time, author, content, channel, id, mentions, everyoneMentioned, embeds) { +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); - if (!content) { - message = time; - channel = author; - time = message.timestamp; - author = message.author; - content = message.content; - id = message.id; - mentions = message.mentions; - everyoneMentioned = message.mention_everyone; - embeds = message.embeds; + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; } - this.time = Date.parse(time); - this.author = new User(author); - this.content = content.replace(/\s+/g, ' ').trim(); //content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); - this.channel = channel; - this.id = id; - this.mentions = new List("id"); - this.everyoneMentioned = everyoneMentioned; - this.embeds = embeds; - for (x in mentions) { - var _mention = mentions[x]; - this.mentions.add(new User(_mention)); - } -}; + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ -exports.Message.prototype.isPM = function () { - return this.channel instanceof PMChannel; -}; + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; -exports.Message.prototype.isMentioned = function (user) { - return this.mentions.filter("id", user.id).length > 0; -}; \ No newline at end of file + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }]); + + return Message; +})(); + +module.exports = Message; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index ac3511461..df79c64e8 100644 --- a/src/Client.js +++ b/src/Client.js @@ -3,6 +3,7 @@ var Endpoints = require("./Endpoints.js"); var User = require("./User.js"); var Server = require("./Server.js"); var Channel = require("./Channel.js"); +var Message = require("./Message.js"); //node modules var request = require("superagent"); @@ -57,6 +58,16 @@ class Client { return this.userCache; } + get messages() { + + var msgs = []; + for (var channel of this.channelCache) { + msgs = msgs.concat(channel.messages); + } + return msgs; + + } + sendPacket(JSONObject) { if (this.websocket.readyState === 1) { this.websocket.send(JSON.stringify(JSONObject)); @@ -191,6 +202,32 @@ class Client { break; case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + for (var mention of data.mentions) { + mentions.push(self.addUser(mention)); + } + + var channel = self.getChannel("id", data.channel_id); + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + + self.trigger("message", msg); + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + }else{ + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; default: self.debug("received unknown packet"); diff --git a/src/message.js b/src/message.js index 121bbf5dd..ba869c1e1 100644 --- a/src/message.js +++ b/src/message.js @@ -2,38 +2,39 @@ var User = require( "./user.js" ).User; var List = require( "./list.js" ).List; var PMChannel = require( "./PMChannel.js" ).PMChannel; -exports.Message = function( time, author, content, channel, id, mentions, everyoneMentioned, embeds ) { - - if ( !content ) { - message = time; - channel = author; - time = message.timestamp; - author = message.author; - content = message.content; - id = message.id; - mentions = message.mentions; - everyoneMentioned = message.mention_everyone; - embeds = message.embeds; +class Message{ + constructor(data, channel, mentions, author){ + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; } - - this.time = Date.parse( time ); - this.author = new User( author ); - this.content = content.replace( /\s+/g, ' ' ).trim(); //content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); - this.channel = channel; - this.id = id; - this.mentions = new List( "id" ); - this.everyoneMentioned = everyoneMentioned; - this.embeds = embeds; - for ( x in mentions ) { - var _mention = mentions[ x ]; - this.mentions.add( new User( _mention ) ); + + isMentioned( user ){ + var id = (user.id ? user.id : user); + for(var mention of this.mentions){ + if(mention.id === id){ + return true; + } + } + return false; + } + + get sender(){ + return this.author; } } -exports.Message.prototype.isPM = function() { +/*exports.Message.prototype.isPM = function() { return ( this.channel instanceof PMChannel ); -} +}*/ -exports.Message.prototype.isMentioned = function( user ) { - return ( this.mentions.filter( "id", user.id ).length > 0 ); -} +module.exports = Message; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index 8df078e92..2adab326e 100644 --- a/test/bot.js +++ b/test/bot.js @@ -8,4 +8,14 @@ mybot.login(Auth.email, Auth.password, function(err, res){ mybot.on("ready", function(){ console.log("Ready!"); -}) \ No newline at end of file +}) + +mybot.on("message", function(msg){ + console.log("Another message by "+msg.author.username+"... now I have "+mybot.messages.length); +}) + +mybot.on("messageDelete", function(channel, message){ + + console.log("MESSAGE WAS DELETED BY " + ( message ? message.author.username : channel.name )); + +}); \ No newline at end of file From ead8287881b49a15fb92c642bd4250a044692fb6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 18:31:39 +0100 Subject: [PATCH 018/191] added message update listening --- lib/Client.js | 171 +++++++++++++++++++++++++++++++++----------------- src/Client.js | 37 ++++++++++- test/bot.js | 8 ++- 3 files changed, 154 insertions(+), 62 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 47d63ee49..f8fbe77d3 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -161,7 +161,7 @@ var Client = (function () { this.websocket.onmessage = function (e) { var dat = false, - data = false; + data = {}; try { dat = JSON.parse(e.data); @@ -284,6 +284,59 @@ var Client = (function () { //don't have the cache of that message ;( self.trigger("messageDelete", channel); } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var mention = _step4.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened break; default: @@ -329,50 +382,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = this.userCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var user = _step4.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = this.channelCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var channel = _step5.value; + for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var user = _step5.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -393,22 +412,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.serverCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var server = _step6.value; + for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var channel = _step6.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -429,6 +446,42 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var server = _step7.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -480,27 +533,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var channel = _step7.value; + for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError8) { + throw _iteratorError8; } } } diff --git a/src/Client.js b/src/Client.js index df79c64e8..a38fb12a9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -166,7 +166,7 @@ class Client { //message this.websocket.onmessage = function (e) { - var dat = false, data = false; + var dat = false, data = {}; try { dat = JSON.parse(e.data); @@ -223,11 +223,44 @@ class Client { if (message) { self.trigger("messageDelete", channel, message); channel.messages.splice(channel.messages.indexOf(message), 1); - }else{ + } else { //don't have the cache of that message ;( self.trigger("messageDelete", channel); } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + for (var mention of data.mentions) { + mentions.push(self.addUser(mention)); + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + break; default: self.debug("received unknown packet"); diff --git a/test/bot.js b/test/bot.js index 2adab326e..3d87dccca 100644 --- a/test/bot.js +++ b/test/bot.js @@ -18,4 +18,10 @@ mybot.on("messageDelete", function(channel, message){ console.log("MESSAGE WAS DELETED BY " + ( message ? message.author.username : channel.name )); -}); \ No newline at end of file +}); + +mybot.on("messageUpdate", function(message, formerMessage){ + + console.log(message.author.username, "changed", formerMessage.content, "to", message.content); + +}) \ No newline at end of file From 7b7d7ad1af45a96af835712df71b3a26a022f939 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 18:34:38 +0100 Subject: [PATCH 019/191] fixed message cache updating --- lib/Client.js | 2 ++ src/Client.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index f8fbe77d3..9526b103c 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -333,6 +333,8 @@ var Client = (function () { var newMessage = new Message(info, channel, mentions, formerMessage.author); self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; } // message isn't in cache, and if it's a partial it could cause diff --git a/src/Client.js b/src/Client.js index a38fb12a9..aa71b2758 100644 --- a/src/Client.js +++ b/src/Client.js @@ -256,6 +256,8 @@ class Client { self.trigger("messageUpdate", newMessage, formerMessage); + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } // message isn't in cache, and if it's a partial it could cause From e473b03de50623f902faf6b758cb6fd3d042a9c1 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 20:25:12 +0100 Subject: [PATCH 020/191] experimental addition --- lib/Client.js | 144 +++++++++++++++++++++----------------------------- src/Client.js | 7 +-- 2 files changed, 60 insertions(+), 91 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 9526b103c..cf8a79b12 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -304,33 +304,7 @@ var Client = (function () { info[key] = data[key]; } - var mentions = []; - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = data.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var mention = _step4.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - var newMessage = new Message(info, channel, mentions, formerMessage.author); + var newMessage = new Message(info, channel, data.mentions.map(self.addUser), formerMessage.author); self.trigger("messageUpdate", newMessage, formerMessage); @@ -384,16 +358,50 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.userCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var user = _step4.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var user = _step5.value; + for (var _iterator5 = this.channelCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var channel = _step5.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -414,20 +422,22 @@ var Client = (function () { return null; } - //def getChannel + //def getServer }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var channel = _step6.value; + for (var _iterator6 = this.serverCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var server = _step6.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -448,42 +458,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; - - try { - for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var server = _step7.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; - } finally { - try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); - } - } finally { - if (_didIteratorError7) { - throw _iteratorError7; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -535,27 +509,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var channel = _step8.value; + for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var channel = _step7.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError7) { + throw _iteratorError7; } } } diff --git a/src/Client.js b/src/Client.js index aa71b2758..bdf0bd733 100644 --- a/src/Client.js +++ b/src/Client.js @@ -247,12 +247,7 @@ class Client { info[key] = data[key]; } - var mentions = []; - for (var mention of data.mentions) { - mentions.push(self.addUser(mention)); - } - - var newMessage = new Message(info, channel, mentions, formerMessage.author); + var newMessage = new Message(info, channel, data.mentions.map(self.addUser), formerMessage.author); self.trigger("messageUpdate", newMessage, formerMessage); From 0efc734154a706bbbb975b1c8723dcd8a8edf2ee Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 21:10:18 +0100 Subject: [PATCH 021/191] Revert "experimental addition" This reverts commit e473b03de50623f902faf6b758cb6fd3d042a9c1. --- lib/Client.js | 144 +++++++++++++++++++++++++++++--------------------- src/Client.js | 7 ++- 2 files changed, 91 insertions(+), 60 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index cf8a79b12..9526b103c 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -304,7 +304,33 @@ var Client = (function () { info[key] = data[key]; } - var newMessage = new Message(info, channel, data.mentions.map(self.addUser), formerMessage.author); + var mentions = []; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var mention = _step4.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); self.trigger("messageUpdate", newMessage, formerMessage); @@ -358,50 +384,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = this.userCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var user = _step4.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = this.channelCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var channel = _step5.value; + for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var user = _step5.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -422,22 +414,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.serverCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var server = _step6.value; + for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var channel = _step6.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -458,6 +448,42 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer() { + var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; + var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var server = _step7.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -509,27 +535,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var channel = _step7.value; + for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError8) { + throw _iteratorError8; } } } diff --git a/src/Client.js b/src/Client.js index bdf0bd733..aa71b2758 100644 --- a/src/Client.js +++ b/src/Client.js @@ -247,7 +247,12 @@ class Client { info[key] = data[key]; } - var newMessage = new Message(info, channel, data.mentions.map(self.addUser), formerMessage.author); + var mentions = []; + for (var mention of data.mentions) { + mentions.push(self.addUser(mention)); + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); self.trigger("messageUpdate", newMessage, formerMessage); From b3c030a8f524524a6d022521a75d8b9efbc2fd73 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 21:46:59 +0100 Subject: [PATCH 022/191] fixed experimental --- lib/Client.js | 14 +++++++++++++- src/Client.js | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 9526b103c..d5b1125f0 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -310,7 +310,7 @@ var Client = (function () { var _iteratorError4 = undefined; try { - for (var _iterator4 = data.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + for (var _iterator4 = info.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var mention = _step4.value; mentions.push(self.addUser(mention)); @@ -341,6 +341,18 @@ var Client = (function () { // all hell to break loose... best to just act as if nothing happened break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/src/Client.js b/src/Client.js index aa71b2758..9642c78c4 100644 --- a/src/Client.js +++ b/src/Client.js @@ -248,12 +248,12 @@ class Client { } var mentions = []; - for (var mention of data.mentions) { + for (var mention of info.mentions) { mentions.push(self.addUser(mention)); } var newMessage = new Message(info, channel, mentions, formerMessage.author); - + self.trigger("messageUpdate", newMessage, formerMessage); channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; @@ -264,6 +264,18 @@ class Client { // all hell to break loose... best to just act as if nothing happened break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if(server){ + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); From 278ceeee9c08ee34bfde11041201202b33116ab9 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 22:13:33 +0100 Subject: [PATCH 023/191] added channel deletion monitoring and uptime --- lib/Client.js | 32 +++++++++++++++++++++++++++++--- src/Client.js | 32 +++++++++++++++++++++++++++++++- test/bot.js | 2 +- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index d5b1125f0..a707d366d 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -50,6 +50,7 @@ var Client = (function () { this.userCache = []; this.channelCache = []; this.serverCache = []; + this.readyTime = null; } _createClass(Client, [{ @@ -230,6 +231,7 @@ var Client = (function () { } self.trigger("ready"); + self.readyTime = Date.now(); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels and " + self.userCache.length + " users."); setInterval(function () { @@ -353,6 +355,26 @@ var Client = (function () { break; + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); @@ -463,9 +485,7 @@ var Client = (function () { //def getServer }, { key: "getServer", - value: function getServer() { - var key = arguments.length <= 0 || arguments[0] === undefined ? "id" : arguments[0]; - var value = arguments.length <= 1 || arguments[1] === undefined ? "abc123" : arguments[1]; + value: function getServer(key, value) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; @@ -522,6 +542,12 @@ var Client = (function () { this.websocket.send(JSON.stringify(data)); } } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } }, { key: "ready", get: function get() { diff --git a/src/Client.js b/src/Client.js index 9642c78c4..314136ac9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -40,6 +40,13 @@ class Client { this.userCache = []; this.channelCache = []; this.serverCache = []; + this.readyTime = null; + } + + get uptime(){ + + return (this.readyTime ? Date.now() - this.readyTime : null); + } get ready() { @@ -194,6 +201,7 @@ class Client { } self.trigger("ready"); + self.readyTime = Date.now(); self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels and ${self.userCache.length} users.`); setInterval(function () { @@ -275,6 +283,28 @@ class Client { } break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if(channel){ + + var server = channel.server; + + if(server){ + + server.channels.splice( server.channels.indexOf(channel), 1 ); + + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice( self.serverCache.indexOf(channel), 1 ); + + } + + break; default: self.debug("received unknown packet"); @@ -332,7 +362,7 @@ class Client { } //def getServer - getServer(key = "id", value = "abc123") { + getServer(key, value) { for (var server of this.serverCache) { if (server[key] === value) { return server; diff --git a/test/bot.js b/test/bot.js index 3d87dccca..0ddda494d 100644 --- a/test/bot.js +++ b/test/bot.js @@ -11,7 +11,7 @@ mybot.on("ready", function(){ }) mybot.on("message", function(msg){ - console.log("Another message by "+msg.author.username+"... now I have "+mybot.messages.length); + console.log("Another message by "+msg.author.username+"... now I have "+mybot.messages.length + " I have been online for " + mybot.uptime); }) mybot.on("messageDelete", function(channel, message){ From dff1d267c055b3e0a9dd03e00aba29d1abedf60a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 22:41:57 +0100 Subject: [PATCH 024/191] watch channel/server create --- lib/Client.js | 167 +++++++++++++++++++++++++++++++++----------------- src/Client.js | 36 +++++++++++ 2 files changed, 147 insertions(+), 56 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index a707d366d..ef02342ad 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -375,6 +375,61 @@ var Client = (function () { break; + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + + var serv = self.addServer(data); + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var channel = _step5.value; + + serv.channels.push(self.addChannel(channel, serv.id)); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.channels.push(chann); + } + self.trigger("channelCreate", chann); + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); @@ -418,50 +473,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; - - try { - for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var user = _step5.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var channel = _step6.value; + for (var _iterator6 = this.userCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var user = _step6.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -482,20 +503,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer(key, value) { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { - for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var server = _step7.value; + for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var channel = _step7.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -516,6 +537,40 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = this.serverCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var server = _step8.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -573,27 +628,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; try { - for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var channel = _step8.value; + for (var _iterator9 = this.channelCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var channel = _step9.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError9 = true; + _iteratorError9 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError9) { + throw _iteratorError9; } } } diff --git a/src/Client.js b/src/Client.js index 314136ac9..b5ec12bc5 100644 --- a/src/Client.js +++ b/src/Client.js @@ -306,6 +306,42 @@ class Client { break; + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if(!server){ + //if server doesn't already exist because duh + + var serv = self.addServer(data); + + for (var channel of data.channels) { + serv.channels.push(self.addChannel(channel, serv.id)); + } + + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if(!channel){ + + var chann = self.addChannel( data, data.guild_id ); + var srv = self.getServer( "id", data.guild_id ); + if(srv){ + srv.channels.push( chann ); + } + self.trigger("channelCreate", chann); + + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); From 00fdad1ecd7ff54fc2da899e2ac50c5e72c3c9ca Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 22:51:43 +0100 Subject: [PATCH 025/191] Added user join/leave monitoring --- lib/Client.js | 34 ++++++++++++++++++++++++++++++++++ src/Client.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index ef02342ad..4c287a81d 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -430,6 +430,40 @@ var Client = (function () { break; + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user); + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/src/Client.js b/src/Client.js index b5ec12bc5..0eb3a0ed5 100644 --- a/src/Client.js +++ b/src/Client.js @@ -341,6 +341,40 @@ class Client { } break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if(server){ + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if( !~server.members.indexOf(user) ){ + server.members.push(user); + } + + self.trigger("serverNewMember", user); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if(server){ + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if( ~server.members.indexOf(user) ){ + server.members.splice( server.members.indexOf(user), 1 ); + } + + self.trigger("serverRemoveMember", user); + } + + break; default: self.debug("received unknown packet"); From 0da7945278a48da1374fb761a86c7aa6c2c1efda Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 22:56:51 +0100 Subject: [PATCH 026/191] added user update listener --- lib/Client.js | 17 +++++++++++++++++ src/Client.js | 18 ++++++++++++++++++ test/bot.js | 9 ++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/Client.js b/lib/Client.js index 4c287a81d..8293d5955 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -464,6 +464,23 @@ var Client = (function () { break; + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/src/Client.js b/src/Client.js index 0eb3a0ed5..34e411d11 100644 --- a/src/Client.js +++ b/src/Client.js @@ -376,6 +376,24 @@ class Client { break; + case "USER_UPDATE": + + if(self.user && data.id === self.user.id){ + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if( ~self.userCache.indexOf(self.user) ){ + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/test/bot.js b/test/bot.js index 0ddda494d..747e19fe0 100644 --- a/test/bot.js +++ b/test/bot.js @@ -24,4 +24,11 @@ mybot.on("messageUpdate", function(message, formerMessage){ console.log(message.author.username, "changed", formerMessage.content, "to", message.content); -}) \ No newline at end of file +}); + +mybot.on("serverNewMember", function(user){ + console.log("new user", user.username); +}); +mybot.on("serverRemoveMember", function(user){ + console.log("left user", user.username); +}); \ No newline at end of file From f2e3be0bade467d72ea092d9d1ca1c212a146a7b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 24 Aug 2015 23:05:13 +0100 Subject: [PATCH 027/191] Added full user tracking --- lib/Client.js | 24 ++++++++++++++++++++++++ lib/user.js | 5 +++++ src/Client.js | 24 ++++++++++++++++++++++++ src/user.js | 4 ++++ test/bot.js | 3 +++ 5 files changed, 60 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index 8293d5955..47bdd24f6 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -481,6 +481,30 @@ var Client = (function () { break; + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/lib/user.js b/lib/user.js index e4b6e682c..2f363dd1e 100644 --- a/lib/user.js +++ b/lib/user.js @@ -37,6 +37,11 @@ var User = (function () { value: function equals(object) { return object.id === this.id; } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } }, { key: "avatarURL", get: function get() { diff --git a/src/Client.js b/src/Client.js index 34e411d11..fafb277d9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -393,6 +393,30 @@ class Client { } break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if(userInCache){ + //user exists + var presenceUser = new User(data.user); + if(presenceUser.equalsStrict(userInCache)){ + //they're exactly the same, an actual presence update + self.trigger("presence", { + user : userInCache, + status : data.status, + server : self.getServer("id", data.guild_id), + gameId : data.game_id + }); + }else{ + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; default: self.debug("received unknown packet"); diff --git a/src/user.js b/src/user.js index b69896534..375ec7c60 100644 --- a/src/user.js +++ b/src/user.js @@ -30,6 +30,10 @@ class User{ equals(object){ return object.id === this.id; } + + equalsStrict(object){ + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } } module.exports = User; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index 747e19fe0..c78244192 100644 --- a/test/bot.js +++ b/test/bot.js @@ -31,4 +31,7 @@ mybot.on("serverNewMember", function(user){ }); mybot.on("serverRemoveMember", function(user){ console.log("left user", user.username); +}); +mybot.on("userUpdate", function(oldUser, newUser){ + console.log(oldUser, "vs", newUser); }); \ No newline at end of file From 15f995c07c01313c1d2fb499a798e63220aaddf7 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 11:49:59 +0100 Subject: [PATCH 028/191] Added promises and logout --- lib/Client.js | 54 +++++++----- src/Client.js | 227 ++++++++++++++++++++++++++++---------------------- test/bot.js | 36 ++++---- 3 files changed, 181 insertions(+), 136 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 47bdd24f6..af1e651f1 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -107,34 +107,50 @@ var Client = (function () { value: function login() { var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; - var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2]; var self = this; this.createws(); + return new Promise(function (resolve, reject) { + if (self.state === 0 || self.state === 4) { - if (this.state === 0 || this.state === 4) { + self.state = 1; //set the state to logging in - this.state = 1; //set the state to logging in + request.post(Endpoints.LOGIN).send({ + email: email, + password: password + }).end(function (err, res) { - request.post(Endpoints.LOGIN).send({ - email: email, - password: password - }).end(function (err, res) { + if (err) { + self.state = 4; //set state to disconnected + self.trigger("disconnected"); + self.websocket.close(); + reject(err); + } else { + self.state = 2; //set state to logged in (not yet ready) + self.token = res.body.token; //set our token + self.trySendConnData(); + resolve(self.token); + } + }); + } else { + reject(new Error("Client already logging in or ready")); + } + }); + } + }, { + key: "logout", + value: function logout() { - if (err) { - self.state = 4; //set state to disconnected - self.trigger("disconnected"); - self.websocket.close(); - callback(err); - } else { - self.state = 2; //set state to logged in (not yet ready) - self.token = res.body.token; //set our token - self.trySendConnData(); - callback(null, self.token); - } + var self = this; + + return new Promise(function (resolve, reject) { + + request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) { + + if (err) reject(err);else resolve(); }); - } + }); } //def createws diff --git a/src/Client.js b/src/Client.js index fafb277d9..a1f616832 100644 --- a/src/Client.js +++ b/src/Client.js @@ -42,11 +42,11 @@ class Client { this.serverCache = []; this.readyTime = null; } - - get uptime(){ - + + get uptime() { + return (this.readyTime ? Date.now() - this.readyTime : null); - + } get ready() { @@ -115,39 +115,64 @@ class Client { } //def login - login(email = "foo@bar.com", password = "pass1234", callback = function () { }) { + login(email = "foo@bar.com", password = "pass1234") { var self = this; this.createws(); + return new Promise(function (resolve, reject) { + if (self.state === 0 || self.state === 4) { + + self.state = 1; //set the state to logging in + + request + .post(Endpoints.LOGIN) + .send({ + email: email, + password: password + }).end(function (err, res) { - if (this.state === 0 || this.state === 4) { + if (err) { + self.state = 4; //set state to disconnected + self.trigger("disconnected"); + self.websocket.close(); + reject(err); + } else { + self.state = 2; //set state to logged in (not yet ready) + self.token = res.body.token; //set our token + self.trySendConnData(); + resolve(self.token); + } - this.state = 1; //set the state to logging in + }); + + }else{ + reject(new Error("Client already logging in or ready")); + } + }); + + } + + logout(){ + + var self = this; + + return new Promise(function(resolve, reject){ request - .post(Endpoints.LOGIN) - .send({ - email: email, - password: password - }).end(function (err, res) { - - if (err) { - self.state = 4; //set state to disconnected - self.trigger("disconnected"); - self.websocket.close(); - callback(err); - } else { - self.state = 2; //set state to logged in (not yet ready) - self.token = res.body.token; //set our token - self.trySendConnData(); - callback(null, self.token); - } - + .post(Endpoints.LOGOUT) + .set( "authorization", self.token ) + .end(function(err, res){ + + if(err) + reject(err); + else + resolve(); + }); - - } - + + }); + } //def createws @@ -274,148 +299,148 @@ class Client { break; case "GUILD_DELETE": - + var server = self.getServer("id", data.id); - - if(server){ + + if (server) { self.serverCache.splice(self.serverCache.indexOf(server), 1); self.trigger("serverDelete", server); } - + break; - + case "CHANNEL_DELETE": - + var channel = self.getChannel("id", data.id); - - if(channel){ - + + if (channel) { + var server = channel.server; - - if(server){ - - server.channels.splice( server.channels.indexOf(channel), 1 ); - + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } - + self.trigger("channelDelete", channel); - - self.serverCache.splice( self.serverCache.indexOf(channel), 1 ); - + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } - + break; case "GUILD_CREATE": - + var server = self.getServer("id", data.id); - - if(!server){ + + if (!server) { //if server doesn't already exist because duh var serv = self.addServer(data); - + for (var channel of data.channels) { serv.channels.push(self.addChannel(channel, serv.id)); } - + } - + self.trigger("serverCreate", server); - + break; - + case "CHANNEL_CREATE": - + var channel = self.getChannel("id", data.id); - - if(!channel){ - - var chann = self.addChannel( data, data.guild_id ); - var srv = self.getServer( "id", data.guild_id ); - if(srv){ - srv.channels.push( chann ); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.channels.push(chann); } self.trigger("channelCreate", chann); - + } - + break; - + case "GUILD_MEMBER_ADD": - + var server = self.getServer("id", data.guild_id); - - if(server){ - + + if (server) { + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. - if( !~server.members.indexOf(user) ){ + if (!~server.members.indexOf(user)) { server.members.push(user); } - + self.trigger("serverNewMember", user); } - + break; - + case "GUILD_MEMBER_REMOVE": - + var server = self.getServer("id", data.guild_id); - - if(server){ - + + if (server) { + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. - if( ~server.members.indexOf(user) ){ - server.members.splice( server.members.indexOf(user), 1 ); + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); } - + self.trigger("serverRemoveMember", user); } - + break; case "USER_UPDATE": - - if(self.user && data.id === self.user.id){ - + + if (self.user && data.id === self.user.id) { + var newUser = new User(data); //not actually adding to the cache self.trigger("userUpdate", newUser, self.user); - - if( ~self.userCache.indexOf(self.user) ){ + + if (~self.userCache.indexOf(self.user)) { self.userCache[self.userCache.indexOf(self.user)] = newUser; } - + self.user = newUser; - + } - + break; - + case "PRESENCE_UPDATE": - + var userInCache = self.getUser("id", data.user.id); - - if(userInCache){ + + if (userInCache) { //user exists var presenceUser = new User(data.user); - if(presenceUser.equalsStrict(userInCache)){ + if (presenceUser.equalsStrict(userInCache)) { //they're exactly the same, an actual presence update self.trigger("presence", { - user : userInCache, - status : data.status, - server : self.getServer("id", data.guild_id), - gameId : data.game_id + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id }); - }else{ + } else { //one of their details changed. self.trigger("userUpdate", userInCache, presenceUser); self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; } } - + break; default: diff --git a/test/bot.js b/test/bot.js index c78244192..101ea173a 100644 --- a/test/bot.js +++ b/test/bot.js @@ -2,36 +2,40 @@ var Discord = require("../lib/index.js"); var Auth = require("./auth.json"); var mybot = new Discord.Client(); -mybot.login(Auth.email, Auth.password, function(err, res){ - -}); +mybot.login(Auth.email+"a", Auth.password) -mybot.on("ready", function(){ + .then(function (token) { + console.log("wooo!"); + }).catch(function (error) { + console.log(error); + }); + +mybot.on("ready", function () { console.log("Ready!"); }) -mybot.on("message", function(msg){ - console.log("Another message by "+msg.author.username+"... now I have "+mybot.messages.length + " I have been online for " + mybot.uptime); +mybot.on("message", function (msg) { + console.log("Another message by " + msg.author.username + "... now I have " + mybot.messages.length + " I have been online for " + mybot.uptime); }) -mybot.on("messageDelete", function(channel, message){ - - console.log("MESSAGE WAS DELETED BY " + ( message ? message.author.username : channel.name )); - +mybot.on("messageDelete", function (channel, message) { + + console.log("MESSAGE WAS DELETED BY " + (message ? message.author.username : channel.name)); + }); -mybot.on("messageUpdate", function(message, formerMessage){ - +mybot.on("messageUpdate", function (message, formerMessage) { + console.log(message.author.username, "changed", formerMessage.content, "to", message.content); - + }); -mybot.on("serverNewMember", function(user){ +mybot.on("serverNewMember", function (user) { console.log("new user", user.username); }); -mybot.on("serverRemoveMember", function(user){ +mybot.on("serverRemoveMember", function (user) { console.log("left user", user.username); }); -mybot.on("userUpdate", function(oldUser, newUser){ +mybot.on("userUpdate", function (oldUser, newUser) { console.log(oldUser, "vs", newUser); }); \ No newline at end of file From fb3bdcf0793e86dc15f3bcefb002f2e200dab06d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 12:54:39 +0100 Subject: [PATCH 029/191] Added callback fallbacks, create server & channels --- lib/Client.js | 317 +++++++++++++++++++++++++++++--------------------- lib/server.js | 21 ++++ src/Client.js | 131 ++++++++++++++++----- src/server.js | 19 +++ test/bot.js | 17 ++- 5 files changed, 341 insertions(+), 164 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index af1e651f1..4424c114b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -107,6 +107,7 @@ var Client = (function () { value: function login() { var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2]; var self = this; @@ -125,11 +126,13 @@ var Client = (function () { self.state = 4; //set state to disconnected self.trigger("disconnected"); self.websocket.close(); + callback(err); reject(err); } else { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token self.trySendConnData(); + callback(null, self.token); resolve(self.token); } }); @@ -141,6 +144,7 @@ var Client = (function () { }, { key: "logout", value: function logout() { + var callback = arguments.length <= 0 || arguments[0] === undefined ? function (err) {} : arguments[0]; var self = this; @@ -148,7 +152,63 @@ var Client = (function () { request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) { - if (err) reject(err);else resolve(); + if (err) { + callback(err); + reject(err); + } else { + callback(null); + resolve(); + } + }); + }); + } + }, { + key: "createServer", + value: function createServer(name, region) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, server) {} : arguments[2]; + + var self = this; + return new Promise(function (resolve, reject) { + + request.post(Endpoints.SERVERS).set("authorization", self.token).send({ + name: name, + region: region + }).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var srv = self.addServer(res.body); + callback(null, srv); + resolve(srv); + } + }); + }); + } + }, { + key: "createChannel", + value: function createChannel(server, channelName, channelType) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, chann) {} : arguments[3]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization", self.token).send({ + name: channelName, + type: channelType + }).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var server = self.getServer("id", res.body.guild_id); + var chann = self.addChannel(res.body, res.body.guild_id); + server.addChannel(chann); + callback(null, chann); + resolve(chann); + } }); }); } @@ -205,31 +265,6 @@ var Client = (function () { var _server = _step.value; var server = self.addServer(_server); - - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = _server.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var channel = _step2.value; - - server.channels.push(self.addChannel(channel, server.id)); - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } } } catch (err) { _didIteratorError = true; @@ -259,27 +294,27 @@ var Client = (function () { self.debug("received message"); var mentions = []; - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; try { - for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; + for (var _iterator2 = data.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var mention = _step2.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; + _didIteratorError2 = true; + _iteratorError2 = err; } finally { try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); } } finally { - if (_didIteratorError3) { - throw _iteratorError3; + if (_didIteratorError2) { + throw _iteratorError2; } } } @@ -323,27 +358,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; try { - for (var _iterator4 = info.mentions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var mention = _step4.value; + for (var _iterator3 = info.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError3 = true; + _iteratorError3 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError3) { + throw _iteratorError3; } } } @@ -399,31 +434,6 @@ var Client = (function () { //if server doesn't already exist because duh var serv = self.addServer(data); - - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; - - try { - for (var _iterator5 = data.channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var channel = _step5.value; - - serv.channels.push(self.addChannel(channel, serv.id)); - } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } } self.trigger("serverCreate", server); @@ -439,7 +449,7 @@ var Client = (function () { var chann = self.addChannel(data, data.guild_id); var srv = self.getServer("id", data.guild_id); if (srv) { - srv.channels.push(chann); + srv.addChannel(chann); } self.trigger("channelCreate", chann); } @@ -554,26 +564,91 @@ var Client = (function () { }, { key: "addServer", value: function addServer(data) { - if (!this.getServer("id", data.id)) { - this.serverCache.push(new Server(data, this)); + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + if (data.channels) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var channel = _step4.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + this.serverCache.push(server); } - return this.getServer("id", data.id); + + return server; } //def getUser }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var user = _step5.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.userCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var user = _step6.value; + for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var channel = _step6.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -594,20 +669,20 @@ var Client = (function () { return null; } - //def getChannel + //def getServer }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getServer", + value: function getServer(key, value) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { - for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var channel = _step7.value; + for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var server = _step7.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -628,40 +703,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; - - try { - for (var _iterator8 = this.serverCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var server = _step8.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; - } finally { - try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); - } - } finally { - if (_didIteratorError8) { - throw _iteratorError8; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -688,6 +729,16 @@ var Client = (function () { this.websocket.send(JSON.stringify(data)); } } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } }, { key: "uptime", get: function get() { @@ -719,27 +770,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator9 = this.channelCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var channel = _step9.value; + for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError9) { - throw _iteratorError9; + if (_didIteratorError8) { + throw _iteratorError8; } } } diff --git a/lib/server.js b/lib/server.js index 3549683de..fe02e7256 100644 --- a/lib/server.js +++ b/lib/server.js @@ -19,6 +19,11 @@ var Server = (function () { this.afkTimeout = data.afk_timeout; this.afkChannelId = data.afk_channel_id; + if (!data.members) { + data.members = [client.user]; + return; + } + var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; @@ -116,6 +121,22 @@ var Server = (function () { return null; } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } }, { key: "iconURL", get: function get() { diff --git a/src/Client.js b/src/Client.js index a1f616832..b70fb476b 100644 --- a/src/Client.js +++ b/src/Client.js @@ -115,14 +115,14 @@ class Client { } //def login - login(email = "foo@bar.com", password = "pass1234") { + login(email = "foo@bar.com", password = "pass1234", callback = function(err, token){}) { var self = this; this.createws(); return new Promise(function (resolve, reject) { if (self.state === 0 || self.state === 4) { - + self.state = 1; //set the state to logging in request @@ -136,43 +136,104 @@ class Client { self.state = 4; //set state to disconnected self.trigger("disconnected"); self.websocket.close(); + callback(err); reject(err); } else { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token self.trySendConnData(); + callback(null, self.token); resolve(self.token); } }); - }else{ + } else { reject(new Error("Client already logging in or ready")); } }); } - - logout(){ - + + logout(callback = function(err){}) { + var self = this; - - return new Promise(function(resolve, reject){ - + + return new Promise(function (resolve, reject) { + request .post(Endpoints.LOGOUT) - .set( "authorization", self.token ) - .end(function(err, res){ - - if(err) + .set("authorization", self.token) + .end(function (err, res) { + + if (err){ + callback(err); reject(err); - else + }else{ + callback(null); resolve(); - + } }); - + }); - + + } + + createServer(name, region, callback = function(err, server){}) { + var self = this; + return new Promise(function (resolve, reject) { + + request + .post(Endpoints.SERVERS) + .set("authorization", self.token) + .send({ + name: name, + region: region + }) + .end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var srv = self.addServer(res.body); + callback(null, srv); + resolve(srv); + } + }); + + }); + } + + createChannel(server, channelName, channelType, callback = function(err, chann){}) { + + var self = this; + + return new Promise(function (resolve, reject) { + + request + .post(`${Endpoints.SERVERS}/${self.resolveServerID(server) }/channels`) + .set("authorization", self.token) + .send({ + name: channelName, + type: channelType + }) + .end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var server = self.getServer("id", res.body.guild_id); + var chann = self.addChannel(res.body, res.body.guild_id); + server.addChannel(chann); + callback(null, chann); + resolve(chann); + } + + }) + + }); + } //def createws @@ -220,10 +281,6 @@ class Client { var server = self.addServer(_server); - for (var channel of _server.channels) { - server.channels.push(self.addChannel(channel, server.id)); - } - } self.trigger("ready"); self.readyTime = Date.now(); @@ -340,10 +397,6 @@ class Client { var serv = self.addServer(data); - for (var channel of data.channels) { - serv.channels.push(self.addChannel(channel, serv.id)); - } - } self.trigger("serverCreate", server); @@ -359,7 +412,7 @@ class Client { var chann = self.addChannel(data, data.guild_id); var srv = self.getServer("id", data.guild_id); if (srv) { - srv.channels.push(chann); + srv.addChannel(chann); } self.trigger("channelCreate", chann); @@ -472,10 +525,20 @@ class Client { //def addServer addServer(data) { - if (!this.getServer("id", data.id)) { - this.serverCache.push(new Server(data, this)); + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + if (data.channels) { + for (var channel of data.channels) { + server.channels.push(this.addChannel(channel, server.id)); + } + } + this.serverCache.push(server); } - return this.getServer("id", data.id); + + return server; } //def getUser @@ -533,6 +596,16 @@ class Client { } } + resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + + } + } module.exports = Client; \ No newline at end of file diff --git a/src/server.js b/src/server.js index 322db6a44..259fe9bb5 100644 --- a/src/server.js +++ b/src/server.js @@ -11,6 +11,11 @@ class Server { this.afkTimeout = data.afk_timeout; this.afkChannelId = data.afk_channel_id; + if(!data.members){ + data.members = [ client.user ]; + return; + } + for (var member of data.members) { // first we cache the user in our Discord Client, @@ -64,6 +69,20 @@ class Server { return null; } + + addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + + addMember(member){ + if (!this.getMember("id", member.id)){ + this.members.push(member); + } + return member; + } } module.exports = Server; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index 101ea173a..89c1ed2ef 100644 --- a/test/bot.js +++ b/test/bot.js @@ -2,7 +2,7 @@ var Discord = require("../lib/index.js"); var Auth = require("./auth.json"); var mybot = new Discord.Client(); -mybot.login(Auth.email+"a", Auth.password) +mybot.login(Auth.email, Auth.password) .then(function (token) { console.log("wooo!"); @@ -12,6 +12,15 @@ mybot.login(Auth.email+"a", Auth.password) mybot.on("ready", function () { console.log("Ready!"); + + mybot.createServer("myServer", "london").then(function(server){ + console.log("New server! Based in "+server.region+" and is called "+server.name); + + mybot.createChannel(server, "wooof", "text", function(err, chann){ + console.log(chann.name); + }); + + }); }) mybot.on("message", function (msg) { @@ -38,4 +47,8 @@ mybot.on("serverRemoveMember", function (user) { }); mybot.on("userUpdate", function (oldUser, newUser) { console.log(oldUser, "vs", newUser); -}); \ No newline at end of file +}); + +mybot.on("channelCreate", function(chann){ + console.log(chann); +}) \ No newline at end of file From 659fdf5bff3a1d16137a13ecebbc2ff42b850f67 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 13:05:41 +0100 Subject: [PATCH 030/191] Added leave server --- lib/Client.js | 31 ++++++++++++++++++++++++++++--- src/Client.js | 47 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 4424c114b..97c8a52f6 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -212,6 +212,29 @@ var Client = (function () { }); }); } + }, { + key: "leaveServer", + value: function leaveServer(server) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization", self.token).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var srv = self.getServer("id", self.resolveServerID(server)); + callback(null, srv); + resolve(srv); + self.serverCache.splice(self.serverCache.indexOf(srv), 1); + } + }); + }); + } //def createws }, { @@ -294,6 +317,7 @@ var Client = (function () { self.debug("received message"); var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; @@ -320,9 +344,10 @@ var Client = (function () { } var channel = self.getChannel("id", data.channel_id); - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - - self.trigger("message", msg); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } break; case "MESSAGE_DELETE": diff --git a/src/Client.js b/src/Client.js index b70fb476b..9cb558cee 100644 --- a/src/Client.js +++ b/src/Client.js @@ -115,7 +115,7 @@ class Client { } //def login - login(email = "foo@bar.com", password = "pass1234", callback = function(err, token){}) { + login(email = "foo@bar.com", password = "pass1234", callback = function (err, token) { }) { var self = this; @@ -155,7 +155,7 @@ class Client { } - logout(callback = function(err){}) { + logout(callback = function (err) { }) { var self = this; @@ -166,10 +166,10 @@ class Client { .set("authorization", self.token) .end(function (err, res) { - if (err){ + if (err) { callback(err); reject(err); - }else{ + } else { callback(null); resolve(); } @@ -179,7 +179,7 @@ class Client { } - createServer(name, region, callback = function(err, server){}) { + createServer(name, region, callback = function (err, server) { }) { var self = this; return new Promise(function (resolve, reject) { @@ -204,7 +204,7 @@ class Client { }); } - createChannel(server, channelName, channelType, callback = function(err, chann){}) { + createChannel(server, channelName, channelType, callback = function (err, chann) { }) { var self = this; @@ -235,6 +235,33 @@ class Client { }); } + + leaveServer(server, callback = function (err, server) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + request + .del(`${Endpoints.SERVERS}/${self.resolveServerID(server) }`) + .set("authorization", self.token) + .end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var srv = self.getServer("id", self.resolveServerID(server)); + callback(null, srv); + resolve(srv); + self.serverCache.splice(self.serverCache.indexOf(srv), 1); + } + + }); + + }); + + } //def createws createws() { @@ -295,14 +322,16 @@ class Client { self.debug("received message"); 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); - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - - self.trigger("message", msg); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } break; case "MESSAGE_DELETE": From dd941ab604ba3fbdbb0156fd71a74343a568eb42 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 14:30:03 +0100 Subject: [PATCH 031/191] Fixed invites --- lib/Client.js | 202 ++++++++++++++++++++++++++++++++----------------- lib/channel.js | 114 ++++++++++++++-------------- lib/invite.js | 48 +++++++----- lib/server.js | 2 +- src/Client.js | 51 ++++++++++++- src/invite.js | 35 +++++---- src/server.js | 5 +- test/bot.js | 9 --- 8 files changed, 294 insertions(+), 172 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 97c8a52f6..6ff83fec1 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -10,6 +10,7 @@ var User = require("./User.js"); var Server = require("./Server.js"); var Channel = require("./Channel.js"); var Message = require("./Message.js"); +var Invite = require("./Invite.js"); //node modules var request = require("superagent"); @@ -235,6 +236,43 @@ var Client = (function () { }); }); } + }, { + key: "createInvite", + value: function createInvite(serverOrChannel, options) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, invite) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var destination; + + if (serverOrChannel instanceof Server) { + destination = serverOrChannel.id; + } else if (serverOrChannel instanceof Channel) { + destination = serverOrChannel.id; + } else { + destination = serverOrChannel; + } + + options = options || {}; + options.max_age = options.maxAge || 0; + options.max_uses = options.maxUses || 0; + options.temporary = options.temporary || false; + options.xkcdpass = options.xkcd || false; + + request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization", self.token).send(options).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var inv = new Invite(res.body, self); + callback(null, inv); + resolve(inv); + } + }); + }); + } //def createws }, { @@ -457,8 +495,36 @@ var Client = (function () { if (!server) { //if server doesn't already exist because duh - var serv = self.addServer(data); + } else if (server.channels.length === 0) { + + var srv = new Server(data, self); + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + channel = _step4.value; + + srv.channels.push(new Channel(channel, data.id)); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + self.serverCache[self.serverCache.indexOf(server)] = srv; } self.trigger("serverCreate", server); @@ -595,27 +661,27 @@ var Client = (function () { if (!server) { server = new Server(data, this); if (data.channels) { - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; try { - for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var channel = _step4.value; + for (var _iterator5 = data.channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var channel = _step5.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError5 = true; + _iteratorError5 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError5) { + throw _iteratorError5; } } } @@ -630,50 +696,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; - - try { - for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var user = _step5.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var channel = _step6.value; + for (var _iterator6 = this.userCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var user = _step6.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -694,20 +726,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer(key, value) { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { - for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var server = _step7.value; + for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var channel = _step7.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -728,6 +760,40 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = this.serverCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var server = _step8.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -795,27 +861,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; try { - for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var channel = _step8.value; + for (var _iterator9 = this.channelCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var channel = _step9.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError9 = true; + _iteratorError9 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError9) { + throw _iteratorError9; } } } diff --git a/lib/channel.js b/lib/channel.js index 8938e594a..d3c3d2dc7 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -5,70 +5,70 @@ 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 Channel = (function () { - function Channel(data, server) { - _classCallCheck(this, Channel); + function Channel(data, server) { + _classCallCheck(this, Channel); - this.server = server; - this.name = data.name; - this.type = data.type; - this.id = data.id; - this.messages = []; - //this.isPrivate = isPrivate; //not sure about the implementation of this... - } - - _createClass(Channel, [{ - key: "equals", - value: function equals(object) { - return object.id === this.id; + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... } - }, { - key: "addMessage", - value: function addMessage(data) { - if (!this.getMessage("id", data.id)) { - this.messages.push(data); - } - return this.getMessage("id", data.id); - } - }, { - key: "getMessage", - value: function getMessage(key, value) { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - try { - for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var message = _step.value; - - if (message[key] === value) { - return message; - } + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); } - } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; - return null; - } - }, { - key: "client", - get: function get() { - return this.server.client; - } - }]); + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; - return Channel; + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); + + return Channel; })(); module.exports = Channel; \ No newline at end of file diff --git a/lib/invite.js b/lib/invite.js index 359ac512b..cb8594af1 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -1,23 +1,37 @@ "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 User = require("./user.js").User; -exports.Invite = function (json) { +var Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); - this.max_age = json.max_age; - this.code = json.code; - this.server = json.guild; - this.revoked = json.revoked; - this.created_at = Date.parse(json.created_at); - this.temporary = json.temporary; - this.uses = json.uses; - this.max_uses = json.uses; - this.inviter = new User(json.inviter); - this.xkcdpass = json.xkcdpass; - this.channel = json.channel; -}; + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } -exports.Invite.prototype.generateInviteURL = function (xkcd) { - var code = xkcd ? this.xkcdpass : this.code; - return "https://discord.gg/" + code; -}; \ No newline at end of file + _createClass(Invite, [{ + key: "inviteURL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index fe02e7256..9c9903843 100644 --- a/lib/server.js +++ b/lib/server.js @@ -37,7 +37,7 @@ var Server = (function () { // get a user from this server's member list, // it will be identical (unless an async change occurred) // to the client's cache. - this.members.push(client.addUser(member.user)); + if (member.user) this.members.push(client.addUser(member.user)); } } catch (err) { _didIteratorError = true; diff --git a/src/Client.js b/src/Client.js index 9cb558cee..f59ff9dab 100644 --- a/src/Client.js +++ b/src/Client.js @@ -4,6 +4,7 @@ var User = require("./User.js"); var Server = require("./Server.js"); var Channel = require("./Channel.js"); var Message = require("./Message.js"); +var Invite = require("./Invite.js"); //node modules var request = require("superagent"); @@ -262,6 +263,46 @@ class Client { }); } + + createInvite(serverOrChannel, options, callback = function (err, invite) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + var destination; + + if (serverOrChannel instanceof Server) { + destination = serverOrChannel.id; + } else if (serverOrChannel instanceof Channel) { + destination = serverOrChannel.id; + } else { + destination = serverOrChannel; + } + + options = options || {}; + options.max_age = options.maxAge || 0; + options.max_uses = options.maxUses || 0; + options.temporary = options.temporary || false; + options.xkcdpass = options.xkcd || false; + + request + .post(`${Endpoints.CHANNELS}/${destination}/invites`) + .set("authorization", self.token) + .send(options) + .end(function (err, res) { + if(err){ + callback(err); + reject(err); + }else{ + var inv = new Invite(res.body, self); + callback(null, inv); + resolve(inv); + } + }); + }); + + } //def createws createws() { @@ -423,9 +464,15 @@ class Client { if (!server) { //if server doesn't already exist because duh - var serv = self.addServer(data); - + }else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + } self.trigger("serverCreate", server); diff --git a/src/invite.js b/src/invite.js index f2e10077a..08d414062 100644 --- a/src/invite.js +++ b/src/invite.js @@ -1,21 +1,24 @@ var User = require("./user.js").User; -exports.Invite = function(json){ +class Invite { + constructor(data, client) { + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } - this.max_age = json.max_age; - this.code = json.code; - this.server = json.guild; - this.revoked = json.revoked; - this.created_at = Date.parse(json.created_at); - this.temporary = json.temporary; - this.uses = json.uses; - this.max_uses = json.uses; - this.inviter = new User(json.inviter); - this.xkcdpass = json.xkcdpass; - this.channel = json.channel; + get inviteURL() { + var code = (this.xkcd ? this.xkcdpass : this.code); + return "https://discord.gg/" + code; + } } -exports.Invite.prototype.generateInviteURL = function(xkcd){ - var code = (xkcd ? this.xkcdpass : this.code); - return "https://discord.gg/"+code; -} +module.exports = Invite; \ No newline at end of file diff --git a/src/server.js b/src/server.js index 259fe9bb5..eba1b2e14 100644 --- a/src/server.js +++ b/src/server.js @@ -17,13 +17,14 @@ class Server { } for (var member of data.members) { - + // first we cache the user in our Discord Client, // then we add it to our list. This way when we // get a user from this server's member list, // it will be identical (unless an async change occurred) // to the client's cache. - this.members.push(client.addUser(member.user)); + if(member.user) + this.members.push(client.addUser(member.user)); } } diff --git a/test/bot.js b/test/bot.js index 89c1ed2ef..4a6de2d55 100644 --- a/test/bot.js +++ b/test/bot.js @@ -12,15 +12,6 @@ mybot.login(Auth.email, Auth.password) mybot.on("ready", function () { console.log("Ready!"); - - mybot.createServer("myServer", "london").then(function(server){ - console.log("New server! Based in "+server.region+" and is called "+server.name); - - mybot.createChannel(server, "wooof", "text", function(err, chann){ - console.log(chann.name); - }); - - }); }) mybot.on("message", function (msg) { From 4f179901c6809126b0e515af102651d91c4d2f96 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 14:42:38 +0100 Subject: [PATCH 032/191] Potential patch when calling create server, a partial server was returned. fixed that --- lib/Client.js | 188 ++++++++++++++++++++++++-------------------------- lib/invite.js | 2 +- src/Client.js | 19 +++-- src/invite.js | 2 +- 4 files changed, 106 insertions(+), 105 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 6ff83fec1..40803a1b6 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -39,6 +39,7 @@ var Client = (function () { this.events = new Map(); this.user = null; this.alreadySentData = false; + this.serverCreateListener = new Map(); /* State values: 0 - idle @@ -179,9 +180,13 @@ var Client = (function () { callback(err); reject(err); } else { - var srv = self.addServer(res.body); - callback(null, srv); - resolve(srv); + // potentially redundant in future + // creating here does NOT give us the channels of the server + // so we must wait for the guild_create event. + self.serverCreateListener.set(res.body.id, [resolve, callback]); + /*var srv = self.addServer(res.body); + callback(null, srv); + resolve(srv);*/ } }); }); @@ -495,36 +500,21 @@ var Client = (function () { if (!server) { //if server doesn't already exist because duh - var serv = self.addServer(data); - } else if (server.channels.length === 0) { + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ - var srv = new Server(data, self); - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - channel = _step4.value; - - srv.channels.push(new Channel(channel, data.id)); - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - self.serverCache[self.serverCache.indexOf(server)] = srv; + if (self.serverCreateListener.get(data.id)) { + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback } self.trigger("serverCreate", server); @@ -661,27 +651,27 @@ var Client = (function () { if (!server) { server = new Server(data, this); if (data.channels) { - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; try { - for (var _iterator5 = data.channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var channel = _step5.value; + for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var channel = _step4.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; + _didIteratorError4 = true; + _iteratorError4 = err; } finally { try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); } } finally { - if (_didIteratorError5) { - throw _iteratorError5; + if (_didIteratorError4) { + throw _iteratorError4; } } } @@ -696,16 +686,50 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var user = _step5.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = this.userCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var user = _step6.value; + for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var channel = _step6.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -726,20 +750,20 @@ var Client = (function () { return null; } - //def getChannel + //def getServer }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getServer", + value: function getServer(key, value) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { - for (var _iterator7 = this.channelCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var channel = _step7.value; + for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var server = _step7.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -760,40 +784,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; - - try { - for (var _iterator8 = this.serverCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var server = _step8.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; - } finally { - try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); - } - } finally { - if (_didIteratorError8) { - throw _iteratorError8; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -861,27 +851,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator9 = this.channelCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var channel = _step9.value; + for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError9) { - throw _iteratorError9; + if (_didIteratorError8) { + throw _iteratorError8; } } } diff --git a/lib/invite.js b/lib/invite.js index cb8594af1..6ce06bd04 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -24,7 +24,7 @@ var Invite = (function () { } _createClass(Invite, [{ - key: "inviteURL", + key: "URL", get: function get() { var code = this.xkcd ? this.xkcdpass : this.code; return "https://discord.gg/" + code; diff --git a/src/Client.js b/src/Client.js index f59ff9dab..156279419 100644 --- a/src/Client.js +++ b/src/Client.js @@ -29,6 +29,7 @@ class Client { this.events = new Map(); this.user = null; this.alreadySentData = false; + this.serverCreateListener = new Map(); /* State values: 0 - idle @@ -196,9 +197,13 @@ class Client { callback(err); reject(err); } else { - var srv = self.addServer(res.body); + // potentially redundant in future + // creating here does NOT give us the channels of the server + // so we must wait for the guild_create event. + self.serverCreateListener.set(res.body.id, [resolve, callback]); + /*var srv = self.addServer(res.body); callback(null, srv); - resolve(srv); + resolve(srv);*/ } }); @@ -464,8 +469,8 @@ class Client { if (!server) { //if server doesn't already exist because duh - var serv = self.addServer(data); - }else if(server.channels.length === 0){ + server = self.addServer(data); + }/*else if(server.channels.length === 0){ var srv = new Server(data, self); for(channel of data.channels){ @@ -473,6 +478,12 @@ class Client { } self.serverCache[self.serverCache.indexOf(server)] = srv; + }*/ + + if(self.serverCreateListener.get(data.id)){ + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback } self.trigger("serverCreate", server); diff --git a/src/invite.js b/src/invite.js index 08d414062..6880a834f 100644 --- a/src/invite.js +++ b/src/invite.js @@ -15,7 +15,7 @@ class Invite { this.channel = client.getChannel("id", data.channel.id); } - get inviteURL() { + get URL() { var code = (this.xkcd ? this.xkcdpass : this.code); return "https://discord.gg/" + code; } From 5f812f7c905121130ef4a4eeb8d48cf222b87493 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 15:44:18 +0100 Subject: [PATCH 033/191] added message sending and PM channel resolving --- lib/Client.js | 425 +++++++++++++++++++++++++++++++++++++---------- lib/PMChannel.js | 63 ++++++- src/Client.js | 161 +++++++++++++++++- src/PMChannel.js | 29 +++- test/bot.js | 8 +- 5 files changed, 579 insertions(+), 107 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 40803a1b6..798921293 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -11,6 +11,7 @@ var Server = require("./Server.js"); var Channel = require("./Channel.js"); var Message = require("./Message.js"); var Invite = require("./Invite.js"); +var PMChannel = require("./PMChannel.js"); //node modules var request = require("superagent"); @@ -52,6 +53,7 @@ var Client = (function () { this.userCache = []; this.channelCache = []; this.serverCache = []; + this.pmChannelCache = []; this.readyTime = null; } @@ -278,6 +280,186 @@ var Client = (function () { }); }); } + }, { + key: "startPM", + value: function startPM(user) { + + var self = this; + + return new Promise(function (resolve, reject) { + var userId = user; + if (user instanceof User) { + userId = user.id; + } + request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization", self.token).send({ + recipient_id: userId + }).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(self.addPMChannel(res.body)); + } + }); + }); + } + }, { + key: "sendMessage", + value: function sendMessage(destination, message) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + message = resolveMessage(message); + var mentions = resolveMentions(); + destination = resolveDestination(destination); + + if (destination) send(); + + function send() { + + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: message, + mentions: mentions + }).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + callback(null, msg); + resolve(msg); + } + } + }); + } + + function resolveDestination() { + var channId = false; + + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = self.pmChannelCache[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var pmc = _step2.value; + + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + self.startPM(destination).then(function (pmc) { + destination = pmc.id; + send(); + }); + } else { + channId = destination; + } + + return channId; + } + + function resolveMessage() { + var msg = message; + if (message instanceof Array) { + msg = message.join("\n"); + } + return msg; + } + + function resolveMentions() { + var _mentions = []; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + } //def createws }, { @@ -322,34 +504,59 @@ var Client = (function () { self.user = self.addUser(data.user); - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; try { - for (var _iterator = data.guilds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var _server = _step.value; + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; var server = self.addServer(_server); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _didIteratorError4 = true; + _iteratorError4 = err; } finally { try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); } } finally { - if (_didIteratorError) { - throw _iteratorError; + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; } } } self.trigger("ready"); self.readyTime = Date.now(); - self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels and " + self.userCache.length + " users."); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); setInterval(function () { self.keepAlive.apply(self); @@ -361,27 +568,27 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; try { - for (var _iterator2 = data.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var mention = _step2.value; + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; + _didIteratorError6 = true; + _iteratorError6 = err; } finally { try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); } } finally { - if (_didIteratorError2) { - throw _iteratorError2; + if (_didIteratorError6) { + throw _iteratorError6; } } } @@ -426,27 +633,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator3 = info.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError3) { - throw _iteratorError3; + if (_didIteratorError7) { + throw _iteratorError7; } } } @@ -640,6 +847,14 @@ var Client = (function () { } return this.getChannel("id", data.id); } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } //def addServer }, { @@ -651,27 +866,27 @@ var Client = (function () { if (!server) { server = new Server(data, this); if (data.channels) { - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator4 = data.channels[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var channel = _step4.value; + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError8) { + throw _iteratorError8; } } } @@ -686,29 +901,29 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; try { - for (var _iterator5 = this.userCache[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var user = _step5.value; + for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var user = _step9.value; if (user[key] === value) { return user; } } } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; + _didIteratorError9 = true; + _iteratorError9 = err; } finally { try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); } } finally { - if (_didIteratorError5) { - throw _iteratorError5; + if (_didIteratorError9) { + throw _iteratorError9; } } } @@ -720,29 +935,61 @@ var Client = (function () { }, { key: "getChannel", value: function getChannel(key, value) { - var _iteratorNormalCompletion6 = true; - var _didIteratorError6 = false; - var _iteratorError6 = undefined; + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; try { - for (var _iterator6 = this.channelCache[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var channel = _step6.value; + for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; if (channel[key] === value) { return channel; } } } catch (err) { - _didIteratorError6 = true; - _iteratorError6 = err; + _didIteratorError10 = true; + _iteratorError10 = err; } finally { try { - if (!_iteratorNormalCompletion6 && _iterator6["return"]) { - _iterator6["return"](); + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); } } finally { - if (_didIteratorError6) { - throw _iteratorError6; + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; } } } @@ -754,29 +1001,29 @@ var Client = (function () { }, { key: "getServer", value: function getServer(key, value) { - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; try { - for (var _iterator7 = this.serverCache[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var server = _step7.value; + for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var server = _step12.value; if (server[key] === value) { return server; } } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError12 = true; + _iteratorError12 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError12) { + throw _iteratorError12; } } } @@ -851,27 +1098,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; try { - for (var _iterator8 = this.channelCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var channel = _step8.value; + for (var _iterator13 = this.channelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var channel = _step13.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError13 = true; + _iteratorError13 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError13) { + throw _iteratorError13; } } } diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 31911a4d3..ae44d3d60 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -1,8 +1,61 @@ "use strict"; -var User = require("./user.js").User; +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; }; })(); -exports.PMChannel = function (user, id) { - this.user = new User(user); - this.id = id; -}; \ No newline at end of file +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index 156279419..f4f1ddbaa 100644 --- a/src/Client.js +++ b/src/Client.js @@ -5,6 +5,7 @@ var Server = require("./Server.js"); var Channel = require("./Channel.js"); var Message = require("./Message.js"); var Invite = require("./Invite.js"); +var PMChannel = require("./PMChannel.js"); //node modules var request = require("superagent"); @@ -42,6 +43,7 @@ class Client { this.userCache = []; this.channelCache = []; this.serverCache = []; + this.pmChannelCache = []; this.readyTime = null; } @@ -274,9 +276,9 @@ class Client { var self = this; return new Promise(function (resolve, reject) { - + var destination; - + if (serverOrChannel instanceof Server) { destination = serverOrChannel.id; } else if (serverOrChannel instanceof Channel) { @@ -296,10 +298,10 @@ class Client { .set("authorization", self.token) .send(options) .end(function (err, res) { - if(err){ + if (err) { callback(err); reject(err); - }else{ + } else { var inv = new Invite(res.body, self); callback(null, inv); resolve(inv); @@ -308,6 +310,132 @@ class Client { }); } + + startPM(user) { + + var self = this; + + return new Promise(function (resolve, reject) { + var userId = user; + if (user instanceof User) { + userId = user.id; + } + request + .post(`${Endpoints.USERS}/${self.user.id}/channels`) + .set("authorization", self.token) + .send({ + recipient_id: userId + }) + .end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(self.addPMChannel(res.body)); + } + }); + }); + + } + + sendMessage(destination, message, callback = function (err, msg) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + message = resolveMessage(message); + var mentions = resolveMentions(); + destination = resolveDestination(destination); + + if (destination) + send(); + + function send() { + + request + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .send({ + content: message, + mentions: mentions + }) + .end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var data = res.body; + + 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); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + callback(null, msg); + resolve(msg); + } + } + + }); + + } + + function resolveDestination() { + var channId = false; + + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + for (var pmc of self.pmChannelCache) { + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + self.startPM(destination).then(function (pmc) { + destination = pmc.id; + send(); + }); + + } else { + channId = destination; + } + + return channId; + } + + function resolveMessage() { + var msg = message; + if (message instanceof Array) { + msg = message.join("\n"); + } + return msg; + } + + function resolveMentions() { + var _mentions = []; + for (var mention of (message.match(/<@[^>]*>/g) || [])) { + _mentions.push(mention.substring(2, mention.length - 1)); + } + return _mentions; + } + + }); + } //def createws createws() { @@ -355,9 +483,14 @@ class Client { var server = self.addServer(_server); } + + for (var _pmc of data.private_channels) { + var pmc = self.addPMChannel(_pmc); + } + self.trigger("ready"); self.readyTime = Date.now(); - self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels and ${self.userCache.length} users.`); + self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels, ${self.pmChannelCache.length} PMs and ${self.userCache.length} users.`); setInterval(function () { self.keepAlive.apply(self); @@ -480,7 +613,7 @@ class Client { }*/ - if(self.serverCreateListener.get(data.id)){ + if (self.serverCreateListener.get(data.id)) { var cbs = self.serverCreateListener.get(data.id); cbs[0](server); //promise then callback cbs[1](null, server); //legacy callback @@ -609,6 +742,13 @@ class Client { } return this.getChannel("id", data.id); } + + addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } //def addServer addServer(data) { @@ -645,6 +785,15 @@ class Client { return channel; } } + return this.getPMChannel(key, value); //might be a PM + } + + getPMChannel(key, value) { + for (var channel of this.pmChannelCache) { + if (channel[key] === value) { + return channel; + } + } return null; } diff --git a/src/PMChannel.js b/src/PMChannel.js index 1bfe3c155..6b069d50b 100644 --- a/src/PMChannel.js +++ b/src/PMChannel.js @@ -1,6 +1,25 @@ -var User = require("./user.js").User; - -exports.PMChannel = function(user, id){ - this.user = new User(user); - this.id = id; +class PMChannel { + constructor(data, client) { + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + addMessage(data){ + if(!this.getMessage("id", data.id)){ + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + + getMessage(key, value){ + for(var message of this.messages){ + if(message[key] === value){ + return message; + } + } + return null; + } } + +module.exports = PMChannel; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index 4a6de2d55..59e4783c3 100644 --- a/test/bot.js +++ b/test/bot.js @@ -15,8 +15,12 @@ mybot.on("ready", function () { }) mybot.on("message", function (msg) { - console.log("Another message by " + msg.author.username + "... now I have " + mybot.messages.length + " I have been online for " + mybot.uptime); -}) + + if(msg.content === "pmme"){ + mybot.sendMessage(msg.channel, "You know what "+msg.sender+"? NO"); + } + +}); mybot.on("messageDelete", function (channel, message) { From b47d62b151bec3efb7e3da6fb8515c1fdb9db4ff Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 16:38:35 +0100 Subject: [PATCH 034/191] Added reply --- lib/Client.js | 16 +++++++++++++++- src/Client.js | 17 +++++++++++++++-- test/bot.js | 3 ++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 798921293..19f45dd46 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -302,16 +302,30 @@ var Client = (function () { }); }); } + }, { + key: "reply", + value: function reply(destination, message) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (response, reject) { + + var user = destination.sender; + self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); + }); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3]; var self = this; return new Promise(function (resolve, reject) { - message = resolveMessage(message); + message = premessage + resolveMessage(message); var mentions = resolveMentions(); destination = resolveDestination(destination); diff --git a/src/Client.js b/src/Client.js index f4f1ddbaa..867510574 100644 --- a/src/Client.js +++ b/src/Client.js @@ -336,14 +336,27 @@ class Client { }); } + + reply(destination, message, callback = function(err, msg){}){ + + var self = this; + + return new Promise(function(response, reject){ + + var user = destination.sender; + self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject); + + }); + + } - sendMessage(destination, message, callback = function (err, msg) { }) { + sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { var self = this; return new Promise(function (resolve, reject) { - message = resolveMessage(message); + message = premessage + resolveMessage(message); var mentions = resolveMentions(); destination = resolveDestination(destination); diff --git a/test/bot.js b/test/bot.js index 59e4783c3..881d9f0fc 100644 --- a/test/bot.js +++ b/test/bot.js @@ -17,7 +17,8 @@ mybot.on("ready", function () { mybot.on("message", function (msg) { if(msg.content === "pmme"){ - mybot.sendMessage(msg.channel, "You know what "+msg.sender+"? NO"); + console.log("yes we found it!"); + mybot.reply(msg, "You know what "+msg.sender+"? NO"); } }); From 8eb1afa371d91cb34cd4ed5733e338e9dee3a127 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 16:59:11 +0100 Subject: [PATCH 035/191] Added message deletion --- lib/Client.js | 27 +++++++++++++++++++++++++++ src/Client.js | 44 ++++++++++++++++++++++++++++++++++++-------- test/bot.js | 4 +++- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 19f45dd46..3b362da83 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -315,6 +315,33 @@ var Client = (function () { self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); }); } + }, { + key: "deleteMessage", + value: function deleteMessage(message, timeout) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + if (timeout) { + setTimeout(remove, timeout); + } else { + remove(); + } + + function remove() { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + callback(null, message); + resolve(message); + } + }); + } + }); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { diff --git a/src/Client.js b/src/Client.js index 867510574..be3230c74 100644 --- a/src/Client.js +++ b/src/Client.js @@ -336,18 +336,46 @@ class Client { }); } - - reply(destination, message, callback = function(err, msg){}){ - + + reply(destination, message, callback = function (err, msg) { }) { + var self = this; - - return new Promise(function(response, reject){ - + + return new Promise(function (response, reject) { + var user = destination.sender; self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject); - + + }); + + } + + deleteMessage(message, timeout, callback = function (err, msg) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + if (timeout) { + setTimeout(remove, timeout) + }else{ + remove(); + } + + function remove() { + request + .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) + .set("authorization", self.token) + .end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + callback(null, message); + resolve(message); + } + }); + } }); - } sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { diff --git a/test/bot.js b/test/bot.js index 881d9f0fc..a142d5861 100644 --- a/test/bot.js +++ b/test/bot.js @@ -18,7 +18,9 @@ mybot.on("message", function (msg) { if(msg.content === "pmme"){ console.log("yes we found it!"); - mybot.reply(msg, "You know what "+msg.sender+"? NO"); + mybot.reply(msg, "You know what "+msg.sender+"? NO").then(function(msg){ + mybot.deleteMessage(msg, 5000); + }); } }); From ab424ce4a40797e36d8b979c5f48d97ef2a9a71d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 17:32:49 +0100 Subject: [PATCH 036/191] Added username changing --- lib/Client.js | 53 +++++++++++++++++++++++++++++++++++++++++++ src/Client.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++- test/bot.js | 5 +++- 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 3b362da83..d01e87163 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -41,6 +41,10 @@ var Client = (function () { this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); + + this.email = "abc"; + this.password = "abc"; + /* State values: 0 - idle @@ -121,6 +125,9 @@ var Client = (function () { self.state = 1; //set the state to logging in + self.email = email; + self.password = password; + request.post(Endpoints.LOGIN).send({ email: email, password: password @@ -342,6 +349,52 @@ var Client = (function () { } }); } + }, { + key: "updateMessage", + value: function updateMessage(message, content) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + callback(null, msg); + resolve(msg); + + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "setUsername", + value: function setUsername(newName) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({ + avatar: self.user.avatar, + email: self.email, + new_password: null, + password: self.password, + username: newName + }).end(function (err) { + callback(err); + if (err) reject(err);else resolve(); + }); + }); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { diff --git a/src/Client.js b/src/Client.js index be3230c74..d77434a9d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -31,6 +31,10 @@ class Client { this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); + + this.email = "abc"; + this.password = "abc"; + /* State values: 0 - idle @@ -128,6 +132,9 @@ class Client { if (self.state === 0 || self.state === 4) { self.state = 1; //set the state to logging in + + self.email = email; + self.password = password; request .post(Endpoints.LOGIN) @@ -357,7 +364,7 @@ class Client { return new Promise(function (resolve, reject) { if (timeout) { setTimeout(remove, timeout) - }else{ + } else { remove(); } @@ -378,6 +385,60 @@ class Client { }); } + updateMessage(message, content, callback = function (err, msg) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + request + .patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) + .set("authorization", self.token) + .send({ + content: content, + mentions: [] + }) + .end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + callback(null, msg); + resolve(msg); + + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + + }); + } + + setUsername(newName, callback = function (err) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + request + .patch(`${Endpoints.API}/users/@me`) + .set("authorization", self.token) + .send({ + avatar: self.user.avatar, + email: self.email, + new_password: null, + password: self.password, + username: newName + }) + .end(function (err) { + callback(err); + if (err) + reject(err); + else + resolve(); + }); + }); + } + sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { var self = this; diff --git a/test/bot.js b/test/bot.js index a142d5861..0b591439d 100644 --- a/test/bot.js +++ b/test/bot.js @@ -18,8 +18,11 @@ mybot.on("message", function (msg) { if(msg.content === "pmme"){ console.log("yes we found it!"); + mybot.setUsername("hydrabot").catch(function(err){ + console.log(err); + }); mybot.reply(msg, "You know what "+msg.sender+"? NO").then(function(msg){ - mybot.deleteMessage(msg, 5000); + mybot.updateMessage(msg, "wat"); }); } From dea786d90ade6dbc483a0bd5f0c53fcb6fa483b6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 18:56:56 +0100 Subject: [PATCH 037/191] added log retrieval --- lib/Client.js | 438 ++++++++++++++++++++++++++++++-------------------- src/Client.js | 51 +++++- test/bot.js | 7 +- 3 files changed, 315 insertions(+), 181 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index d01e87163..35ad91bfa 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -395,6 +395,90 @@ var Client = (function () { }); }); } + }, { + key: "getChannelLogs", + value: function getChannelLogs(channel) { + var amount = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1]; + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, logs) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", self.token).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var logs = []; + + var channel = self.getChannel("id", channelID); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = res.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + var mentions = []; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = message.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var mention = _step2.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + var author = self.addUser(message.author); + + logs.push(new Message(message, channel, mentions, author)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + callback(null, logs); + resolve(logs); + } + }); + }); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { @@ -428,27 +512,27 @@ var Client = (function () { data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; try { - for (var _iterator = data.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var mention = _step.value; + for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _didIteratorError3 = true; + _iteratorError3 = err; } finally { try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); } } finally { - if (_didIteratorError) { - throw _iteratorError; + if (_didIteratorError3) { + throw _iteratorError3; } } } @@ -475,13 +559,13 @@ var Client = (function () { } else if (destination instanceof User) { //check if we have a PM - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; try { - for (var _iterator2 = self.pmChannelCache[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var pmc = _step2.value; + for (var _iterator4 = self.pmChannelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var pmc = _step4.value; if (pmc.user.equals(destination)) { return pmc.id; @@ -490,16 +574,16 @@ var Client = (function () { //we don't, at this point we're late } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; + _didIteratorError4 = true; + _iteratorError4 = err; } finally { try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); } } finally { - if (_didIteratorError2) { - throw _iteratorError2; + if (_didIteratorError4) { + throw _iteratorError4; } } } @@ -525,27 +609,27 @@ var Client = (function () { function resolveMentions() { var _mentions = []; - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; try { - for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; + for (var _iterator5 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var mention = _step5.value; _mentions.push(mention.substring(2, mention.length - 1)); } } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; + _didIteratorError5 = true; + _iteratorError5 = err; } finally { try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); } } finally { - if (_didIteratorError3) { - throw _iteratorError3; + if (_didIteratorError5) { + throw _iteratorError5; } } } @@ -598,52 +682,52 @@ var Client = (function () { self.user = self.addUser(data.user); - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; try { - for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var _server = _step4.value; + for (var _iterator6 = data.guilds[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var _server = _step6.value; var server = self.addServer(_server); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError6 = true; + _iteratorError6 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError6) { + throw _iteratorError6; } } } - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var _pmc = _step5.value; + for (var _iterator7 = data.private_channels[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var _pmc = _step7.value; var pmc = self.addPMChannel(_pmc); } } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError5) { - throw _iteratorError5; + if (_didIteratorError7) { + throw _iteratorError7; } } } @@ -662,27 +746,27 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion6 = true; - var _didIteratorError6 = false; - var _iteratorError6 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var mention = _step6.value; + for (var _iterator8 = data.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var mention = _step8.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError6 = true; - _iteratorError6 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion6 && _iterator6["return"]) { - _iterator6["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError6) { - throw _iteratorError6; + if (_didIteratorError8) { + throw _iteratorError8; } } } @@ -727,27 +811,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; try { - for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var mention = _step7.value; + for (var _iterator9 = info.mentions[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var mention = _step9.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError9 = true; + _iteratorError9 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError9) { + throw _iteratorError9; } } } @@ -959,33 +1043,33 @@ var Client = (function () { if (!server) { server = new Server(data, this); + this.serverCache.push(server); if (data.channels) { - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; try { - for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var channel = _step8.value; + for (var _iterator10 = data.channels[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError10 = true; + _iteratorError10 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError10) { + throw _iteratorError10; } } } } - this.serverCache.push(server); } return server; @@ -995,82 +1079,16 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; - - try { - for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var user = _step9.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; - } finally { - try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); - } - } finally { - if (_didIteratorError9) { - throw _iteratorError9; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { - var _iteratorNormalCompletion10 = true; - var _didIteratorError10 = false; - var _iteratorError10 = undefined; - - try { - for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var channel = _step10.value; - - if (channel[key] === value) { - return channel; - } - } - } catch (err) { - _didIteratorError10 = true; - _iteratorError10 = err; - } finally { - try { - if (!_iteratorNormalCompletion10 && _iterator10["return"]) { - _iterator10["return"](); - } - } finally { - if (_didIteratorError10) { - throw _iteratorError10; - } - } - } - - return this.getPMChannel(key, value); //might be a PM - } - }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { - for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { - var channel = _step11.value; + for (var _iterator11 = this.userCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var user = _step11.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -1091,20 +1109,20 @@ var Client = (function () { return null; } - //def getServer + //def getChannel }, { - key: "getServer", - value: function getServer(key, value) { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { - for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { - var server = _step12.value; + for (var _iterator12 = this.channelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -1122,6 +1140,72 @@ var Client = (function () { } } + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var channel = _step13.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = this.serverCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var server = _step14.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + return null; } @@ -1192,27 +1276,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion13 = true; - var _didIteratorError13 = false; - var _iteratorError13 = undefined; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; try { - for (var _iterator13 = this.channelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var channel = _step13.value; + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError13 = true; - _iteratorError13 = err; + _didIteratorError15 = true; + _iteratorError15 = err; } finally { try { - if (!_iteratorNormalCompletion13 && _iterator13["return"]) { - _iterator13["return"](); + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); } } finally { - if (_didIteratorError13) { - throw _iteratorError13; + if (_didIteratorError15) { + throw _iteratorError15; } } } diff --git a/src/Client.js b/src/Client.js index d77434a9d..1ac97e4ad 100644 --- a/src/Client.js +++ b/src/Client.js @@ -31,7 +31,7 @@ class Client { this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); - + this.email = "abc"; this.password = "abc"; @@ -135,7 +135,7 @@ class Client { self.email = email; self.password = password; - + request .post(Endpoints.LOGIN) .send({ @@ -439,6 +439,51 @@ class Client { }); } + getChannelLogs(channel, amount = 500, callback = function (err, logs) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request + .get(`${Endpoints.CHANNELS}/${channelID}/messages?limit=${amount}`) + .set("authorization", self.token) + .end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var logs = []; + + var channel = self.getChannel("id", channelID); + + for (var message of res.body) { + + var mentions = []; + for(var mention of message.mentions){ + mentions.push( self.addUser(mention) ); + } + + var author = self.addUser(message.author); + + logs.push(new Message(message, channel, mentions, author)); + } + callback(null, logs); + resolve(logs); + } + + }); + + }); + + } + sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { var self = this; @@ -859,12 +904,12 @@ class Client { if (!server) { server = new Server(data, this); + this.serverCache.push(server); if (data.channels) { for (var channel of data.channels) { server.channels.push(this.addChannel(channel, server.id)); } } - this.serverCache.push(server); } return server; diff --git a/test/bot.js b/test/bot.js index 0b591439d..30b8dbacb 100644 --- a/test/bot.js +++ b/test/bot.js @@ -22,7 +22,12 @@ mybot.on("message", function (msg) { console.log(err); }); mybot.reply(msg, "You know what "+msg.sender+"? NO").then(function(msg){ - mybot.updateMessage(msg, "wat"); + mybot.updateMessage(msg, "wat i sed nothin m8"); + }); + mybot.getChannelLogs(msg.channel).then(function(logs){ + console.log(logs[0]); + }).catch(function(error){ + console.log(error); }); } From 8337e3d5405e0d3b807bdb81ba200afcb34ecaf7 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 19:06:52 +0100 Subject: [PATCH 038/191] Finalised ec6 rewrite! woo! --- lib/Client.js | 47 ++++++++++++++++++++++++++++++++++++ src/Client.js | 67 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 35ad91bfa..68bbfb3dc 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -479,6 +479,52 @@ var Client = (function () { }); }); } + }, { + key: "deleteChannel", + value: function deleteChannel(channel) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", self.token).end(function (err) { + if (err) { + callback(err); + reject(err); + } else { + callback(null); + resolve(); + } + }); + }); + } + }, { + key: "joinServer", + value: function joinServer(invite) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var id = invite instanceof Invite ? invite.code : invite; + + request.post(Endpoints.API + "/invite/" + id).set("authorization", self.token).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } + }); + }); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { @@ -900,6 +946,7 @@ var Client = (function () { var cbs = self.serverCreateListener.get(data.id); cbs[0](server); //promise then callback cbs[1](null, server); //legacy callback + self.serverCreateListener["delete"](data.id); } self.trigger("serverCreate", server); diff --git a/src/Client.js b/src/Client.js index 1ac97e4ad..4338a1cce 100644 --- a/src/Client.js +++ b/src/Client.js @@ -460,18 +460,18 @@ class Client { reject(err); } else { var logs = []; - + var channel = self.getChannel("id", channelID); - + for (var message of res.body) { - + var mentions = []; - for(var mention of message.mentions){ - mentions.push( self.addUser(mention) ); + for (var mention of message.mentions) { + mentions.push(self.addUser(mention)); } - + var author = self.addUser(message.author); - + logs.push(new Message(message, channel, mentions, author)); } callback(null, logs); @@ -484,6 +484,58 @@ class Client { } + deleteChannel(channel, callback = function (err) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request + .del(`${Endpoints.CHANNELS}/${channelID}`) + .set("authorization", self.token) + .end(function (err) { + if (err) { + callback(err); + reject(err); + } else { + callback(null); + resolve(); + } + }); + + }); + + } + + joinServer(invite, callback = function (err, server) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + var id = (invite instanceof Invite ? invite.code : invite); + + request + .post(`${Endpoints.API}/invite/${id}`) + .set("authorization", self.token) + .end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } + }); + + }); + + } + sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { var self = this; @@ -764,6 +816,7 @@ class Client { var cbs = self.serverCreateListener.get(data.id); cbs[0](server); //promise then callback cbs[1](null, server); //legacy callback + self.serverCreateListener.delete(data.id); } self.trigger("serverCreate", server); From 8254b916e18bdcc58583ed0a61a90ba0ff39e6f0 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 21:59:44 +0100 Subject: [PATCH 039/191] Patches --- lib/Client.js | 17 ++-- src/Client.js | 16 ++-- src/list.js | 248 -------------------------------------------------- 3 files changed, 21 insertions(+), 260 deletions(-) delete mode 100644 src/list.js diff --git a/lib/Client.js b/lib/Client.js index 68bbfb3dc..a0a343444 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -167,7 +167,8 @@ var Client = (function () { callback(err); reject(err); } else { - callback(null); + self.state = 4; + callback(); resolve(); } }); @@ -242,10 +243,9 @@ var Client = (function () { callback(err); reject(err); } else { - var srv = self.getServer("id", self.resolveServerID(server)); - callback(null, srv); - resolve(srv); - self.serverCache.splice(self.serverCache.indexOf(srv), 1); + self.serverCache.splice(self.serverCache.indexOf(server), 1); + callback(null); + resolve(); } }); }); @@ -781,7 +781,7 @@ var Client = (function () { self.trigger("ready"); self.readyTime = Date.now(); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); - + self.state = 3; setInterval(function () { self.keepAlive.apply(self); }, data.heartbeat_interval); @@ -1318,6 +1318,11 @@ var Client = (function () { get: function get() { return this.userCache; } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } }, { key: "messages", get: function get() { diff --git a/src/Client.js b/src/Client.js index 4338a1cce..0b7163c0a 100644 --- a/src/Client.js +++ b/src/Client.js @@ -72,6 +72,10 @@ class Client { get users() { return this.userCache; } + + get PMChannels() { + return this.pmChannelCache; + } get messages() { @@ -181,7 +185,8 @@ class Client { callback(err); reject(err); } else { - callback(null); + self.state = 4; + callback(); resolve(); } }); @@ -266,10 +271,9 @@ class Client { callback(err); reject(err); } else { - var srv = self.getServer("id", self.resolveServerID(server)); - callback(null, srv); - resolve(srv); - self.serverCache.splice(self.serverCache.indexOf(srv), 1); + self.serverCache.splice(self.serverCache.indexOf(server), 1); + callback(null); + resolve(); } }); @@ -690,7 +694,7 @@ class Client { self.trigger("ready"); self.readyTime = Date.now(); self.debug(`cached ${self.serverCache.length} servers, ${self.channelCache.length} channels, ${self.pmChannelCache.length} PMs and ${self.userCache.length} users.`); - + self.state = 3; setInterval(function () { self.keepAlive.apply(self); }, data.heartbeat_interval); diff --git a/src/list.js b/src/list.js deleted file mode 100644 index 5ad268523..000000000 --- a/src/list.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Similar to a Java set. Contains no duplicate elements and includes filter - * functions. Discriminates between elements based on a discriminator passed - * when created. Generally "ID" - * @class List - */ -exports.List = function( discriminator, cap ) { - /** - * What to use to distringuish duplicates - * @attribute discriminator - * @type {String} - */ - this.discriminator = discriminator; - /** - * The maximum amount of elements allowed in the list. - * @default Infinity - * @attribute cap - * @type {Number} - */ - this.cap = cap || Number.MAX_SAFE_INTEGER; - /** - * The Array version of the List. - * @type {Array} - * @attribute contents - */ - this.contents = []; -} - -/** - * Adds an element to the list if it isn't already there. - * @method add - * @param {Object/Array} element The element(s) to add - * @example - * List.add( obj ); - * List.add( [ obj, obj, obj ] ); - */ -exports.List.prototype.add = function( child ) { - - var self = this; - - if ( child.constructor === Array ) { - - children = child; - for ( child of children ) { - addChild( child ); - } - - } else { - addChild( child ); - } - - function addChild( child ) { - - if ( self.length() > self.cap ) { - self.splice( 0, 1 ); - } - - if ( self.filter( self.discriminator, child[ self.discriminator ] ).length() === 0 ) - self.contents.push( child ); - } -} - -/** - * Returns the length of the List - * @method length - * @return {Number} - */ -exports.List.prototype.length = function() { - return this.contents.length; -} - -/** - * Gets the index of an element in the List or defaults to false - * @param {Object} object The element we want to get the index of - * @return {Number/Boolean} The index if the object is in the list, or false. - * @method getIndex - */ -exports.List.prototype.getIndex = function( object ) { - - var index = false; - - for ( elementIndex in this.contents ) { - var element = this.contents[ elementIndex ]; - if ( element[ this.discriminator ] == object[ this.discriminator ] ) { - return elementIndex; - } - - } - - return index; - -} - -/** - * Removes an element at the specified index - * @param {Number} index - * @method removeIndex - */ -exports.List.prototype.removeIndex = function( index ) { - this.contents.splice( index, 1 ); -} - -/** - * Removes an element from the list - * @param {Object} element - * @method removeElement - * @return {Boolean} whether the operation was successful or not. - */ -exports.List.prototype.removeElement = function( child ) { - - for ( _element in this.contents ) { - var element = this.contents[ _element ]; - if ( child[ this.discriminator ] == element[ this.discriminator ] ) { - this.removeIndex( _element, 1 ); - return true; - } - } - - return false; -} - -/** - * Replaces an element in the list with a specified element - * @method updateElement - * @param {Object} element Element to update. - * @param {Object} newElement New Element - * @return {Boolean} whether the operation was successful or not. - */ -exports.List.prototype.updateElement = function( child, newChild ) { - - for ( _element in this.contents ) { - var element = this.contents[ _element ]; - if ( child[ this.discriminator ] == element[ this.discriminator ] ) { - this.contents[ _element ] = newChild; - return true; - } - } - - return false; - -} - -exports.List.prototype.concatSublists = function( whereList, discriminator ) { - //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values. - - var concatList = new exports.List( discriminator ); - - for ( item of this.contents ) { - var itemList = item[ whereList ]; - concatList.add( itemList.contents ); - } - - return concatList; -} - -exports.List.prototype.filter = function( key, value, onlyOne, caseInsen ) { - - var results = []; - - value = change( value ); - - for ( index in this.contents ) { - var child = this.contents[ index ]; - if ( change( child[ key ] ) == value ) { - if ( onlyOne ) { - return child; - } else { - results.push( child ); - } - } - } - - function change( val ) { - if ( caseInsen ) { - val = val.toUpperCase(); - } - return val; - } - - if ( onlyOne ) { - return false; - } - - var retList = new exports.List( this.discriminator ); - retList.contents = results; - - return retList; -} - -exports.List.prototype.getValues = function( key ){ - - var valList = []; - for( child of this.contents){ - valList.push( child[key] ); - } - return valList; - -} - -exports.List.prototype.deepFilter = function( keys, value, onlyOne, caseInsen ) { - - var results = []; - - value = change( value ); - - for ( index in this.contents ) { - var child = this.contents[ index ]; - var buffer = child; - - for ( key of keys ) { - if(buffer instanceof exports.List){ - buffer = buffer.contents; - } - if(buffer instanceof Array){ - for(elem of buffer){ - if( change(elem[key]) == value ){ - buffer = elem; - } - } - } - buffer = buffer[ key ]; - } - - if ( change( buffer ) == value ) { - if ( onlyOne ) { - return child; - } else { - results.push( child ); - } - } - } - - function change( val ) { - if ( caseInsen ) { - val = val.toUpperCase(); - } - return val; - } - - if ( onlyOne ) { - return false; - } - - var retList = new exports.List( this.discriminator ); - retList.contents = results; - - return retList; -} From 2c1d13f9e0e6d44e81a7cec99b102a5fdb0e5886 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 22:50:10 +0100 Subject: [PATCH 040/191] Patch --- lib/Client.js | 6 ++++-- src/Client.js | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index a0a343444..23b4fd713 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -342,8 +342,8 @@ var Client = (function () { callback(err); reject(err); } else { - callback(null, message); - resolve(message); + callback(null); + resolve(); } }); } @@ -358,6 +358,8 @@ var Client = (function () { return new Promise(function (resolve, reject) { + content = content instanceof Array ? content.join("\n") : content; + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ content: content, mentions: [] diff --git a/src/Client.js b/src/Client.js index 0b7163c0a..d40222a4f 100644 --- a/src/Client.js +++ b/src/Client.js @@ -381,8 +381,8 @@ class Client { callback(err); reject(err); } else { - callback(null, message); - resolve(message); + callback(null); + resolve(); } }); } @@ -395,6 +395,8 @@ class Client { return new Promise(function (resolve, reject) { + content = (content instanceof Array ? content.join("\n") : content); + request .patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) .set("authorization", self.token) From f8b2383baf27c3424492d68b462876f50c80881b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 23:02:25 +0100 Subject: [PATCH 041/191] version 3.0.0! --- README.md | 6 +- lib/TokenManager.js | 67 --------- lib/asd.js | 63 -------- lib/list.js | 350 -------------------------------------------- package.json | 5 +- src/TokenManager.js | 68 --------- 6 files changed, 4 insertions(+), 555 deletions(-) delete mode 100644 lib/TokenManager.js delete mode 100644 lib/asd.js delete mode 100644 lib/list.js delete mode 100644 src/TokenManager.js diff --git a/README.md b/README.md index b80c65f0d..ed50cc5c4 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,12 @@ Discord.js is a node module that allows you to interface with the [Discord](http The aim of this API is to make it *really* simple to start developing your bots. This API has server, channel and user tracking, as well as tools to make identification really simple. -New update features **big speed boosts** (everything cached and sorted with around 1 second of calling the login function) upon connection and allows editing of messages! +The new rewrite of the API (version 3+) is written in ECMAScript 6 and compiled down to EC5 using Babel. It allows the code to be written faster and more consistently, and take use of new features. -## PLEASE BE AWARE - I'm currently rewriting this _entire_ module in ECMAScript 6 and then using Babel to compile it so it works in node. That means for a few days I won't be adding features, but after that features will come out faster and better than ever! -back to +## New update break your code? Read why [here](https://github.com/discord-js/discord.js/wiki#why-did-my-code-break-with-the-new-update). **[Find the website here.](http://discord-js.github.io)** - **[For more information, click here.](https://github.com/hydrabolt/discord.js/wiki)** ### This module is still in alpha - especially the newer versions! diff --git a/lib/TokenManager.js b/lib/TokenManager.js deleted file mode 100644 index 22732a462..000000000 --- a/lib/TokenManager.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; - -var fs = require("fs"); -var crypto = require("crypto"); -var md5 = require("md5"); - -var tokens = {}; - -exports.TokenManager = function (folder, file) { - - this.path = folder + file; - - var self = this; - - try { - var fd = fs.openSync(self.path, "wx"); - self.writeTokens(); - } catch (e) { - self.readTokens(); - } -}; - -exports.TokenManager.prototype.addToken = function (id, token, pass) { - tokens[md5(id)] = encrypt(token, pass); - this.writeTokens(); -}; - -exports.TokenManager.prototype.readTokens = function () { - tokens = JSON.parse(fs.readFileSync(this.path, "utf8")); - for (tkn in tokens) { - tokens[tkn] = decrypt(tokens[tkn], tkn); - } -}; - -exports.TokenManager.prototype.writeTokens = function () { - var tkn = {}; - for (token in tokens) { - tkn[token] = encrypt(tokens[token], token); - } - fs.writeFile(this.path, JSON.stringify(tkn), function (err) {}); -}; - -exports.TokenManager.prototype.exists = function (id) { - return tokens[md5(id)]; -}; - -exports.TokenManager.prototype.getToken = function (id, pass) { - try { - return decrypt(tokens[md5(id)], pass); - } catch (e) { - return false; - } -}; - -function encrypt(string, password) { - var cipher = crypto.createCipher("aes-256-ctr", password); - var crypted = cipher.update(string, 'utf8', 'hex'); - crypted += cipher.final('hex'); - return crypted; -} - -function decrypt(string, password) { - var decipher = crypto.createDecipher("aes-256-ctr", password); - var dec = decipher.update(string, 'hex', 'utf8'); - dec += decipher.final('utf8'); - return dec; -} \ No newline at end of file diff --git a/lib/asd.js b/lib/asd.js deleted file mode 100644 index c74b5e209..000000000 --- a/lib/asd.js +++ /dev/null @@ -1,63 +0,0 @@ -"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 request = require("superagent"); - -var defaultOptions = { - cache_tokens: false -}; - -var Client = (function () { - function Client() { - var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; - var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; - - _classCallCheck(this, Client); - - /* - When created, if a token is specified the Client will - try connecting with it. If the token is incorrect, no - further efforts will be made to connect. - */ - this.options = options; - this.token = token; - this.state = 0; - this.websocket = null; - this.events = new Map(); - this.user = null; - /* - State values: - 0 - idle - 1 - logging in - 2 - logged in - 3 - ready - 4 - disconnected - */ - } - - _createClass(Client, [{ - key: "login", - - //def login - value: function login() { - var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; - var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234s" : arguments[1]; - - if (this.state === 0 || this.state === 4) { - - this.state = 1; - request.post(); - } - } - }, { - key: "ready", - get: function get() { - return this.state === 3; - } - }]); - - return Client; -})(); \ No newline at end of file diff --git a/lib/list.js b/lib/list.js deleted file mode 100644 index df07cad86..000000000 --- a/lib/list.js +++ /dev/null @@ -1,350 +0,0 @@ -/** - * Similar to a Java set. Contains no duplicate elements and includes filter - * functions. Discriminates between elements based on a discriminator passed - * when created. Generally "ID" - * @class List - */ -"use strict"; - -exports.List = function (discriminator, cap) { - /** - * What to use to distringuish duplicates - * @attribute discriminator - * @type {String} - */ - this.discriminator = discriminator; - /** - * The maximum amount of elements allowed in the list. - * @default Infinity - * @attribute cap - * @type {Number} - */ - this.cap = cap || Number.MAX_SAFE_INTEGER; - /** - * The Array version of the List. - * @type {Array} - * @attribute contents - */ - this.contents = []; -}; - -/** - * Adds an element to the list if it isn't already there. - * @method add - * @param {Object/Array} element The element(s) to add - * @example - * List.add( obj ); - * List.add( [ obj, obj, obj ] ); - */ -exports.List.prototype.add = function (child) { - - var self = this; - - if (child.constructor === Array) { - - children = child; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - child = _step.value; - - addChild(child); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } else { - addChild(child); - } - - function addChild(child) { - - if (self.length() > self.cap) { - self.splice(0, 1); - } - - if (self.filter(self.discriminator, child[self.discriminator]).length() === 0) self.contents.push(child); - } -}; - -/** - * Returns the length of the List - * @method length - * @return {Number} - */ -exports.List.prototype.length = function () { - return this.contents.length; -}; - -/** - * Gets the index of an element in the List or defaults to false - * @param {Object} object The element we want to get the index of - * @return {Number/Boolean} The index if the object is in the list, or false. - * @method getIndex - */ -exports.List.prototype.getIndex = function (object) { - - var index = false; - - for (elementIndex in this.contents) { - var element = this.contents[elementIndex]; - if (element[this.discriminator] == object[this.discriminator]) { - return elementIndex; - } - } - - return index; -}; - -/** - * Removes an element at the specified index - * @param {Number} index - * @method removeIndex - */ -exports.List.prototype.removeIndex = function (index) { - this.contents.splice(index, 1); -}; - -/** - * Removes an element from the list - * @param {Object} element - * @method removeElement - * @return {Boolean} whether the operation was successful or not. - */ -exports.List.prototype.removeElement = function (child) { - - for (_element in this.contents) { - var element = this.contents[_element]; - if (child[this.discriminator] == element[this.discriminator]) { - this.removeIndex(_element, 1); - return true; - } - } - - return false; -}; - -/** - * Replaces an element in the list with a specified element - * @method updateElement - * @param {Object} element Element to update. - * @param {Object} newElement New Element - * @return {Boolean} whether the operation was successful or not. - */ -exports.List.prototype.updateElement = function (child, newChild) { - - for (_element in this.contents) { - var element = this.contents[_element]; - if (child[this.discriminator] == element[this.discriminator]) { - this.contents[_element] = newChild; - return true; - } - } - - return false; -}; - -exports.List.prototype.concatSublists = function (whereList, discriminator) { - //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values. - - var concatList = new exports.List(discriminator); - - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = this.contents[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - item = _step2.value; - - var itemList = item[whereList]; - concatList.add(itemList.contents); - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - return concatList; -}; - -exports.List.prototype.filter = function (key, value, onlyOne, caseInsen) { - - var results = []; - - value = change(value); - - for (index in this.contents) { - var child = this.contents[index]; - if (change(child[key]) == value) { - if (onlyOne) { - return child; - } else { - results.push(child); - } - } - } - - function change(val) { - if (caseInsen) { - val = val.toUpperCase(); - } - return val; - } - - if (onlyOne) { - return false; - } - - var retList = new exports.List(this.discriminator); - retList.contents = results; - - return retList; -}; - -exports.List.prototype.getValues = function (key) { - - var valList = []; - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = this.contents[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - child = _step3.value; - - valList.push(child[key]); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - return valList; -}; - -exports.List.prototype.deepFilter = function (keys, value, onlyOne, caseInsen) { - - var results = []; - - value = change(value); - - for (index in this.contents) { - var child = this.contents[index]; - var buffer = child; - - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = keys[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - key = _step4.value; - - if (buffer instanceof exports.List) { - buffer = buffer.contents; - } - if (buffer instanceof Array) { - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; - - try { - for (var _iterator5 = buffer[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - elem = _step5.value; - - if (change(elem[key]) == value) { - buffer = elem; - } - } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } - } - buffer = buffer[key]; - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - if (change(buffer) == value) { - if (onlyOne) { - return child; - } else { - results.push(child); - } - } - } - - function change(val) { - if (caseInsen) { - val = val.toUpperCase(); - } - return val; - } - - if (onlyOne) { - return false; - } - - var retList = new exports.List(this.discriminator); - retList.contents = results; - - return retList; -}; \ No newline at end of file diff --git a/package.json b/package.json index 1b8a533f6..f832c5cac 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "discord.js", - "version": "2.7.2", + "version": "3", "description": "A way to interface with the Discord API", - "main": "index.js", + "main": "./lib/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, @@ -25,7 +25,6 @@ }, "homepage": "https://github.com/discord-js/discord.js#readme", "dependencies": { - "md5": "^2.0.0", "superagent": "^1.3.0", "ws": "^0.7.2" } diff --git a/src/TokenManager.js b/src/TokenManager.js deleted file mode 100644 index ceeed9ded..000000000 --- a/src/TokenManager.js +++ /dev/null @@ -1,68 +0,0 @@ -var fs = require( "fs" ); -var crypto = require( "crypto" ); -var md5 = require( "md5" ); - -var tokens = {}; - -exports.TokenManager = function( folder, file ) { - - this.path = folder + file; - - var self = this; - - try { - var fd = fs.openSync( self.path, "wx" ); - self.writeTokens(); - } catch ( e ) { - self.readTokens(); - } - -} - -exports.TokenManager.prototype.addToken = function( id, token, pass ) { - tokens[ md5( id ) ] = encrypt( token, pass ); - this.writeTokens(); -} - -exports.TokenManager.prototype.readTokens = function() { - tokens = JSON.parse( fs.readFileSync( this.path, "utf8" ) ); - for ( tkn in tokens ) { - tokens[ tkn ] = decrypt( tokens[ tkn ], tkn ); - } -} - -exports.TokenManager.prototype.writeTokens = function() { - var tkn = {}; - for ( token in tokens ) { - tkn[ token ] = encrypt( tokens[ token ], token ); - } - fs.writeFile( this.path, JSON.stringify( tkn ), function( err ) { - - } ); -} - -exports.TokenManager.prototype.exists = function( id ) { - return tokens[ md5( id ) ]; -} - -exports.TokenManager.prototype.getToken = function( id, pass ) { - try{ - return decrypt( tokens[ md5( id ) ], pass ); - }catch(e){ - return false; - } -} - -function encrypt( string, password ) { - var cipher = crypto.createCipher( "aes-256-ctr", password ) - var crypted = cipher.update( string, 'utf8', 'hex' ) - crypted += cipher.final( 'hex' ); - return crypted; -} - -function decrypt( string, password ) { - var decipher = crypto.createDecipher( "aes-256-ctr", password ) - var dec = decipher.update( string, 'hex', 'utf8' ) - dec += decipher.final( 'utf8' ); - return dec; -} From 0f1fbf1eb62aa2309219f47cc6203f2486ef9a97 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 25 Aug 2015 23:03:00 +0100 Subject: [PATCH 042/191] working 3.0.0. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f832c5cac..4e29966db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3", + "version": "3.0.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From b5131b55eeb2fde00879ea709fc09f925d831930 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 08:25:13 +0100 Subject: [PATCH 043/191] 3.0.1 - removed unused import --- lib/invite.js | 2 -- lib/message.js | 4 ---- package.json | 2 +- src/invite.js | 2 -- src/message.js | 4 ---- 5 files changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/invite.js b/lib/invite.js index 6ce06bd04..5f51dc1a9 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -4,8 +4,6 @@ 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 User = require("./user.js").User; - var Invite = (function () { function Invite(data, client) { _classCallCheck(this, Invite); diff --git a/lib/message.js b/lib/message.js index f4b937f02..24c54fbb3 100644 --- a/lib/message.js +++ b/lib/message.js @@ -4,10 +4,6 @@ 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 User = require("./user.js").User; -var List = require("./list.js").List; -var PMChannel = require("./PMChannel.js").PMChannel; - var Message = (function () { function Message(data, channel, mentions, author) { _classCallCheck(this, Message); diff --git a/package.json b/package.json index 4e29966db..a20514ae9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.0.0", + "version": "3.0.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/invite.js b/src/invite.js index 6880a834f..91c43bbd1 100644 --- a/src/invite.js +++ b/src/invite.js @@ -1,5 +1,3 @@ -var User = require("./user.js").User; - class Invite { constructor(data, client) { this.max_age = data.max_age; diff --git a/src/message.js b/src/message.js index ba869c1e1..a979e87dd 100644 --- a/src/message.js +++ b/src/message.js @@ -1,7 +1,3 @@ -var User = require( "./user.js" ).User; -var List = require( "./list.js" ).List; -var PMChannel = require( "./PMChannel.js" ).PMChannel; - class Message{ constructor(data, channel, mentions, author){ this.tts = data.tts; From 69f27948235e5c3d8c21533171377084db804ae5 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:18:58 +0100 Subject: [PATCH 044/191] added .travis.yml --- .travis.yml | 3 +++ package.json | 2 +- test/bot.js | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..6998e3244 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "stable" \ No newline at end of file diff --git a/package.json b/package.json index a20514ae9..07c6bec4c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "node test/bot.js" }, "repository": { "type": "git", diff --git a/test/bot.js b/test/bot.js index 30b8dbacb..ee15f97b5 100644 --- a/test/bot.js +++ b/test/bot.js @@ -1,3 +1,7 @@ +/* + +*/ + var Discord = require("../lib/index.js"); var Auth = require("./auth.json"); var mybot = new Discord.Client(); From c75c260a686619fe2d9668151128025c200cefde Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:20:21 +0100 Subject: [PATCH 045/191] no test --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07c6bec4c..a20514ae9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { - "test": "node test/bot.js" + "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", From 61cd96a83cd408bb8cc53fc16f84a07fafb95652 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:23:20 +0100 Subject: [PATCH 046/191] updated package --- lib/index.js | 2 -- package.json | 2 +- src/index.js | 2 -- test/bot.js | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/index.js b/lib/index.js index fa2343ae4..f40ad04a1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,8 +1,6 @@ "use strict"; var request = require("superagent"); -var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); -exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file diff --git a/package.json b/package.json index a20514ae9..fce74adc0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "node ./test/bot.js" }, "repository": { "type": "git", diff --git a/src/index.js b/src/index.js index f64a62a7f..8c059d576 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,4 @@ var request = require("superagent"); -var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); -exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index ee15f97b5..5e6670da4 100644 --- a/test/bot.js +++ b/test/bot.js @@ -2,7 +2,7 @@ */ -var Discord = require("../lib/index.js"); +var Discord = require("../"); var Auth = require("./auth.json"); var mybot = new Discord.Client(); From ff5d2b242e1d9d69a41c24c7d70decabb6c15643 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:28:25 +0100 Subject: [PATCH 047/191] build should work --- lib/index.js | 4 +++- src/index.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index f40ad04a1..ceb8d2918 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,8 @@ "use strict"; var request = require("superagent"); -var Client = require("./Client.js"); +var Endpoints = require("./endpoints.js"); +var Client = require("./client.js"); +exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 8c059d576..f06b89b05 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,6 @@ var request = require("superagent"); -var Client = require("./Client.js"); +var Endpoints = require("./endpoints.js"); +var Client = require("./client.js"); +exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file From b12540238c3d55f4d08722bfb5ce06c257504f35 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:33:16 +0100 Subject: [PATCH 048/191] test script should wor --- lib/Client.js | 12 +++++----- src/Client.js | 12 +++++----- test/bot.js | 64 ++++++++------------------------------------------- 3 files changed, 21 insertions(+), 67 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 23b4fd713..bf08ba38c 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -5,12 +5,12 @@ 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 Endpoints = require("./Endpoints.js"); -var User = require("./User.js"); -var Server = require("./Server.js"); -var Channel = require("./Channel.js"); -var Message = require("./Message.js"); -var Invite = require("./Invite.js"); +var Endpoints = require("./endpoints.js"); +var User = require("./user.js"); +var Server = require("./server.js"); +var Channel = require("./channel.js"); +var Message = require("./message.js"); +var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); //node modules diff --git a/src/Client.js b/src/Client.js index d40222a4f..d7a0e069e 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1,10 +1,10 @@ //discord.js modules -var Endpoints = require("./Endpoints.js"); -var User = require("./User.js"); -var Server = require("./Server.js"); -var Channel = require("./Channel.js"); -var Message = require("./Message.js"); -var Invite = require("./Invite.js"); +var Endpoints = require("./endpoints.js"); +var User = require("./user.js"); +var Server = require("./server.js"); +var Channel = require("./channel.js"); +var Message = require("./message.js"); +var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); //node modules diff --git a/test/bot.js b/test/bot.js index 5e6670da4..6dc4c9ca2 100644 --- a/test/bot.js +++ b/test/bot.js @@ -3,62 +3,16 @@ */ var Discord = require("../"); -var Auth = require("./auth.json"); var mybot = new Discord.Client(); -mybot.login(Auth.email, Auth.password) +mybot.login("email", "password").then(success).catch(error); - .then(function (token) { - console.log("wooo!"); - }).catch(function (error) { - console.log(error); - }); +function success(){ + console.log("login successful"); + process.exit(0); +} -mybot.on("ready", function () { - console.log("Ready!"); -}) - -mybot.on("message", function (msg) { - - if(msg.content === "pmme"){ - console.log("yes we found it!"); - mybot.setUsername("hydrabot").catch(function(err){ - console.log(err); - }); - mybot.reply(msg, "You know what "+msg.sender+"? NO").then(function(msg){ - mybot.updateMessage(msg, "wat i sed nothin m8"); - }); - mybot.getChannelLogs(msg.channel).then(function(logs){ - console.log(logs[0]); - }).catch(function(error){ - console.log(error); - }); - } - -}); - -mybot.on("messageDelete", function (channel, message) { - - console.log("MESSAGE WAS DELETED BY " + (message ? message.author.username : channel.name)); - -}); - -mybot.on("messageUpdate", function (message, formerMessage) { - - console.log(message.author.username, "changed", formerMessage.content, "to", message.content); - -}); - -mybot.on("serverNewMember", function (user) { - console.log("new user", user.username); -}); -mybot.on("serverRemoveMember", function (user) { - console.log("left user", user.username); -}); -mybot.on("userUpdate", function (oldUser, newUser) { - console.log(oldUser, "vs", newUser); -}); - -mybot.on("channelCreate", function(chann){ - console.log(chann); -}) \ No newline at end of file +function error(){ + console.log("login error, but the API works"); + process.exit(0); +} \ No newline at end of file From d3089c11ab4366ec83263cc477e8eace07602f8f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:41:46 +0100 Subject: [PATCH 049/191] try and get travis to work by deleting lib cache --- lib/Client.js | 1365 ---------------------------------------------- lib/PMChannel.js | 61 --- lib/channel.js | 74 --- lib/endpoints.js | 13 - lib/index.js | 8 - lib/internal.js | 203 ------- lib/invite.js | 35 -- lib/message.js | 72 --- lib/server.js | 168 ------ lib/user.js | 56 -- 10 files changed, 2055 deletions(-) delete mode 100644 lib/Client.js delete mode 100644 lib/PMChannel.js delete mode 100644 lib/channel.js delete mode 100644 lib/endpoints.js delete mode 100644 lib/index.js delete mode 100644 lib/internal.js delete mode 100644 lib/invite.js delete mode 100644 lib/message.js delete mode 100644 lib/server.js delete mode 100644 lib/user.js diff --git a/lib/Client.js b/lib/Client.js deleted file mode 100644 index bf08ba38c..000000000 --- a/lib/Client.js +++ /dev/null @@ -1,1365 +0,0 @@ -//discord.js modules -"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 Endpoints = require("./endpoints.js"); -var User = require("./user.js"); -var Server = require("./server.js"); -var Channel = require("./channel.js"); -var Message = require("./message.js"); -var Invite = require("./invite.js"); -var PMChannel = require("./PMChannel.js"); - -//node modules -var request = require("superagent"); -var WebSocket = require("ws"); - -var defaultOptions = { - cache_tokens: false -}; - -var Client = (function () { - function Client() { - var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; - var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; - - _classCallCheck(this, Client); - - /* - When created, if a token is specified the Client will - try connecting with it. If the token is incorrect, no - further efforts will be made to connect. - */ - this.options = options; - this.token = token; - this.state = 0; - this.websocket = null; - this.events = new Map(); - this.user = null; - this.alreadySentData = false; - this.serverCreateListener = new Map(); - - this.email = "abc"; - this.password = "abc"; - - /* - State values: - 0 - idle - 1 - logging in - 2 - logged in - 3 - ready - 4 - disconnected - */ - - this.userCache = []; - this.channelCache = []; - this.serverCache = []; - this.pmChannelCache = []; - this.readyTime = null; - } - - _createClass(Client, [{ - key: "sendPacket", - value: function sendPacket(JSONObject) { - if (this.websocket.readyState === 1) { - this.websocket.send(JSON.stringify(JSONObject)); - } - } - - //def debug - }, { - key: "debug", - value: function debug(message) { - console.log(message); - } - }, { - key: "on", - value: function on(event, fn) { - this.events.set(event, fn); - } - }, { - key: "off", - value: function off(event, fn) { - this.events["delete"](event); - } - }, { - key: "keepAlive", - value: function keepAlive() { - this.debug("keep alive triggered"); - this.sendPacket({ - op: 1, - d: Date.now() - }); - } - - //def trigger - }, { - key: "trigger", - value: function trigger(event) { - var args = []; - for (var arg in arguments) { - args.push(arguments[arg]); - } - var evt = this.events.get(event); - if (evt) { - evt.apply(this, args.slice(1)); - } - } - - //def login - }, { - key: "login", - value: function login() { - var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; - var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2]; - - var self = this; - - this.createws(); - return new Promise(function (resolve, reject) { - if (self.state === 0 || self.state === 4) { - - self.state = 1; //set the state to logging in - - self.email = email; - self.password = password; - - request.post(Endpoints.LOGIN).send({ - email: email, - password: password - }).end(function (err, res) { - - if (err) { - self.state = 4; //set state to disconnected - self.trigger("disconnected"); - self.websocket.close(); - callback(err); - reject(err); - } else { - self.state = 2; //set state to logged in (not yet ready) - self.token = res.body.token; //set our token - self.trySendConnData(); - callback(null, self.token); - resolve(self.token); - } - }); - } else { - reject(new Error("Client already logging in or ready")); - } - }); - } - }, { - key: "logout", - value: function logout() { - var callback = arguments.length <= 0 || arguments[0] === undefined ? function (err) {} : arguments[0]; - - var self = this; - - return new Promise(function (resolve, reject) { - - request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - self.state = 4; - callback(); - resolve(); - } - }); - }); - } - }, { - key: "createServer", - value: function createServer(name, region) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, server) {} : arguments[2]; - - var self = this; - return new Promise(function (resolve, reject) { - - request.post(Endpoints.SERVERS).set("authorization", self.token).send({ - name: name, - region: region - }).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - // potentially redundant in future - // creating here does NOT give us the channels of the server - // so we must wait for the guild_create event. - self.serverCreateListener.set(res.body.id, [resolve, callback]); - /*var srv = self.addServer(res.body); - callback(null, srv); - resolve(srv);*/ - } - }); - }); - } - }, { - key: "createChannel", - value: function createChannel(server, channelName, channelType) { - var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, chann) {} : arguments[3]; - - var self = this; - - return new Promise(function (resolve, reject) { - - request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization", self.token).send({ - name: channelName, - type: channelType - }).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var server = self.getServer("id", res.body.guild_id); - var chann = self.addChannel(res.body, res.body.guild_id); - server.addChannel(chann); - callback(null, chann); - resolve(chann); - } - }); - }); - } - }, { - key: "leaveServer", - value: function leaveServer(server) { - var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; - - var self = this; - - return new Promise(function (resolve, reject) { - - request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization", self.token).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - self.serverCache.splice(self.serverCache.indexOf(server), 1); - callback(null); - resolve(); - } - }); - }); - } - }, { - key: "createInvite", - value: function createInvite(serverOrChannel, options) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, invite) {} : arguments[2]; - - var self = this; - - return new Promise(function (resolve, reject) { - - var destination; - - if (serverOrChannel instanceof Server) { - destination = serverOrChannel.id; - } else if (serverOrChannel instanceof Channel) { - destination = serverOrChannel.id; - } else { - destination = serverOrChannel; - } - - options = options || {}; - options.max_age = options.maxAge || 0; - options.max_uses = options.maxUses || 0; - options.temporary = options.temporary || false; - options.xkcdpass = options.xkcd || false; - - request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization", self.token).send(options).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - var inv = new Invite(res.body, self); - callback(null, inv); - resolve(inv); - } - }); - }); - } - }, { - key: "startPM", - value: function startPM(user) { - - var self = this; - - return new Promise(function (resolve, reject) { - var userId = user; - if (user instanceof User) { - userId = user.id; - } - request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization", self.token).send({ - recipient_id: userId - }).end(function (err, res) { - if (err) { - reject(err); - } else { - resolve(self.addPMChannel(res.body)); - } - }); - }); - } - }, { - key: "reply", - value: function reply(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - - var self = this; - - return new Promise(function (response, reject) { - - var user = destination.sender; - self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); - }); - } - }, { - key: "deleteMessage", - value: function deleteMessage(message, timeout) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - - var self = this; - - return new Promise(function (resolve, reject) { - if (timeout) { - setTimeout(remove, timeout); - } else { - remove(); - } - - function remove() { - request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - callback(null); - resolve(); - } - }); - } - }); - } - }, { - key: "updateMessage", - value: function updateMessage(message, content) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - - var self = this; - - return new Promise(function (resolve, reject) { - - content = content instanceof Array ? content.join("\n") : content; - - request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ - content: content, - mentions: [] - }).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - var msg = new Message(res.body, message.channel, message.mentions, message.sender); - callback(null, msg); - resolve(msg); - - message.channel.messages[message.channel.messages.indexOf(message)] = msg; - } - }); - }); - } - }, { - key: "setUsername", - value: function setUsername(newName) { - var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; - - var self = this; - - return new Promise(function (resolve, reject) { - request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({ - avatar: self.user.avatar, - email: self.email, - new_password: null, - password: self.password, - username: newName - }).end(function (err) { - callback(err); - if (err) reject(err);else resolve(); - }); - }); - } - }, { - key: "getChannelLogs", - value: function getChannelLogs(channel) { - var amount = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1]; - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, logs) {} : arguments[2]; - - var self = this; - - return new Promise(function (resolve, reject) { - - var channelID = channel; - if (channel instanceof Channel) { - channelID = channel.id; - } - - request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", self.token).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var logs = []; - - var channel = self.getChannel("id", channelID); - - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = res.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var message = _step.value; - - var mentions = []; - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = message.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var mention = _step2.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - var author = self.addUser(message.author); - - logs.push(new Message(message, channel, mentions, author)); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - - callback(null, logs); - resolve(logs); - } - }); - }); - } - }, { - key: "deleteChannel", - value: function deleteChannel(channel) { - var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; - - var self = this; - - return new Promise(function (resolve, reject) { - - var channelID = channel; - if (channel instanceof Channel) { - channelID = channel.id; - } - - request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", self.token).end(function (err) { - if (err) { - callback(err); - reject(err); - } else { - callback(null); - resolve(); - } - }); - }); - } - }, { - key: "joinServer", - value: function joinServer(invite) { - var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; - - var self = this; - - return new Promise(function (resolve, reject) { - - var id = invite instanceof Invite ? invite.code : invite; - - request.post(Endpoints.API + "/invite/" + id).set("authorization", self.token).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); - } - }); - }); - } - }, { - key: "sendMessage", - value: function sendMessage(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3]; - - var self = this; - - return new Promise(function (resolve, reject) { - - message = premessage + resolveMessage(message); - var mentions = resolveMentions(); - destination = resolveDestination(destination); - - if (destination) send(); - - function send() { - - request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ - content: message, - mentions: mentions - }).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var data = res.body; - - var mentions = []; - - data.mentions = data.mentions || []; //for some reason this was not defined at some point? - - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - var channel = self.getChannel("id", data.channel_id); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - callback(null, msg); - resolve(msg); - } - } - }); - } - - function resolveDestination() { - var channId = false; - - if (destination instanceof Server) { - channId = destination.id; //general is the same as server id - } else if (destination instanceof Channel) { - channId = destination.id; - } else if (destination instanceof Message) { - channId = destination.channel.id; - } else if (destination instanceof User) { - - //check if we have a PM - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = self.pmChannelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var pmc = _step4.value; - - if (pmc.user.equals(destination)) { - return pmc.id; - } - } - - //we don't, at this point we're late - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - self.startPM(destination).then(function (pmc) { - destination = pmc.id; - send(); - }); - } else { - channId = destination; - } - - return channId; - } - - function resolveMessage() { - var msg = message; - if (message instanceof Array) { - msg = message.join("\n"); - } - return msg; - } - - function resolveMentions() { - var _mentions = []; - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; - - try { - for (var _iterator5 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var mention = _step5.value; - - _mentions.push(mention.substring(2, mention.length - 1)); - } - } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; - } finally { - try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); - } - } finally { - if (_didIteratorError5) { - throw _iteratorError5; - } - } - } - - return _mentions; - } - }); - } - - //def createws - }, { - key: "createws", - value: function createws() { - if (this.websocket) return false; - - var self = this; - - //good to go - this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); - - //open - this.websocket.onopen = function () { - self.trySendConnData(); //try connecting - }; - - //close - this.websocket.onclose = function () { - self.trigger("disconnected"); - }; - - //message - this.websocket.onmessage = function (e) { - - var dat = false, - data = {}; - - try { - dat = JSON.parse(e.data); - data = dat.d; - } catch (err) { - self.trigger("error", err, e); - return; - } - - //valid message - switch (dat.t) { - - case "READY": - self.debug("received ready packet"); - - self.user = self.addUser(data.user); - - var _iteratorNormalCompletion6 = true; - var _didIteratorError6 = false; - var _iteratorError6 = undefined; - - try { - for (var _iterator6 = data.guilds[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var _server = _step6.value; - - var server = self.addServer(_server); - } - } catch (err) { - _didIteratorError6 = true; - _iteratorError6 = err; - } finally { - try { - if (!_iteratorNormalCompletion6 && _iterator6["return"]) { - _iterator6["return"](); - } - } finally { - if (_didIteratorError6) { - throw _iteratorError6; - } - } - } - - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; - - try { - for (var _iterator7 = data.private_channels[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var _pmc = _step7.value; - - var pmc = self.addPMChannel(_pmc); - } - } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; - } finally { - try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); - } - } finally { - if (_didIteratorError7) { - throw _iteratorError7; - } - } - } - - self.trigger("ready"); - self.readyTime = Date.now(); - self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); - self.state = 3; - setInterval(function () { - self.keepAlive.apply(self); - }, data.heartbeat_interval); - - break; - case "MESSAGE_CREATE": - self.debug("received message"); - - var mentions = []; - data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; - - try { - for (var _iterator8 = data.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var mention = _step8.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; - } finally { - try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); - } - } finally { - if (_didIteratorError8) { - throw _iteratorError8; - } - } - } - - var channel = self.getChannel("id", data.channel_id); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - self.trigger("message", msg); - } - - break; - case "MESSAGE_DELETE": - self.debug("message deleted"); - - var channel = self.getChannel("id", data.channel_id); - var message = channel.getMessage("id", data.id); - if (message) { - self.trigger("messageDelete", channel, message); - channel.messages.splice(channel.messages.indexOf(message), 1); - } else { - //don't have the cache of that message ;( - self.trigger("messageDelete", channel); - } - break; - case "MESSAGE_UPDATE": - self.debug("message updated"); - - var channel = self.getChannel("id", data.channel_id); - var formerMessage = channel.getMessage("id", data.id); - - if (formerMessage) { - - //new message might be partial, so we need to fill it with whatever the old message was. - var info = {}; - - for (var key in formerMessage) { - info[key] = formerMessage[key]; - } - - for (var key in data) { - info[key] = data[key]; - } - - var mentions = []; - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; - - try { - for (var _iterator9 = info.mentions[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var mention = _step9.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; - } finally { - try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); - } - } finally { - if (_didIteratorError9) { - throw _iteratorError9; - } - } - } - - var newMessage = new Message(info, channel, mentions, formerMessage.author); - - self.trigger("messageUpdate", newMessage, formerMessage); - - channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; - } - - // message isn't in cache, and if it's a partial it could cause - // all hell to break loose... best to just act as if nothing happened - - break; - - case "GUILD_DELETE": - - var server = self.getServer("id", data.id); - - if (server) { - self.serverCache.splice(self.serverCache.indexOf(server), 1); - self.trigger("serverDelete", server); - } - - break; - - case "CHANNEL_DELETE": - - var channel = self.getChannel("id", data.id); - - if (channel) { - - var server = channel.server; - - if (server) { - - server.channels.splice(server.channels.indexOf(channel), 1); - } - - self.trigger("channelDelete", channel); - - self.serverCache.splice(self.serverCache.indexOf(channel), 1); - } - - break; - - case "GUILD_CREATE": - - var server = self.getServer("id", data.id); - - if (!server) { - //if server doesn't already exist because duh - server = self.addServer(data); - } /*else if(server.channels.length === 0){ - - var srv = new Server(data, self); - for(channel of data.channels){ - srv.channels.push(new Channel(channel, data.id)); - } - self.serverCache[self.serverCache.indexOf(server)] = srv; - - }*/ - - if (self.serverCreateListener.get(data.id)) { - var cbs = self.serverCreateListener.get(data.id); - cbs[0](server); //promise then callback - cbs[1](null, server); //legacy callback - self.serverCreateListener["delete"](data.id); - } - - self.trigger("serverCreate", server); - - break; - - case "CHANNEL_CREATE": - - var channel = self.getChannel("id", data.id); - - if (!channel) { - - var chann = self.addChannel(data, data.guild_id); - var srv = self.getServer("id", data.guild_id); - if (srv) { - srv.addChannel(chann); - } - self.trigger("channelCreate", chann); - } - - break; - - case "GUILD_MEMBER_ADD": - - var server = self.getServer("id", data.guild_id); - - if (server) { - - var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. - - if (! ~server.members.indexOf(user)) { - server.members.push(user); - } - - self.trigger("serverNewMember", user); - } - - break; - - case "GUILD_MEMBER_REMOVE": - - var server = self.getServer("id", data.guild_id); - - if (server) { - - var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. - - if (~server.members.indexOf(user)) { - server.members.splice(server.members.indexOf(user), 1); - } - - self.trigger("serverRemoveMember", user); - } - - break; - - case "USER_UPDATE": - - if (self.user && data.id === self.user.id) { - - var newUser = new User(data); //not actually adding to the cache - - self.trigger("userUpdate", newUser, self.user); - - if (~self.userCache.indexOf(self.user)) { - self.userCache[self.userCache.indexOf(self.user)] = newUser; - } - - self.user = newUser; - } - - break; - - case "PRESENCE_UPDATE": - - var userInCache = self.getUser("id", data.user.id); - - if (userInCache) { - //user exists - var presenceUser = new User(data.user); - if (presenceUser.equalsStrict(userInCache)) { - //they're exactly the same, an actual presence update - self.trigger("presence", { - user: userInCache, - status: data.status, - server: self.getServer("id", data.guild_id), - gameId: data.game_id - }); - } else { - //one of their details changed. - self.trigger("userUpdate", userInCache, presenceUser); - self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; - } - } - - break; - - default: - self.debug("received unknown packet"); - self.trigger("unknown", dat); - break; - - } - }; - } - - //def addUser - }, { - key: "addUser", - value: function addUser(data) { - if (!this.getUser("id", data.id)) { - this.userCache.push(new User(data)); - } - return this.getUser("id", data.id); - } - - //def addChannel - }, { - key: "addChannel", - value: function addChannel(data, serverId) { - if (!this.getChannel("id", data.id)) { - this.channelCache.push(new Channel(data, this.getServer("id", serverId))); - } - return this.getChannel("id", data.id); - } - }, { - key: "addPMChannel", - value: function addPMChannel(data) { - if (!this.getPMChannel("id", data.id)) { - this.pmChannelCache.push(new PMChannel(data, this)); - } - return this.getPMChannel("id", data.id); - } - - //def addServer - }, { - key: "addServer", - value: function addServer(data) { - - var server = this.getServer("id", data.id); - - if (!server) { - server = new Server(data, this); - this.serverCache.push(server); - if (data.channels) { - var _iteratorNormalCompletion10 = true; - var _didIteratorError10 = false; - var _iteratorError10 = undefined; - - try { - for (var _iterator10 = data.channels[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var channel = _step10.value; - - server.channels.push(this.addChannel(channel, server.id)); - } - } catch (err) { - _didIteratorError10 = true; - _iteratorError10 = err; - } finally { - try { - if (!_iteratorNormalCompletion10 && _iterator10["return"]) { - _iterator10["return"](); - } - } finally { - if (_didIteratorError10) { - throw _iteratorError10; - } - } - } - } - } - - return server; - } - - //def getUser - }, { - key: "getUser", - value: function getUser(key, value) { - var _iteratorNormalCompletion11 = true; - var _didIteratorError11 = false; - var _iteratorError11 = undefined; - - try { - for (var _iterator11 = this.userCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { - var user = _step11.value; - - if (user[key] === value) { - return user; - } - } - } catch (err) { - _didIteratorError11 = true; - _iteratorError11 = err; - } finally { - try { - if (!_iteratorNormalCompletion11 && _iterator11["return"]) { - _iterator11["return"](); - } - } finally { - if (_didIteratorError11) { - throw _iteratorError11; - } - } - } - - return null; - } - - //def getChannel - }, { - key: "getChannel", - value: function getChannel(key, value) { - var _iteratorNormalCompletion12 = true; - var _didIteratorError12 = false; - var _iteratorError12 = undefined; - - try { - for (var _iterator12 = this.channelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { - var channel = _step12.value; - - if (channel[key] === value) { - return channel; - } - } - } catch (err) { - _didIteratorError12 = true; - _iteratorError12 = err; - } finally { - try { - if (!_iteratorNormalCompletion12 && _iterator12["return"]) { - _iterator12["return"](); - } - } finally { - if (_didIteratorError12) { - throw _iteratorError12; - } - } - } - - return this.getPMChannel(key, value); //might be a PM - } - }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { - var _iteratorNormalCompletion13 = true; - var _didIteratorError13 = false; - var _iteratorError13 = undefined; - - try { - for (var _iterator13 = this.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var channel = _step13.value; - - if (channel[key] === value) { - return channel; - } - } - } catch (err) { - _didIteratorError13 = true; - _iteratorError13 = err; - } finally { - try { - if (!_iteratorNormalCompletion13 && _iterator13["return"]) { - _iterator13["return"](); - } - } finally { - if (_didIteratorError13) { - throw _iteratorError13; - } - } - } - - return null; - } - - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; - - try { - for (var _iterator14 = this.serverCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var server = _step14.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError14 = true; - _iteratorError14 = err; - } finally { - try { - if (!_iteratorNormalCompletion14 && _iterator14["return"]) { - _iterator14["return"](); - } - } finally { - if (_didIteratorError14) { - throw _iteratorError14; - } - } - } - - return null; - } - - //def trySendConnData - }, { - key: "trySendConnData", - value: function trySendConnData() { - - if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { - - this.alreadySentData = true; - - var data = { - op: 2, - d: { - token: this.token, - v: 2, - properties: { - "$os": "discord.js", - "$browser": "discord.js", - "$device": "discord.js", - "$referrer": "", - "$referring_domain": "" - } - } - }; - this.websocket.send(JSON.stringify(data)); - } - } - }, { - key: "resolveServerID", - value: function resolveServerID(resource) { - - if (resource instanceof Server) { - return resource.id; - } else if (!isNaN(resource) && resource.length && resource.length === 17) { - return resource; - } - } - }, { - key: "uptime", - get: function get() { - - return this.readyTime ? Date.now() - this.readyTime : null; - } - }, { - key: "ready", - get: function get() { - return this.state === 3; - } - }, { - key: "servers", - get: function get() { - return this.serverCache; - } - }, { - key: "channels", - get: function get() { - return this.channelCache; - } - }, { - key: "users", - get: function get() { - return this.userCache; - } - }, { - key: "PMChannels", - get: function get() { - return this.pmChannelCache; - } - }, { - key: "messages", - get: function get() { - - var msgs = []; - var _iteratorNormalCompletion15 = true; - var _didIteratorError15 = false; - var _iteratorError15 = undefined; - - try { - for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { - var channel = _step15.value; - - msgs = msgs.concat(channel.messages); - } - } catch (err) { - _didIteratorError15 = true; - _iteratorError15 = err; - } finally { - try { - if (!_iteratorNormalCompletion15 && _iterator15["return"]) { - _iterator15["return"](); - } - } finally { - if (_didIteratorError15) { - throw _iteratorError15; - } - } - } - - return msgs; - } - }]); - - return Client; -})(); - -module.exports = Client; \ No newline at end of file diff --git a/lib/PMChannel.js b/lib/PMChannel.js deleted file mode 100644 index ae44d3d60..000000000 --- a/lib/PMChannel.js +++ /dev/null @@ -1,61 +0,0 @@ -"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 PMChannel = (function () { - function PMChannel(data, client) { - _classCallCheck(this, PMChannel); - - this.user = client.getUser("id", data.recipient.id); - this.id = data.id; - this.messages = []; - } - - _createClass(PMChannel, [{ - key: "addMessage", - value: function addMessage(data) { - if (!this.getMessage("id", data.id)) { - this.messages.push(data); - } - return this.getMessage("id", data.id); - } - }, { - key: "getMessage", - value: function getMessage(key, value) { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var message = _step.value; - - if (message[key] === value) { - return message; - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - - return null; - } - }]); - - return PMChannel; -})(); - -module.exports = PMChannel; \ No newline at end of file diff --git a/lib/channel.js b/lib/channel.js deleted file mode 100644 index d3c3d2dc7..000000000 --- a/lib/channel.js +++ /dev/null @@ -1,74 +0,0 @@ -"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 Channel = (function () { - function Channel(data, server) { - _classCallCheck(this, Channel); - - this.server = server; - this.name = data.name; - this.type = data.type; - this.id = data.id; - this.messages = []; - //this.isPrivate = isPrivate; //not sure about the implementation of this... - } - - _createClass(Channel, [{ - key: "equals", - value: function equals(object) { - return object.id === this.id; - } - }, { - key: "addMessage", - value: function addMessage(data) { - if (!this.getMessage("id", data.id)) { - this.messages.push(data); - } - return this.getMessage("id", data.id); - } - }, { - key: "getMessage", - value: function getMessage(key, value) { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var message = _step.value; - - if (message[key] === value) { - return message; - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - - return null; - } - }, { - key: "client", - get: function get() { - return this.server.client; - } - }]); - - return Channel; -})(); - -module.exports = Channel; \ No newline at end of file diff --git a/lib/endpoints.js b/lib/endpoints.js deleted file mode 100644 index 271b465eb..000000000 --- a/lib/endpoints.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -exports.BASE_DOMAIN = "discordapp.com"; -exports.BASE = "https://" + exports.BASE_DOMAIN; -exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; - -exports.API = exports.BASE + "/api"; -exports.AUTH = exports.API + "/auth"; -exports.LOGIN = exports.AUTH + "/login"; -exports.LOGOUT = exports.AUTH + "/logout"; -exports.USERS = exports.API + "/users"; -exports.SERVERS = exports.API + "/guilds"; -exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index ceb8d2918..000000000 --- a/lib/index.js +++ /dev/null @@ -1,8 +0,0 @@ -"use strict"; - -var request = require("superagent"); -var Endpoints = require("./endpoints.js"); -var Client = require("./client.js"); - -exports.Endpoints = Endpoints; -exports.Client = Client; \ No newline at end of file diff --git a/lib/internal.js b/lib/internal.js deleted file mode 100644 index 3acf5940b..000000000 --- a/lib/internal.js +++ /dev/null @@ -1,203 +0,0 @@ -"use strict"; - -var request = require("superagent"); -var Endpoints = require("./endpoints.js"); - -var Internal = {}; - -Internal.XHR = {}; -Internal.WebSocket = {}; - -Internal.WebSocket.properties = { - "$os": "discord.js", - "$browser": "discord.js", - "$device": "discord.js", - "$referrer": "", - "$referring_domain": "" -}; - -Internal.XHR.login = function (email, password, callback) { - - request.post(Endpoints.LOGIN).send({ - email: email, - password: password - }).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body.token); - } - }); -}; - -Internal.XHR.logout = function (token, callback) { - - request.post(Endpoints.LOGOUT).end(function (err, res) { - - err ? callback(err) : callback(null); - }); -}; - -Internal.XHR.createServer = function (token, name, region, callback) { - - request.post(Endpoints.SERVERS).set("authorization", token).send({ - name: name, - region: region - }).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.leaveServer = function (token, serverId, callback) { - - request.del(Endpoints.SERVERS + "/" + serverId).set("authorization", token).end(function (err, res) { - - err ? callback(err) : callback(null); - }); -}; - -Internal.XHR.createInvite = function (token, channelId, options, callback) { - request.post(Endpoints.CHANNELS + "/" + channelId + "/invites").set("authorization", token).send(options).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.startPM = function (token, selfID, userID, callback) { - - request.post(Endpoints.USERS + "/" + selfID + "/channels").set("authorization", token).send({ - recipient_id: userID - }).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.sendMessage = function (token, channelID, messageParameters, callback) { - request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).send(messageParameters).end(function (err, res) { - - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.sendFile = function (token, channelID, file, fileName, callback) { - request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).attach("file", file, fileName).end(function (err, res) { - - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.deleteMessage = function (token, channelID, messageID, callback) { - request.del(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).end(function (err) { - err ? callback(err) : callback(null); - }); -}; - -Internal.XHR.updateMessage = function (token, channelID, messageID, messageParameters, callback) { - - request.patch(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).send(messageParameters).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.getChannelLogs = function (token, channelID, amount, callback) { - request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", token).end(function (err, res) { - - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.createChannel = function (token, serverID, name, type, callback) { - request.post(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).send({ - name: name, - type: type - }).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.deleteChannel = function (token, channelID, callback) { - - request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", token).end(function (err) { - err ? callback(err) : callback(null); - }); -}; -Internal.XHR.deleteServer = function (token, serverID, callback) { - request.del(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err) { - err ? callback(err) : callback(null); - }); -}; - -Internal.XHR.getChannels = function (token, serverID, callback) { - request.get(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).end(function (err) { - err ? callback(err) : callback(null); - }); -}; - -Internal.XHR.getServer = function (token, serverID, callback) { - - request.get(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err, res) { - - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.acceptInvite = function (token, inviteID, callback) { - - request.post(Endpoints.API + "/invite/" + inviteID).set("authorization", token).end(function (err, res) { - if (err) { - callback(err); - } else { - callback(null, res.body); - } - }); -}; - -Internal.XHR.setUsername = function (token, avatar, email, newPassword, password, username, callback) { - - request.patch(Endpoints.API + "/users/@me").set("authorization", token).send({ - avatar: avatar, - email: email, - new_password: newPassword, - password: password, - username: username - }).end(function (err) { - callback(err); - }); -}; - -exports.Internal = Internal; \ No newline at end of file diff --git a/lib/invite.js b/lib/invite.js deleted file mode 100644 index 5f51dc1a9..000000000 --- a/lib/invite.js +++ /dev/null @@ -1,35 +0,0 @@ -"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 Invite = (function () { - function Invite(data, client) { - _classCallCheck(this, Invite); - - this.max_age = data.max_age; - this.code = data.code; - this.server = client.getServer("id", data.guild.id); - this.revoked = data.revoked; - this.created_at = Date.parse(data.created_at); - this.temporary = data.temporary; - this.uses = data.uses; - this.max_uses = data.uses; - this.inviter = client.addUser(data.inviter); - this.xkcd = data.xkcdpass; - this.channel = client.getChannel("id", data.channel.id); - } - - _createClass(Invite, [{ - key: "URL", - get: function get() { - var code = this.xkcd ? this.xkcdpass : this.code; - return "https://discord.gg/" + code; - } - }]); - - return Invite; -})(); - -module.exports = Invite; \ No newline at end of file diff --git a/lib/message.js b/lib/message.js deleted file mode 100644 index 24c54fbb3..000000000 --- a/lib/message.js +++ /dev/null @@ -1,72 +0,0 @@ -"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 Message = (function () { - function Message(data, channel, mentions, author) { - _classCallCheck(this, Message); - - this.tts = data.tts; - this.timestamp = Date.parse(data.timestamp); - this.nonce = data.nonce; - this.mentions = mentions; - this.everyoneMentioned = data.mention_everyone; - this.id = data.id; - this.embeds = data.embeds; - this.editedTimestamp = data.edited_timestamp; - this.content = data.content.trim(); - this.channel = channel; - this.author = author; - this.attachments = data.attachments; - } - - /*exports.Message.prototype.isPM = function() { - return ( this.channel instanceof PMChannel ); - }*/ - - _createClass(Message, [{ - key: "isMentioned", - value: function isMentioned(user) { - var id = user.id ? user.id : user; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var mention = _step.value; - - if (mention.id === id) { - return true; - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - - return false; - } - }, { - key: "sender", - get: function get() { - return this.author; - } - }]); - - return Message; -})(); - -module.exports = Message; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js deleted file mode 100644 index 9c9903843..000000000 --- a/lib/server.js +++ /dev/null @@ -1,168 +0,0 @@ -"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 Server = (function () { - function Server(data, client) { - _classCallCheck(this, Server); - - this.client = client; - this.region = data.region; - this.ownerID = data.owner_id; - this.name = data.name; - this.id = data.id; - this.members = []; - this.channels = []; - this.icon = data.icon; - this.afkTimeout = data.afk_timeout; - this.afkChannelId = data.afk_channel_id; - - if (!data.members) { - data.members = [client.user]; - return; - } - - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var member = _step.value; - - // first we cache the user in our Discord Client, - // then we add it to our list. This way when we - // get a user from this server's member list, - // it will be identical (unless an async change occurred) - // to the client's cache. - if (member.user) this.members.push(client.addUser(member.user)); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"]) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } - - _createClass(Server, [{ - key: "getChannel", - - // get/set - value: function getChannel(key, value) { - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var channel = _step2.value; - - if (channel[key] === value) { - return channel; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2["return"]) { - _iterator2["return"](); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - return null; - } - }, { - key: "getMember", - value: function getMember(key, value) { - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var member = _step3.value; - - if (member[key] === value) { - return member; - } - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - return null; - } - }, { - key: "addChannel", - value: function addChannel(chann) { - if (!this.getChannel("id", chann.id)) { - this.channels.push(chann); - } - return chann; - } - }, { - key: "addMember", - value: function addMember(member) { - if (!this.getMember("id", member.id)) { - this.members.push(member); - } - return member; - } - }, { - key: "iconURL", - get: function get() { - if (!this.icon) return null; - return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; - } - }, { - key: "afkChannel", - get: function get() { - if (!this.afkChannelId) return false; - - return this.getChannel("id", this.afkChannelId); - } - }, { - key: "defaultChannel", - get: function get() { - return this.getChannel("name", "general"); - } - }, { - key: "owner", - get: function get() { - return this.client.getUser("id", this.ownerID); - } - }]); - - return Server; -})(); - -module.exports = Server; \ No newline at end of file diff --git a/lib/user.js b/lib/user.js deleted file mode 100644 index 2f363dd1e..000000000 --- a/lib/user.js +++ /dev/null @@ -1,56 +0,0 @@ -"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 User = (function () { - function User(data) { - _classCallCheck(this, User); - - this.username = data.username; - this.discriminator = data.discriminator; - this.id = data.id; - this.avatar = data.avatar; - } - - // access using user.avatarURL; - - _createClass(User, [{ - key: "mention", - value: function mention() { - return "<@" + this.id + ">"; - } - }, { - key: "toString", - value: function toString() { - /* - if we embed a user in a String - like so: - "Yo " + user + " what's up?" - It would generate something along the lines of: - "Yo @hydrabolt what's up?" - */ - return this.mention(); - } - }, { - key: "equals", - value: function equals(object) { - return object.id === this.id; - } - }, { - key: "equalsStrict", - value: function equalsStrict(object) { - return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; - } - }, { - key: "avatarURL", - get: function get() { - if (!this.avatar) return null; - return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; - } - }]); - - return User; -})(); - -module.exports = User; \ No newline at end of file From 68b1df1b35d48369c5fc8d356567590c3da2ae53 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:43:23 +0100 Subject: [PATCH 050/191] push files again --- lib/Client.js | 1365 ++++++++++++++++++++++++++++++++++++++++++++++ lib/Endpoints.js | 13 + lib/PMChannel.js | 61 +++ lib/channel.js | 74 +++ lib/index.js | 8 + lib/internal.js | 203 +++++++ lib/invite.js | 35 ++ lib/message.js | 72 +++ lib/server.js | 168 ++++++ lib/user.js | 56 ++ 10 files changed, 2055 insertions(+) create mode 100644 lib/Client.js create mode 100644 lib/Endpoints.js create mode 100644 lib/PMChannel.js create mode 100644 lib/channel.js create mode 100644 lib/index.js create mode 100644 lib/internal.js create mode 100644 lib/invite.js create mode 100644 lib/message.js create mode 100644 lib/server.js create mode 100644 lib/user.js diff --git a/lib/Client.js b/lib/Client.js new file mode 100644 index 000000000..bf08ba38c --- /dev/null +++ b/lib/Client.js @@ -0,0 +1,1365 @@ +//discord.js modules +"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 Endpoints = require("./endpoints.js"); +var User = require("./user.js"); +var Server = require("./server.js"); +var Channel = require("./channel.js"); +var Message = require("./message.js"); +var Invite = require("./invite.js"); +var PMChannel = require("./PMChannel.js"); + +//node modules +var request = require("superagent"); +var WebSocket = require("ws"); + +var defaultOptions = { + cache_tokens: false +}; + +var Client = (function () { + function Client() { + var options = arguments.length <= 0 || arguments[0] === undefined ? defaultOptions : arguments[0]; + var token = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; + + _classCallCheck(this, Client); + + /* + When created, if a token is specified the Client will + try connecting with it. If the token is incorrect, no + further efforts will be made to connect. + */ + this.options = options; + this.token = token; + this.state = 0; + this.websocket = null; + this.events = new Map(); + this.user = null; + this.alreadySentData = false; + this.serverCreateListener = new Map(); + + this.email = "abc"; + this.password = "abc"; + + /* + State values: + 0 - idle + 1 - logging in + 2 - logged in + 3 - ready + 4 - disconnected + */ + + this.userCache = []; + this.channelCache = []; + this.serverCache = []; + this.pmChannelCache = []; + this.readyTime = null; + } + + _createClass(Client, [{ + key: "sendPacket", + value: function sendPacket(JSONObject) { + if (this.websocket.readyState === 1) { + this.websocket.send(JSON.stringify(JSONObject)); + } + } + + //def debug + }, { + key: "debug", + value: function debug(message) { + console.log(message); + } + }, { + key: "on", + value: function on(event, fn) { + this.events.set(event, fn); + } + }, { + key: "off", + value: function off(event, fn) { + this.events["delete"](event); + } + }, { + key: "keepAlive", + value: function keepAlive() { + this.debug("keep alive triggered"); + this.sendPacket({ + op: 1, + d: Date.now() + }); + } + + //def trigger + }, { + key: "trigger", + value: function trigger(event) { + var args = []; + for (var arg in arguments) { + args.push(arguments[arg]); + } + var evt = this.events.get(event); + if (evt) { + evt.apply(this, args.slice(1)); + } + } + + //def login + }, { + key: "login", + value: function login() { + var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0]; + var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1]; + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2]; + + var self = this; + + this.createws(); + return new Promise(function (resolve, reject) { + if (self.state === 0 || self.state === 4) { + + self.state = 1; //set the state to logging in + + self.email = email; + self.password = password; + + request.post(Endpoints.LOGIN).send({ + email: email, + password: password + }).end(function (err, res) { + + if (err) { + self.state = 4; //set state to disconnected + self.trigger("disconnected"); + self.websocket.close(); + callback(err); + reject(err); + } else { + self.state = 2; //set state to logged in (not yet ready) + self.token = res.body.token; //set our token + self.trySendConnData(); + callback(null, self.token); + resolve(self.token); + } + }); + } else { + reject(new Error("Client already logging in or ready")); + } + }); + } + }, { + key: "logout", + value: function logout() { + var callback = arguments.length <= 0 || arguments[0] === undefined ? function (err) {} : arguments[0]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + self.state = 4; + callback(); + resolve(); + } + }); + }); + } + }, { + key: "createServer", + value: function createServer(name, region) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, server) {} : arguments[2]; + + var self = this; + return new Promise(function (resolve, reject) { + + request.post(Endpoints.SERVERS).set("authorization", self.token).send({ + name: name, + region: region + }).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + // potentially redundant in future + // creating here does NOT give us the channels of the server + // so we must wait for the guild_create event. + self.serverCreateListener.set(res.body.id, [resolve, callback]); + /*var srv = self.addServer(res.body); + callback(null, srv); + resolve(srv);*/ + } + }); + }); + } + }, { + key: "createChannel", + value: function createChannel(server, channelName, channelType) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, chann) {} : arguments[3]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization", self.token).send({ + name: channelName, + type: channelType + }).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var server = self.getServer("id", res.body.guild_id); + var chann = self.addChannel(res.body, res.body.guild_id); + server.addChannel(chann); + callback(null, chann); + resolve(chann); + } + }); + }); + } + }, { + key: "leaveServer", + value: function leaveServer(server) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization", self.token).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + callback(null); + resolve(); + } + }); + }); + } + }, { + key: "createInvite", + value: function createInvite(serverOrChannel, options) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, invite) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var destination; + + if (serverOrChannel instanceof Server) { + destination = serverOrChannel.id; + } else if (serverOrChannel instanceof Channel) { + destination = serverOrChannel.id; + } else { + destination = serverOrChannel; + } + + options = options || {}; + options.max_age = options.maxAge || 0; + options.max_uses = options.maxUses || 0; + options.temporary = options.temporary || false; + options.xkcdpass = options.xkcd || false; + + request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization", self.token).send(options).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var inv = new Invite(res.body, self); + callback(null, inv); + resolve(inv); + } + }); + }); + } + }, { + key: "startPM", + value: function startPM(user) { + + var self = this; + + return new Promise(function (resolve, reject) { + var userId = user; + if (user instanceof User) { + userId = user.id; + } + request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization", self.token).send({ + recipient_id: userId + }).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(self.addPMChannel(res.body)); + } + }); + }); + } + }, { + key: "reply", + value: function reply(destination, message) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (response, reject) { + + var user = destination.sender; + self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); + }); + } + }, { + key: "deleteMessage", + value: function deleteMessage(message, timeout) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + if (timeout) { + setTimeout(remove, timeout); + } else { + remove(); + } + + function remove() { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + callback(null); + resolve(); + } + }); + } + }); + } + }, { + key: "updateMessage", + value: function updateMessage(message, content) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + content = content instanceof Array ? content.join("\n") : content; + + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + callback(null, msg); + resolve(msg); + + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "setUsername", + value: function setUsername(newName) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({ + avatar: self.user.avatar, + email: self.email, + new_password: null, + password: self.password, + username: newName + }).end(function (err) { + callback(err); + if (err) reject(err);else resolve(); + }); + }); + } + }, { + key: "getChannelLogs", + value: function getChannelLogs(channel) { + var amount = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1]; + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, logs) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", self.token).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var logs = []; + + var channel = self.getChannel("id", channelID); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = res.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + var mentions = []; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = message.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var mention = _step2.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + var author = self.addUser(message.author); + + logs.push(new Message(message, channel, mentions, author)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + callback(null, logs); + resolve(logs); + } + }); + }); + } + }, { + key: "deleteChannel", + value: function deleteChannel(channel) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var channelID = channel; + if (channel instanceof Channel) { + channelID = channel.id; + } + + request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", self.token).end(function (err) { + if (err) { + callback(err); + reject(err); + } else { + callback(null); + resolve(); + } + }); + }); + } + }, { + key: "joinServer", + value: function joinServer(invite) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var id = invite instanceof Invite ? invite.code : invite; + + request.post(Endpoints.API + "/invite/" + id).set("authorization", self.token).end(function (err, res) { + if (err) { + callback(err); + reject(err); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } + }); + }); + } + }, { + key: "sendMessage", + value: function sendMessage(destination, message) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3]; + + var self = this; + + return new Promise(function (resolve, reject) { + + message = premessage + resolveMessage(message); + var mentions = resolveMentions(); + destination = resolveDestination(destination); + + if (destination) send(); + + function send() { + + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: message, + mentions: mentions + }).end(function (err, res) { + + if (err) { + callback(err); + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + callback(null, msg); + resolve(msg); + } + } + }); + } + + function resolveDestination() { + var channId = false; + + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = self.pmChannelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var pmc = _step4.value; + + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + self.startPM(destination).then(function (pmc) { + destination = pmc.id; + send(); + }); + } else { + channId = destination; + } + + return channId; + } + + function resolveMessage() { + var msg = message; + if (message instanceof Array) { + msg = message.join("\n"); + } + return msg; + } + + function resolveMentions() { + var _mentions = []; + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var mention = _step5.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + return _mentions; + } + }); + } + + //def createws + }, { + key: "createws", + value: function createws() { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.guilds[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var _server = _step6.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = data.private_channels[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var _pmc = _step7.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var mention = _step8.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = info.mentions[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var mention = _step9.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener.get(data.id)) { + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener["delete"](data.id); + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = data.channels[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.userCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var user = _step11.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.channelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var channel = _step13.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = this.serverCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var server = _step14.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +module.exports = Client; \ No newline at end of file diff --git a/lib/Endpoints.js b/lib/Endpoints.js new file mode 100644 index 000000000..271b465eb --- /dev/null +++ b/lib/Endpoints.js @@ -0,0 +1,13 @@ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file diff --git a/lib/PMChannel.js b/lib/PMChannel.js new file mode 100644 index 000000000..ae44d3d60 --- /dev/null +++ b/lib/PMChannel.js @@ -0,0 +1,61 @@ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; \ No newline at end of file diff --git a/lib/channel.js b/lib/channel.js new file mode 100644 index 000000000..d3c3d2dc7 --- /dev/null +++ b/lib/channel.js @@ -0,0 +1,74 @@ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); + + return Channel; +})(); + +module.exports = Channel; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 000000000..ceb8d2918 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,8 @@ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./endpoints.js"); +var Client = require("./client.js"); + +exports.Endpoints = Endpoints; +exports.Client = Client; \ No newline at end of file diff --git a/lib/internal.js b/lib/internal.js new file mode 100644 index 000000000..3acf5940b --- /dev/null +++ b/lib/internal.js @@ -0,0 +1,203 @@ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./endpoints.js"); + +var Internal = {}; + +Internal.XHR = {}; +Internal.WebSocket = {}; + +Internal.WebSocket.properties = { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" +}; + +Internal.XHR.login = function (email, password, callback) { + + request.post(Endpoints.LOGIN).send({ + email: email, + password: password + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body.token); + } + }); +}; + +Internal.XHR.logout = function (token, callback) { + + request.post(Endpoints.LOGOUT).end(function (err, res) { + + err ? callback(err) : callback(null); + }); +}; + +Internal.XHR.createServer = function (token, name, region, callback) { + + request.post(Endpoints.SERVERS).set("authorization", token).send({ + name: name, + region: region + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.leaveServer = function (token, serverId, callback) { + + request.del(Endpoints.SERVERS + "/" + serverId).set("authorization", token).end(function (err, res) { + + err ? callback(err) : callback(null); + }); +}; + +Internal.XHR.createInvite = function (token, channelId, options, callback) { + request.post(Endpoints.CHANNELS + "/" + channelId + "/invites").set("authorization", token).send(options).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.startPM = function (token, selfID, userID, callback) { + + request.post(Endpoints.USERS + "/" + selfID + "/channels").set("authorization", token).send({ + recipient_id: userID + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.sendMessage = function (token, channelID, messageParameters, callback) { + request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).send(messageParameters).end(function (err, res) { + + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.sendFile = function (token, channelID, file, fileName, callback) { + request.post(Endpoints.CHANNELS + "/" + channelID + "/messages").set("authorization", token).attach("file", file, fileName).end(function (err, res) { + + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.deleteMessage = function (token, channelID, messageID, callback) { + request.del(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; + +Internal.XHR.updateMessage = function (token, channelID, messageID, messageParameters, callback) { + + request.patch(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID).set("authorization", token).send(messageParameters).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.getChannelLogs = function (token, channelID, amount, callback) { + request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", token).end(function (err, res) { + + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.createChannel = function (token, serverID, name, type, callback) { + request.post(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).send({ + name: name, + type: type + }).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.deleteChannel = function (token, channelID, callback) { + + request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; +Internal.XHR.deleteServer = function (token, serverID, callback) { + request.del(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; + +Internal.XHR.getChannels = function (token, serverID, callback) { + request.get(Endpoints.SERVERS + "/" + serverID + "/channels").set("authorization", token).end(function (err) { + err ? callback(err) : callback(null); + }); +}; + +Internal.XHR.getServer = function (token, serverID, callback) { + + request.get(Endpoints.SERVERS + "/" + serverID).set("authorization", token).end(function (err, res) { + + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.acceptInvite = function (token, inviteID, callback) { + + request.post(Endpoints.API + "/invite/" + inviteID).set("authorization", token).end(function (err, res) { + if (err) { + callback(err); + } else { + callback(null, res.body); + } + }); +}; + +Internal.XHR.setUsername = function (token, avatar, email, newPassword, password, username, callback) { + + request.patch(Endpoints.API + "/users/@me").set("authorization", token).send({ + avatar: avatar, + email: email, + new_password: newPassword, + password: password, + username: username + }).end(function (err) { + callback(err); + }); +}; + +exports.Internal = Internal; \ No newline at end of file diff --git a/lib/invite.js b/lib/invite.js new file mode 100644 index 000000000..5f51dc1a9 --- /dev/null +++ b/lib/invite.js @@ -0,0 +1,35 @@ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; \ No newline at end of file diff --git a/lib/message.js b/lib/message.js new file mode 100644 index 000000000..24c54fbb3 --- /dev/null +++ b/lib/message.js @@ -0,0 +1,72 @@ +"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 Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }]); + + return Message; +})(); + +module.exports = Message; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js new file mode 100644 index 000000000..9c9903843 --- /dev/null +++ b/lib/server.js @@ -0,0 +1,168 @@ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; \ No newline at end of file diff --git a/lib/user.js b/lib/user.js new file mode 100644 index 000000000..2f363dd1e --- /dev/null +++ b/lib/user.js @@ -0,0 +1,56 @@ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; \ No newline at end of file From 610e6847d175bdd594e107638c34ab3a7c19feba Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:44:25 +0100 Subject: [PATCH 051/191] rename references --- lib/Client.js | 2 +- lib/index.js | 4 ++-- src/Client.js | 2 +- src/index.js | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index bf08ba38c..b625710fa 100644 --- a/lib/Client.js +++ b/lib/Client.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 Endpoints = require("./endpoints.js"); +var Endpoints = require("./Endpoints.js"); var User = require("./user.js"); var Server = require("./server.js"); var Channel = require("./channel.js"); diff --git a/lib/index.js b/lib/index.js index ceb8d2918..fa2343ae4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,8 +1,8 @@ "use strict"; var request = require("superagent"); -var Endpoints = require("./endpoints.js"); -var Client = require("./client.js"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index d7a0e069e..97a46358c 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1,5 +1,5 @@ //discord.js modules -var Endpoints = require("./endpoints.js"); +var Endpoints = require("./Endpoints.js"); var User = require("./user.js"); var Server = require("./server.js"); var Channel = require("./channel.js"); diff --git a/src/index.js b/src/index.js index f06b89b05..90103aa56 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ var request = require("superagent"); -var Endpoints = require("./endpoints.js"); -var Client = require("./client.js"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); exports.Endpoints = Endpoints; exports.Client = Client; \ No newline at end of file From 2cf2dd9a9f03d27f53cfc04a6ba470256c30c3a2 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 10:44:45 +0100 Subject: [PATCH 052/191] 3.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fce74adc0..1c100b3f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.0.1", + "version": "3.0.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From bf80fc4a7c41a23b0834c7c2ac46068fa067d175 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:25:32 +0100 Subject: [PATCH 053/191] Update README.md --- README.md | 107 +++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index ed50cc5c4..d1dd86644 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,62 @@ # discord.js -Discord.js is a node module that allows you to interface with the [Discord](https://discordapp.com/) API for creation of things such as bots or loggers. -The aim of this API is to make it *really* simple to start developing your bots. This API has server, channel and user tracking, as well as tools to make identification really simple. +[![Build Status](https://travis-ci.org/discord-js/discord.js.svg)](https://travis-ci.org/discord-js/discord.js) -The new rewrite of the API (version 3+) is written in ECMAScript 6 and compiled down to EC5 using Babel. It allows the code to be written faster and more consistently, and take use of new features. - -## New update break your code? Read why [here](https://github.com/discord-js/discord.js/wiki#why-did-my-code-break-with-the-new-update). - -**[Find the website here.](http://discord-js.github.io)** - -**[For more information, click here.](https://github.com/hydrabolt/discord.js/wiki)** - -### This module is still in alpha - especially the newer versions! - -This node module is still in alpha, and some methods and functions may change or completely disappear! +discord.js is a node module used as a way of interfacing with +[Discord](https://discordapp.com/). It is a very useful module for creating +bots. ### Installation -``npm install --save discord.js`` +`npm install --save discord.js` -### Features +--- -* Send, Receive Delete and **Edit** messages from channels _and_ DMs! Auto-initiates DMs for you! -* Create, Delete and Leave servers and channels -* Create invites for Servers -* Silent Mention - trigger mention notification without actually @mentioning a user! -* Get complete metadata on users, channels and servers - including avatars. -* Get limitless logs from channels. -* Fast and efficient caching -* Auto-cache messages - -### Example usage +### Example ```js -/* - * A basic bot that shows how to connect to a Discord account, - * how to listen to messages and how to send messages. - * - * This bot responds to every "ping" message with a "pong". - */ +var Discord = require("discord.js"); -var Discord = require( "discord.js" ); +var mybot = new Discord.Client(); -// Create the bot -var myBot = new Discord.Client(); +mybot.on("message", function(message){ + + if(message.content === "ping") + mybot.reply(message, "pong"); + +}); -// Login with an example email and password -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// Add a listener to the "message" event, which triggers upon receiving -// any message -myBot.on( "message", function( message ) { - // message.content accesses the content of the message as a string. - // If it is equal to "ping", then the bot should respond with "pong". - if ( message.content === "ping" ) { - // Send a message ("pong") to the channel the message was sent in, - // which is accessed by message.channel. - this.sendMessage( message.channel, "pong" ); - } -} ); +mybot.login("email", "password"); ``` -### TODO -* Joining servers from an invite -* Stealthy Ninja support +--- + +### Related Projects + +Here is a list of other Discord APIs: + +#### Java: +[Discord4J](https://github.com/nerd/Discord4J) +#### .NET: +[Discord.Net](https://github.com/RogueException/Discord.Net) + +[DiscordSharp](https://github.com/Luigifan/DiscordSharp) +#### NodeJS +[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level) + +#### PHP +[DiscordPHP](https://github.com/teamreflex/DiscordPHP) + +#### Python +[discord.py](https://github.com/Rapptz/discord.py) + +#### Ruby +[discordrb](https://github.com/meew0/discordrb) + +--- + +### Links +**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)** + +**[GitHub](https://github.com/discord-js/discord.js)** + +**[Wiki](https://github.com/discord-js/discord.js/wiki)** + +**[Website](http://discord-js.github.io/)** From fd3fd6faa2a91e368b54bd9c3ad1d0f20e5bf70c Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:27:39 +0100 Subject: [PATCH 054/191] Update README and tests --- README.md | 116 +++++++++++++++++++++++++------------------------ lib/Client.js | 3 +- src/Client.js | 3 +- test/bot.js | 117 ++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 172 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index ed50cc5c4..1a6360ef6 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,71 @@ # discord.js -Discord.js is a node module that allows you to interface with the [Discord](https://discordapp.com/) API for creation of things such as bots or loggers. -The aim of this API is to make it *really* simple to start developing your bots. This API has server, channel and user tracking, as well as tools to make identification really simple. +[![Build Status](https://travis-ci.org/discord-js/discord.js.svg)](https://travis-ci.org/discord-js/discord.js) -The new rewrite of the API (version 3+) is written in ECMAScript 6 and compiled down to EC5 using Babel. It allows the code to be written faster and more consistently, and take use of new features. - -## New update break your code? Read why [here](https://github.com/discord-js/discord.js/wiki#why-did-my-code-break-with-the-new-update). - -**[Find the website here.](http://discord-js.github.io)** - -**[For more information, click here.](https://github.com/hydrabolt/discord.js/wiki)** - -### This module is still in alpha - especially the newer versions! - -This node module is still in alpha, and some methods and functions may change or completely disappear! +discord.js is a node module used as a way of interfacing with +[Discord](https://discordapp.com/). It is a very useful module for creating +bots. ### Installation -``npm install --save discord.js`` +`npm install --save discord.js` -### Features +--- -* Send, Receive Delete and **Edit** messages from channels _and_ DMs! Auto-initiates DMs for you! -* Create, Delete and Leave servers and channels -* Create invites for Servers -* Silent Mention - trigger mention notification without actually @mentioning a user! -* Get complete metadata on users, channels and servers - including avatars. -* Get limitless logs from channels. -* Fast and efficient caching -* Auto-cache messages - -### Example usage +### Example ```js -/* - * A basic bot that shows how to connect to a Discord account, - * how to listen to messages and how to send messages. - * - * This bot responds to every "ping" message with a "pong". - */ +var Discord = require("discord.js"); -var Discord = require( "discord.js" ); +var mybot = new Discord.Client(); -// Create the bot -var myBot = new Discord.Client(); +mybot.on("message", function(message){ + + if(message.content === "ping") + mybot.reply(message, "pong"); + +}); -// Login with an example email and password -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// Add a listener to the "message" event, which triggers upon receiving -// any message -myBot.on( "message", function( message ) { - // message.content accesses the content of the message as a string. - // If it is equal to "ping", then the bot should respond with "pong". - if ( message.content === "ping" ) { - // Send a message ("pong") to the channel the message was sent in, - // which is accessed by message.channel. - this.sendMessage( message.channel, "pong" ); - } -} ); +mybot.login("email", "password"); ``` -### TODO -* Joining servers from an invite -* Stealthy Ninja support +--- + +### Related Projects + +Here is a list of other Discord APIs: + +#### Java: +[Discord4J](https://github.com/nerd/Discord4J) +#### .NET: +[Discord.Net](https://github.com/RogueException/Discord.Net) + +[DiscordSharp](https://github.com/Luigifan/DiscordSharp) +#### NodeJS +[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level) + +#### PHP +[DiscordPHP](https://github.com/teamreflex/DiscordPHP) + +#### Python +[discord.py](https://github.com/Rapptz/discord.py) + +#### Ruby +[discordrb](https://github.com/meew0/discordrb) + +--- + +### Links +**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)** + +**[GitHub](https://github.com/discord-js/discord.js)** + +**[Wiki](https://github.com/discord-js/discord.js/wiki)** + +**[Website](http://discord-js.github.io/)** + +**[NPM](npmjs.com/package/discord.js)** + +--- + +### Contact + +If you would like to contact me, you can create an issue on the GitHub repo +or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTY66OLO). \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js index b625710fa..02687d0f2 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -73,7 +73,7 @@ var Client = (function () { }, { key: "debug", value: function debug(message) { - console.log(message); + this.trigger("debug", message); } }, { key: "on", @@ -167,6 +167,7 @@ var Client = (function () { callback(err); reject(err); } else { + self.websocket.close(); self.state = 4; callback(); resolve(); diff --git a/src/Client.js b/src/Client.js index 97a46358c..3f152c711 100644 --- a/src/Client.js +++ b/src/Client.js @@ -95,7 +95,7 @@ class Client { //def debug debug(message) { - console.log(message); + this.trigger("debug", message); } on(event, fn) { @@ -185,6 +185,7 @@ class Client { callback(err); reject(err); } else { + self.websocket.close(); self.state = 4; callback(); resolve(); diff --git a/test/bot.js b/test/bot.js index 6dc4c9ca2..af8cb8b6c 100644 --- a/test/bot.js +++ b/test/bot.js @@ -1,18 +1,119 @@ /* - + this file should be used for travis builds only */ var Discord = require("../"); var mybot = new Discord.Client(); -mybot.login("email", "password").then(success).catch(error); +var server, channel, message, sentMessage = false; -function success(){ - console.log("login successful"); +function success1(){ //make server + console.log("preparing..."); + mybot.createServer("test-server", "london").then(success2).catch(error); +} + +function success2(_server){ //make channel + console.log("test 1 successful"); + server = _server; + mybot.createChannel(server, "test-channel", "text").then(success3).catch(error); +} + +function success3(_channel){ //send message + console.log("test 2 successful"); + channel = _channel; + mybot.sendMessage(channel, [mybot.user.avatarURL, "an", "array", "of", "messages"]).then(success4).catch(error); +} + +function success4(_message){ //delete message + console.log("test 3 successful"); + message = _message; + mybot.deleteMessage(message).then(success5).catch(error); +} + +function success5(){ //send ping + console.log("test 4 successful"); + mybot.sendMessage(channel, "ping").then(function(msg){ + message = msg; + }).catch(error); + setTimeout(checkError, 30 * 1000); +} + +function success7(){ + console.log("test 6 successful"); + mybot.deleteChannel(channel).then(success8).catch(error); +} + +function success8(){ + console.log("test 7 successful"); + mybot.createInvite(server).then(success9).catch(error); +} + +function success9(invite){ + console.log("test 8 successful"); + if(invite.code){ + success10(); + }else{ + error("reference error"); + } +} + +function success10(){ + console.log("test 9 succesful"); + mybot.leaveServer(server).then(success11).catch(error); +} + +function success11(){ + console.log("test 10 succesful"); + mybot.joinServer(process.env["ds-invite"]).then(success12).catch(error); +} + +function success12(_server){ + console.log("test 11 successful"); + server = mybot.getServer("id", _server.id); + if(server){ + success13(); + }else{ + error("reference error"); + } +} + +function success13(){ + console.log("test 12 successful"); + mybot.leaveServer(server).then(success14).catch(error); +} + +function success14(){ + console.log("test 13 successful"); + mybot.logout().then(done).catch(error); +} + +function done(){ + console.log("All tests completed succesfully."); process.exit(0); } -function error(){ - console.log("login error, but the API works"); - process.exit(0); -} \ No newline at end of file +function checkError(){ + if(!sentMessage){ + error("failure receiving messages"); + } +} + +function error(err){ + console.log("error", err); + process.exit(1); +} + +mybot.on("message", function(message){ + + if(message.channel.equals(channel)){ + if(message.content === "ping"){ + console.log("test 5 successful"); + sentMessage = true; + + mybot.updateMessage(message, "pong").then(success7).catch(error); + } + } + +}); + +mybot.login(process.env["ds-email"], process.env["ds-password"]).then(success1).catch(error); \ No newline at end of file From 76a01592b2f608da671e265dd87cf6391bbcc6d8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:30:01 +0100 Subject: [PATCH 055/191] Updated README and tests --- README.md | 116 +++++++++++++++++++++++++------------------------ lib/Client.js | 3 +- src/Client.js | 3 +- test/bot.js | 117 ++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 172 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index ed50cc5c4..1a6360ef6 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,71 @@ # discord.js -Discord.js is a node module that allows you to interface with the [Discord](https://discordapp.com/) API for creation of things such as bots or loggers. -The aim of this API is to make it *really* simple to start developing your bots. This API has server, channel and user tracking, as well as tools to make identification really simple. +[![Build Status](https://travis-ci.org/discord-js/discord.js.svg)](https://travis-ci.org/discord-js/discord.js) -The new rewrite of the API (version 3+) is written in ECMAScript 6 and compiled down to EC5 using Babel. It allows the code to be written faster and more consistently, and take use of new features. - -## New update break your code? Read why [here](https://github.com/discord-js/discord.js/wiki#why-did-my-code-break-with-the-new-update). - -**[Find the website here.](http://discord-js.github.io)** - -**[For more information, click here.](https://github.com/hydrabolt/discord.js/wiki)** - -### This module is still in alpha - especially the newer versions! - -This node module is still in alpha, and some methods and functions may change or completely disappear! +discord.js is a node module used as a way of interfacing with +[Discord](https://discordapp.com/). It is a very useful module for creating +bots. ### Installation -``npm install --save discord.js`` +`npm install --save discord.js` -### Features +--- -* Send, Receive Delete and **Edit** messages from channels _and_ DMs! Auto-initiates DMs for you! -* Create, Delete and Leave servers and channels -* Create invites for Servers -* Silent Mention - trigger mention notification without actually @mentioning a user! -* Get complete metadata on users, channels and servers - including avatars. -* Get limitless logs from channels. -* Fast and efficient caching -* Auto-cache messages - -### Example usage +### Example ```js -/* - * A basic bot that shows how to connect to a Discord account, - * how to listen to messages and how to send messages. - * - * This bot responds to every "ping" message with a "pong". - */ +var Discord = require("discord.js"); -var Discord = require( "discord.js" ); +var mybot = new Discord.Client(); -// Create the bot -var myBot = new Discord.Client(); +mybot.on("message", function(message){ + + if(message.content === "ping") + mybot.reply(message, "pong"); + +}); -// Login with an example email and password -myBot.login( "hello@example.com", "password1" ); - -// The "ready" event is triggered after the bot successfully connected to -// Discord and is ready to send messages. -myBot.on( "ready", function() { - console.log( "Bot connected successfully." ); -} ); - -// Add a listener to the "message" event, which triggers upon receiving -// any message -myBot.on( "message", function( message ) { - // message.content accesses the content of the message as a string. - // If it is equal to "ping", then the bot should respond with "pong". - if ( message.content === "ping" ) { - // Send a message ("pong") to the channel the message was sent in, - // which is accessed by message.channel. - this.sendMessage( message.channel, "pong" ); - } -} ); +mybot.login("email", "password"); ``` -### TODO -* Joining servers from an invite -* Stealthy Ninja support +--- + +### Related Projects + +Here is a list of other Discord APIs: + +#### Java: +[Discord4J](https://github.com/nerd/Discord4J) +#### .NET: +[Discord.Net](https://github.com/RogueException/Discord.Net) + +[DiscordSharp](https://github.com/Luigifan/DiscordSharp) +#### NodeJS +[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level) + +#### PHP +[DiscordPHP](https://github.com/teamreflex/DiscordPHP) + +#### Python +[discord.py](https://github.com/Rapptz/discord.py) + +#### Ruby +[discordrb](https://github.com/meew0/discordrb) + +--- + +### Links +**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)** + +**[GitHub](https://github.com/discord-js/discord.js)** + +**[Wiki](https://github.com/discord-js/discord.js/wiki)** + +**[Website](http://discord-js.github.io/)** + +**[NPM](npmjs.com/package/discord.js)** + +--- + +### Contact + +If you would like to contact me, you can create an issue on the GitHub repo +or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTY66OLO). \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js index b625710fa..02687d0f2 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -73,7 +73,7 @@ var Client = (function () { }, { key: "debug", value: function debug(message) { - console.log(message); + this.trigger("debug", message); } }, { key: "on", @@ -167,6 +167,7 @@ var Client = (function () { callback(err); reject(err); } else { + self.websocket.close(); self.state = 4; callback(); resolve(); diff --git a/src/Client.js b/src/Client.js index 97a46358c..3f152c711 100644 --- a/src/Client.js +++ b/src/Client.js @@ -95,7 +95,7 @@ class Client { //def debug debug(message) { - console.log(message); + this.trigger("debug", message); } on(event, fn) { @@ -185,6 +185,7 @@ class Client { callback(err); reject(err); } else { + self.websocket.close(); self.state = 4; callback(); resolve(); diff --git a/test/bot.js b/test/bot.js index 6dc4c9ca2..af8cb8b6c 100644 --- a/test/bot.js +++ b/test/bot.js @@ -1,18 +1,119 @@ /* - + this file should be used for travis builds only */ var Discord = require("../"); var mybot = new Discord.Client(); -mybot.login("email", "password").then(success).catch(error); +var server, channel, message, sentMessage = false; -function success(){ - console.log("login successful"); +function success1(){ //make server + console.log("preparing..."); + mybot.createServer("test-server", "london").then(success2).catch(error); +} + +function success2(_server){ //make channel + console.log("test 1 successful"); + server = _server; + mybot.createChannel(server, "test-channel", "text").then(success3).catch(error); +} + +function success3(_channel){ //send message + console.log("test 2 successful"); + channel = _channel; + mybot.sendMessage(channel, [mybot.user.avatarURL, "an", "array", "of", "messages"]).then(success4).catch(error); +} + +function success4(_message){ //delete message + console.log("test 3 successful"); + message = _message; + mybot.deleteMessage(message).then(success5).catch(error); +} + +function success5(){ //send ping + console.log("test 4 successful"); + mybot.sendMessage(channel, "ping").then(function(msg){ + message = msg; + }).catch(error); + setTimeout(checkError, 30 * 1000); +} + +function success7(){ + console.log("test 6 successful"); + mybot.deleteChannel(channel).then(success8).catch(error); +} + +function success8(){ + console.log("test 7 successful"); + mybot.createInvite(server).then(success9).catch(error); +} + +function success9(invite){ + console.log("test 8 successful"); + if(invite.code){ + success10(); + }else{ + error("reference error"); + } +} + +function success10(){ + console.log("test 9 succesful"); + mybot.leaveServer(server).then(success11).catch(error); +} + +function success11(){ + console.log("test 10 succesful"); + mybot.joinServer(process.env["ds-invite"]).then(success12).catch(error); +} + +function success12(_server){ + console.log("test 11 successful"); + server = mybot.getServer("id", _server.id); + if(server){ + success13(); + }else{ + error("reference error"); + } +} + +function success13(){ + console.log("test 12 successful"); + mybot.leaveServer(server).then(success14).catch(error); +} + +function success14(){ + console.log("test 13 successful"); + mybot.logout().then(done).catch(error); +} + +function done(){ + console.log("All tests completed succesfully."); process.exit(0); } -function error(){ - console.log("login error, but the API works"); - process.exit(0); -} \ No newline at end of file +function checkError(){ + if(!sentMessage){ + error("failure receiving messages"); + } +} + +function error(err){ + console.log("error", err); + process.exit(1); +} + +mybot.on("message", function(message){ + + if(message.channel.equals(channel)){ + if(message.content === "ping"){ + console.log("test 5 successful"); + sentMessage = true; + + mybot.updateMessage(message, "pong").then(success7).catch(error); + } + } + +}); + +mybot.login(process.env["ds-email"], process.env["ds-password"]).then(success1).catch(error); \ No newline at end of file From 011b7789b3cdd9a213c2ded6bf37829d51a64e13 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:36:59 +0100 Subject: [PATCH 056/191] Updated bot environment variables --- test/bot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bot.js b/test/bot.js index af8cb8b6c..e0c2eb940 100644 --- a/test/bot.js +++ b/test/bot.js @@ -64,7 +64,7 @@ function success10(){ function success11(){ console.log("test 10 succesful"); - mybot.joinServer(process.env["ds-invite"]).then(success12).catch(error); + mybot.joinServer(process.env["ds_invite"]).then(success12).catch(error); } function success12(_server){ @@ -116,4 +116,4 @@ mybot.on("message", function(message){ }); -mybot.login(process.env["ds-email"], process.env["ds-password"]).then(success1).catch(error); \ No newline at end of file +mybot.login(process.env["ds_email"], process.env["ds_password"]).then(success1).catch(error); \ No newline at end of file From 0889d0362d616beb6efa8fde099734e3df9e7097 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:39:19 +0100 Subject: [PATCH 057/191] test debug --- test/bot.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/bot.js b/test/bot.js index e0c2eb940..f5af16e5d 100644 --- a/test/bot.js +++ b/test/bot.js @@ -116,4 +116,6 @@ mybot.on("message", function(message){ }); +console.log(process.env); + mybot.login(process.env["ds_email"], process.env["ds_password"]).then(success1).catch(error); \ No newline at end of file From a34f1504f1f269576565fb861cdca601fa893542 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:40:38 +0100 Subject: [PATCH 058/191] unfix --- test/bot.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/bot.js b/test/bot.js index f5af16e5d..e0c2eb940 100644 --- a/test/bot.js +++ b/test/bot.js @@ -116,6 +116,4 @@ mybot.on("message", function(message){ }); -console.log(process.env); - mybot.login(process.env["ds_email"], process.env["ds_password"]).then(success1).catch(error); \ No newline at end of file From 07ad0db114d88a5f24c156eb3e0a4645a58d79fd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 12:40:44 +0100 Subject: [PATCH 059/191] 3.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c100b3f4..de833ea73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.0.2", + "version": "3.0.3", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 2971eccbd22f973ab5ccba64661c3ca6929c0fbb Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:01:59 +0100 Subject: [PATCH 060/191] Moved to resolve destination --- lib/Client.js | 357 +++++++++++++++++++++++++------------------------- src/Client.js | 72 +++++----- 2 files changed, 220 insertions(+), 209 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 02687d0f2..467651f1e 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -528,6 +528,9 @@ var Client = (function () { }); }); } + }, { + key: "sendFile", + value: function sendFile(destination) {} }, { key: "sendMessage", value: function sendMessage(destination, message) { @@ -540,7 +543,7 @@ var Client = (function () { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - destination = resolveDestination(destination); + destination = self.resolveDestination(destination); if (destination) send(); @@ -596,58 +599,6 @@ var Client = (function () { }); } - function resolveDestination() { - var channId = false; - - if (destination instanceof Server) { - channId = destination.id; //general is the same as server id - } else if (destination instanceof Channel) { - channId = destination.id; - } else if (destination instanceof Message) { - channId = destination.channel.id; - } else if (destination instanceof User) { - - //check if we have a PM - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = self.pmChannelCache[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var pmc = _step4.value; - - if (pmc.user.equals(destination)) { - return pmc.id; - } - } - - //we don't, at this point we're late - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - - self.startPM(destination).then(function (pmc) { - destination = pmc.id; - send(); - }); - } else { - channId = destination; - } - - return channId; - } - function resolveMessage() { var msg = message; if (message instanceof Array) { @@ -658,27 +609,27 @@ var Client = (function () { function resolveMentions() { var _mentions = []; - var _iteratorNormalCompletion5 = true; - var _didIteratorError5 = false; - var _iteratorError5 = undefined; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; try { - for (var _iterator5 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var mention = _step5.value; + for (var _iterator4 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var mention = _step4.value; _mentions.push(mention.substring(2, mention.length - 1)); } } catch (err) { - _didIteratorError5 = true; - _iteratorError5 = err; + _didIteratorError4 = true; + _iteratorError4 = err; } finally { try { - if (!_iteratorNormalCompletion5 && _iterator5["return"]) { - _iterator5["return"](); + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); } } finally { - if (_didIteratorError5) { - throw _iteratorError5; + if (_didIteratorError4) { + throw _iteratorError4; } } } @@ -731,15 +682,40 @@ var Client = (function () { self.user = self.addUser(data.user); + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.guilds[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _server = _step5.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { - for (var _iterator6 = data.guilds[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var _server = _step6.value; + for (var _iterator6 = data.private_channels[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var _pmc = _step6.value; - var server = self.addServer(_server); + var pmc = self.addPMChannel(_pmc); } } catch (err) { _didIteratorError6 = true; @@ -756,31 +732,6 @@ var Client = (function () { } } - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; - - try { - for (var _iterator7 = data.private_channels[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var _pmc = _step7.value; - - var pmc = self.addPMChannel(_pmc); - } - } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; - } finally { - try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); - } - } finally { - if (_didIteratorError7) { - throw _iteratorError7; - } - } - } - self.trigger("ready"); self.readyTime = Date.now(); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); @@ -795,27 +746,27 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator8 = data.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var mention = _step8.value; + for (var _iterator7 = data.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError7) { + throw _iteratorError7; } } } @@ -860,27 +811,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator9 = info.mentions[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var mention = _step9.value; + for (var _iterator8 = info.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var mention = _step8.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError9) { - throw _iteratorError9; + if (_didIteratorError8) { + throw _iteratorError8; } } } @@ -1095,27 +1046,27 @@ var Client = (function () { server = new Server(data, this); this.serverCache.push(server); if (data.channels) { - var _iteratorNormalCompletion10 = true; - var _didIteratorError10 = false; - var _iteratorError10 = undefined; + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; try { - for (var _iterator10 = data.channels[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var channel = _step10.value; + for (var _iterator9 = data.channels[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var channel = _step9.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError10 = true; - _iteratorError10 = err; + _didIteratorError9 = true; + _iteratorError9 = err; } finally { try { - if (!_iteratorNormalCompletion10 && _iterator10["return"]) { - _iterator10["return"](); + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); } } finally { - if (_didIteratorError10) { - throw _iteratorError10; + if (_didIteratorError9) { + throw _iteratorError9; } } } @@ -1129,16 +1080,50 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { - for (var _iterator11 = this.userCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { - var user = _step11.value; + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -1156,19 +1141,17 @@ var Client = (function () { } } - return null; + return this.getPMChannel(key, value); //might be a PM } - - //def getChannel }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getPMChannel", + value: function getPMChannel(key, value) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { - for (var _iterator12 = this.channelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { var channel = _step12.value; if (channel[key] === value) { @@ -1190,21 +1173,23 @@ var Client = (function () { } } - return this.getPMChannel(key, value); //might be a PM + return null; } + + //def getServer }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { + key: "getServer", + value: function getServer(key, value) { var _iteratorNormalCompletion13 = true; var _didIteratorError13 = false; var _iteratorError13 = undefined; try { - for (var _iterator13 = this.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var channel = _step13.value; + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -1225,40 +1210,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; - - try { - for (var _iterator14 = this.serverCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var server = _step14.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError14 = true; - _iteratorError14 = err; - } finally { - try { - if (!_iteratorNormalCompletion14 && _iterator14["return"]) { - _iterator14["return"](); - } - } finally { - if (_didIteratorError14) { - throw _iteratorError14; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -1295,6 +1246,60 @@ var Client = (function () { return resource; } } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; + + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } }, { key: "uptime", get: function get() { diff --git a/src/Client.js b/src/Client.js index 3f152c711..5cfd2e44a 100644 --- a/src/Client.js +++ b/src/Client.js @@ -72,7 +72,7 @@ class Client { get users() { return this.userCache; } - + get PMChannels() { return this.pmChannelCache; } @@ -543,6 +543,10 @@ class Client { } + sendFile(destination) { + + } + sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { var self = this; @@ -551,7 +555,7 @@ class Client { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - destination = resolveDestination(destination); + destination = self.resolveDestination(destination); if (destination) send(); @@ -593,37 +597,6 @@ class Client { } - function resolveDestination() { - var channId = false; - - if (destination instanceof Server) { - channId = destination.id; //general is the same as server id - } else if (destination instanceof Channel) { - channId = destination.id; - } else if (destination instanceof Message) { - channId = destination.channel.id; - } else if (destination instanceof User) { - - //check if we have a PM - for (var pmc of self.pmChannelCache) { - if (pmc.user.equals(destination)) { - return pmc.id; - } - } - - //we don't, at this point we're late - self.startPM(destination).then(function (pmc) { - destination = pmc.id; - send(); - }); - - } else { - channId = destination; - } - - return channId; - } - function resolveMessage() { var msg = message; if (message instanceof Array) { @@ -1049,6 +1022,39 @@ class Client { } + resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + for (var pmc of self.pmChannelCache) { + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + }).catch(reject); + + } else { + channId = destination; + } + if(channId) + resolve(channId); + }); + } + } module.exports = Client; \ No newline at end of file From 669c379a62d7edea0a5c0c559c40431030a5ab1b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:05:13 +0100 Subject: [PATCH 061/191] Fixed self resolveDestination Allows much better message sending from different methods, less bloaty --- lib/Client.js | 6 ++---- src/Client.js | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 467651f1e..c11c5a19c 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -543,11 +543,9 @@ var Client = (function () { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - destination = self.resolveDestination(destination); + self.resolveDestination(destination).then(send)["catch"](reject); - if (destination) send(); - - function send() { + function send(destination) { request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ content: message, diff --git a/src/Client.js b/src/Client.js index 5cfd2e44a..bcaad81a7 100644 --- a/src/Client.js +++ b/src/Client.js @@ -555,12 +555,9 @@ class Client { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - destination = self.resolveDestination(destination); + self.resolveDestination(destination).then(send).catch(reject); - if (destination) - send(); - - function send() { + function send(destination) { request .post(`${Endpoints.CHANNELS}/${destination}/messages`) From b1deaf58dbf5620ceb0b7b77a908ea735173bbdc Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:07:06 +0100 Subject: [PATCH 062/191] Began sendFile method --- lib/Client.js | 8 +++++++- src/Client.js | 12 +++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index c11c5a19c..d0de8c022 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -530,7 +530,13 @@ var Client = (function () { } }, { key: "sendFile", - value: function sendFile(destination) {} + value: function sendFile(destination, file) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) {}); + } }, { key: "sendMessage", value: function sendMessage(destination, message) { diff --git a/src/Client.js b/src/Client.js index bcaad81a7..2773607bb 100644 --- a/src/Client.js +++ b/src/Client.js @@ -543,8 +543,14 @@ class Client { } - sendFile(destination) { - + sendFile(destination, file, callback = function (err, msg) { }) { + + var self = this; + + return new Promise(function(resolve, reject){ + + }); + } sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { @@ -1047,7 +1053,7 @@ class Client { } else { channId = destination; } - if(channId) + if (channId) resolve(channId); }); } From 8de0199bf51adc2170c11ef39c207fcd64dfee80 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:11:11 +0100 Subject: [PATCH 063/191] resolve type of file and create stream from it --- lib/Client.js | 12 +++++++++++- src/Client.js | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Client.js b/lib/Client.js index d0de8c022..21b4ce745 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -16,6 +16,7 @@ var PMChannel = require("./PMChannel.js"); //node modules var request = require("superagent"); var WebSocket = require("ws"); +var fs = require("fs"); var defaultOptions = { cache_tokens: false @@ -535,7 +536,16 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) {}); + return new Promise(function (resolve, reject) { + + var fstream; + + if (typeof file === "string" || file instanceof String) { + fstream = fs.createReadStream(file); + } else { + fstream = file; + } + }); } }, { key: "sendMessage", diff --git a/src/Client.js b/src/Client.js index 2773607bb..c350381b8 100644 --- a/src/Client.js +++ b/src/Client.js @@ -10,6 +10,7 @@ var PMChannel = require("./PMChannel.js"); //node modules var request = require("superagent"); var WebSocket = require("ws"); +var fs = require("fs"); var defaultOptions = { cache_tokens: false @@ -549,6 +550,16 @@ class Client { return new Promise(function(resolve, reject){ + var fstream; + + if(typeof file === "string" || file instanceof String){ + fstream = fs.createReadStream(file); + }else{ + fstream = file; + } + + + }); } From 206f8cfe1fb413793cdf3110692fe57bf4e619ad Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:12:51 +0100 Subject: [PATCH 064/191] Added error resolving --- lib/Client.js | 11 +++++++++++ src/Client.js | 28 +++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 21b4ce745..e5133c518 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -545,6 +545,17 @@ var Client = (function () { } else { fstream = file; } + + self.resolveDestination(destination).then(send)["catch"](error); + + function send(destination) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages"); + } + + function error(err) { + callback(err); + reject(err); + } }); } }, { diff --git a/src/Client.js b/src/Client.js index c350381b8..6d96c4401 100644 --- a/src/Client.js +++ b/src/Client.js @@ -545,23 +545,33 @@ class Client { } sendFile(destination, file, callback = function (err, msg) { }) { - + var self = this; - - return new Promise(function(resolve, reject){ - + + return new Promise(function (resolve, reject) { + var fstream; - - if(typeof file === "string" || file instanceof String){ + + if (typeof file === "string" || file instanceof String) { fstream = fs.createReadStream(file); - }else{ + } else { fstream = file; } + self.resolveDestination(destination).then(send).catch(error); + + function send(destination) { + request + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + } - + function error(err){ + callback(err); + reject(err); + } + }); - + } sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { From 20b970ee9d8c7f90f894496b4b328f4706fb2054 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 13:14:20 +0100 Subject: [PATCH 065/191] Added filenamesand fixed sendMessage error handling --- lib/Client.js | 11 +++++++++-- src/Client.js | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index e5133c518..6d6e62870 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -532,7 +532,8 @@ var Client = (function () { }, { key: "sendFile", value: function sendFile(destination, file) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + var fileName = arguments.length <= 2 || arguments[2] === undefined ? "image.png" : arguments[2]; + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3]; var self = this; @@ -542,6 +543,7 @@ var Client = (function () { if (typeof file === "string" || file instanceof String) { fstream = fs.createReadStream(file); + fileName = file; } else { fstream = file; } @@ -570,7 +572,12 @@ var Client = (function () { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - self.resolveDestination(destination).then(send)["catch"](reject); + self.resolveDestination(destination).then(send)["catch"](error); + + function error(err) { + callback(err); + reject(err); + } function send(destination) { diff --git a/src/Client.js b/src/Client.js index 6d96c4401..ad7084d90 100644 --- a/src/Client.js +++ b/src/Client.js @@ -544,7 +544,7 @@ class Client { } - sendFile(destination, file, callback = function (err, msg) { }) { + sendFile(destination, file, fileName = "image.png", callback = function (err, msg) { }) { var self = this; @@ -554,6 +554,7 @@ class Client { if (typeof file === "string" || file instanceof String) { fstream = fs.createReadStream(file); + fileName = file; } else { fstream = file; } @@ -582,7 +583,12 @@ class Client { message = premessage + resolveMessage(message); var mentions = resolveMentions(); - self.resolveDestination(destination).then(send).catch(reject); + self.resolveDestination(destination).then(send).catch(error); + + function error(err){ + callback(err); + reject(err); + } function send(destination) { From 38e81c23c9bef1d5ad63064b41d79c2c8336e54e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 14:00:52 +0100 Subject: [PATCH 066/191] Updated tests and added file sending --- lib/Client.js | 15 ++++++++++++++- src/Client.js | 27 +++++++++++++++++++++++---- test/bot.js | 11 +++++++++-- test/image.png | Bin 0 -> 14150 bytes 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 test/image.png diff --git a/lib/Client.js b/lib/Client.js index 6d6e62870..7d2c96445 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -551,7 +551,20 @@ var Client = (function () { self.resolveDestination(destination).then(send)["catch"](error); function send(destination) { - request.post(Endpoints.CHANNELS + "/" + destination + "/messages"); + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", fstream, fileName).end(function (err, res) { + + if (err) { + error(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + callback(null, msg); + resolve(msg); + } + } + }); } function error(err) { diff --git a/src/Client.js b/src/Client.js index ad7084d90..e2e99d0b9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -558,15 +558,34 @@ class Client { } else { fstream = file; } - + self.resolveDestination(destination).then(send).catch(error); function send(destination) { request .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .attach("file", fstream, fileName) + .end(function (err, res) { + + if (err) { + error(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + callback(null, msg); + resolve(msg); + } + + + } + + }); } - - function error(err){ + + function error(err) { callback(err); reject(err); } @@ -585,7 +604,7 @@ class Client { var mentions = resolveMentions(); self.resolveDestination(destination).then(send).catch(error); - function error(err){ + function error(err) { callback(err); reject(err); } diff --git a/test/bot.js b/test/bot.js index e0c2eb940..b04c7ac29 100644 --- a/test/bot.js +++ b/test/bot.js @@ -79,11 +79,18 @@ function success12(_server){ function success13(){ console.log("test 12 successful"); - mybot.leaveServer(server).then(success14).catch(error); + mybot.sendFile(server, "./test/image.png").then(function(msg){ + mybot.deleteMessage(msg).then(success14).catch(error); + }).catch(error); } -function success14(){ +function success14(msg){ console.log("test 13 successful"); + mybot.leaveServer(server).then(success15).catch(error); +} + +function success15(){ + console.log("test 14 successful"); mybot.logout().then(done).catch(error); } diff --git a/test/image.png b/test/image.png new file mode 100644 index 0000000000000000000000000000000000000000..253ecefb0f2dd7ba51fed4be16ac338c2348ffe8 GIT binary patch literal 14150 zcmZ9zWmH?w7d0Flf);m3arfdDN(t`nr4)B}cXy{iahKxm?k!T>i@V#C-~YoaPu9v! z?p>3UxpQas+2@=+5lRYD=s;p1002OjhJ0250AQH^dm|%4uXy;xxqXJbu5LWuC6|vXjN?i^W6Z^mJo&BkmW`0Gdd;{IU*${ zqzQM_Q|ZD90H6d&e->AB&pusq%TE5&DS9#OF?LhmS)J1XDGq5QcvO^bc$!w0PR^_9DvwX$iasmE6iI7f6-;{%WH zxf$nKixG%!2mI4qPF+qB<3GTsKL0Y+ zjsv!)hOy05X0HV73PA3RBS$5j?1(#s7qtcPW9j#sSG&ps%1*wre~NCw_s=b;S= zP9{|u(=$tm?-(Y8Ghs~c>uF^Gna06uh>ZtWS& zsS=k#VfaidrX2rq_o2=ipo+^r)PwF67W}eux`hvi0-Qu7LK7u5^x^~^hv7++p#uR?F>?6ItaB|MapfhP z@?u{5`4JaaWYCWSOMw=P6D+WS>j8_&`n0KmBXO;5m&xtt;t?qxb&@`Q1SarRO8F6c zYpXi&)AN+>m+rI*Z~E3Yb^v{(7Nj>a{$;ooM*dGI^elbcdzaa0&GDdIzPx--TlL@M3ZdOXY4>Zgiv8oZW7Ji-z3r>uco-!f0yL`Ihn(i<42%0l8%(X{ z)yLUInAM~=KW<`3_%$gq3Gb?d(|9L;Ydx85*NzRFNq|o@gLo#EOt=$Av6##(ld0it zPP1I>ii`eaHEPi#xw<+FFDsd}yc|h>{+`}{df7#P#Zqe{v)vOnNsA>Iz=MFo z0FM?~AjTQp^-A({amhh)1k`Bx2xkebEr(>2 z#Q!FxF5E0cnq3NU)f>N}-Qu--zmUbQk90MnEM%8v0D&sHJf6c0>z{N|k(h^)88VA2 zelIIP@)Kvc^-bk6zTT!-|8q{mG50b719jV?$5Av4ho6X33!-swYmphu!N}~AL}s@x z%sG6X*EJfk%AJ2@h{>o6FUm4eg=}Lxuf0q(wO!Dyth9(lGoGrE8Spt(_p3|}e<8AJ zCw*l2_CW=$P%h1bsm9m_J!;ews1b~dgaVLT(Dgu>u{;mm!%iKjEw(kETLUOO9C3;pf~yeChec2 z%@^}z6mCRDVerO2ZAy`uoRtnKR1C9QRItmOt#n^m%0|2|Ye zc0fCRt}RuEKpblGvvu23XT}KVf_KR(#ybY*iK%fR0xV(iA1Ohg>@{d((6R(f6xKE& zbVNY0#x^|#{f@{CtoUgjQ6)UcVvL8AxhS9zd7bXe_{`v7tl>O=NvM6|QL`h=RgE9xM8ofd#G~ergQPds1h;J=nA_ z=@gY}rz=^*JQN*=!}oD_lm%?+1)`$N<8Fe%g>)n0%KmwZ=bB361ko@N$znpIm@hfy z?BuMklUR_X!=93KZ9R((l{6oN@~m}px@arqE}e1B9>H>&Mo zemj#Ccj!e@m?+pnshQ_}n92efzJs{S$p%&LDgV5L*Rr65E#wS>y>fSBJosd5y^bSk zMU9dIv*nM`Tn&4YWCp1p2n~}adEi$P8vP(^|BtwT(~@H9hhEVB5PK#uIE-cFM^iIZ zEQ=tOR%;ikaW_z^LrQMDeKAI4TNv?`IM5e8sNBcgf^{%Nl>`8=(MPfV`=K|C!fo^C z6r+*fBB6c!ml>F9Y@F@KRqgT+$ z6tH(JQ2SM%V8JG?XBWGzxaU~IrX?s~UL8Ty&z%Nw@xlJ@lFTpelmhOP(7$ma6=N!x zjIzS%+)cm;>f!1I`gPqup(!M7wH3lB>M%mKc$s6R%jv`PMtfz>KaxK~Z&BW!8x#2T zFM~QEZvmRR>AG*Xf}$aCeBsy5T8hnsyB7st+C>ZAgV3_q@v`XaxbevQb(~2zhV1)U zXpWCoYZ;PlS|kn$Y`RbvkS?y$e`BTF>#9Yanj;A#h-AcLI39M?}9Dmgj*3~TmpQ%KQs4UUhcCBJrA)~t`i5~ zVsH7Qif>$Yu03x^G0cl|3(wJms4-sJlQ~~EOuyU32CaJ!&5^AGO_T`pO3{F_Zoy14 zp2>>FCt}@m3G73g4rLcDY7hX4n^c|inn24<4B>`epp!y{T zZTP6@K~5~9wp(cg>#X$&J}TqD{0Oa&N0s^Rd;&R_5C9YfB^b-tvvSS`i7yha>UjRD zV*Uqa&+9#(-5jTGmJO-qFfWIdSI_$f8$UoNKEaJ3#~ROxfQ=IC-uIb1fqX0KGy2V- zd?8vuA&4>+8atOX1O<`u z-#pfp1@fbdT8f8~_VyR(a!e^QfPWRxYXi!wZqDJFXHaq~Vf$ME36YAvCI0+L7tl$D za$*ygU&R%1mkTf8nHWw3PiQj3?MfNWkU=>_xVeDq4hG7xUd{=6U2d;<%Ol9bW zr53B0>%0@VaxWm*pVH86I+^ioj}ETXe)C{z0l*r>6iboDCTrZcs#0iFvjf1e&jL85 z4A+}O%T(;9-Y(sKqM7WM3rJpd_LmsH+)A*3=ExMQ-lMqC>4eP?u$~UX5a6#UCEtqF zkAyI@iuKu4`}>hZPe`6(*w>w}ETPWm((h`NWi@vuCndg34RjGuxcb|^t<}vE=%P!t zG>b1~H{svspQjnNl2W~9!6-5E!x!JGS@Pm6Q{i`tm;LN-@$^smO&g6G0D9DRhc)O8 zY+D3fz9f>lZ{O-8Kl4C=3ZaU$)>-J@s@wfpS@O?!6k8n+qTvL9rzd)_H{-q@H>v87 z=IyiFN*lKO{_Ux|>7j@{NSWA~44G2}mNqS%PM)whSXNWnaBFBJ|BwMQ#zp+M=3`}R z8R_yL;{FBwPOa`LB&$zuCWdA}L<0Ncu>fUJ%C&E2M?BESl+9a)c%VQOJfbbJl_wh4}J|NU6e7j0WPdA3BIvhn0TX zXFf4f994Mpy%t(htC0FA!!hwXe|=pbuUx?w*H!fFN|Du6`rsN6H^e zvFn+fb|Y$!@G9_TvjCC%p%o^TyAd4Me4o!Jl;`vMs^9H9y^B5F*@Yh0RZj*`B6bEPaDIr$gaTBw z9frx=lI1V%G&1C`yCbfRL$%vGuFTq9m|6Fq^DEHAf5bv(C~E-!0p=io5+a#XPuvaB z!!_6O#nqg~?_{q${6q6?IvA@+uB_k;d6>wia%P&Dzd1e0sg8R0k00n!+G3vs!4PKM zl~7TkMigOXI4JA|_s)`V&2TbDqx@uKcaWobF#xIzGp>1)Mo;I?`gf9XbX@j|{09Ob zIdIyBF1p#Qd!y{mhyD<78-ry{ySpbPV8{%+I}mWbG;cRYeWFa=mDFCT_cg{K0~-^u zQhS=vb~#GpOy$hY)NELsM(@Na+Vspd=3M+^Y+?9-Z1r%mE0FD=!c#u(6T74i+F$@m z=oe8mOp%15mS7B}=6vXQSYWMOT8in+k$$i!eQUTO^bDGL-tvuYF_)+7Ydx2>T$>_xki$LSWZ_p1Y3LOS8&~w7}p-4=|R&Th;te*-=7@vpeG_0b%8oq{11QxtPGMvcb0m}frDEE=}4d8QC#E`^H0 zUnq^QmLiEK<&4*x1r{+a<~mfV)wcbzcBg$liq-?DcBe!4-9q>h$3d^YRmUQtuu*A^ zeY^FBQ4P}XNL}Gt`?%^)i?6*IrHI6tc2?|8=8dnkF7E8yCGHdDE|hRn7*R?#bk;igll_7 zo5&V<2p2@U`GWp((`))K#$na>8a|p(=c@^;v|kycgp&!OXxkgL^*T}Sk6gXDn%5Wk zmu-@gy9z`h8!%a}em$IC_{Zg@jJtkET-G_JXf_eA5o5poQ@rPkdpFlD*|gZ62nku6 zaT20*sDFK^sZs2S?Npxd+NGM{t9mPyErS(7Ps`>Z?Dn&yVw73^otA>Y-OnEN^p%!1 zL&t9^q_J=m%Nc^Dls9F&HaJMXDrw|?di+hdHYA}1)QJXEyT{4*=>RzWlx_>4?VeuMl}?Sw+gO4O*t%oY=TGX?T7Skn?S`qfKE z1@Mt7`)n(@YJaji((W3Or$tU@>jb$c9tbeu*ELP3mOMMi5W$*+hA8VEPP=G?_siud zg_-w_xO^gwfL(AfLi=|j|MhQ~i)20U$G7>5UgO`IPw|{lMrw@X^hRVztkiwJ1hlb- z@4Y3#q$k^D=;1WLMs0JlD6go~!|(>(kAn_(qkpvdt8;KmE~ywdo$Nw`ne%cDj>p>? zOZFjRbrvo2tkEz~$B;C=(ZP~Fa_Qp{t*!6Z^M#k{|GL@ggAWR!?p35J`vw81dPgdB+3 ze^pYBt>a-gZ_W8k^zgn)>tL-JLPsSCGvD43vxEgCn)7LbarnB5d^D z+jUOPw^KFra^qVZ6EW)Vo7|aWV)dmS_Jrz16;xGhoylX;*pS zGGdgV{cpEnw=hhLJinP~rf4#c;poxHeWzW)vBQUSe?F#QA3kb%Txe4$)u%VYR48eX zv*$s%22sf$iK5X0>hVls870j#mS~^)><$WzUguU>N(*2#k@%!|qEFip6wD%_Pv+Ik z$A9!l0C*bqC+=H1X^@q7DZPW)E6N90K+>?f8Acg>@Hes}=ku^&ko{Dd3v^~N7zJ5L z&|@Cq6Sy7x^moBU^WTKsQ7GJ}tW%h&+1XXb3!g6&kopXBOpnH@thz4_Cy!5qPvQlJ zvc@2VKm4%Ayj0Cy+Ezq}l;pe|4&M+~1qNNeRyj~H=9MwRhj9g^qVKJS&f{d0)KLS1 zP~}Kvt&k#ay~)w3h+&sjh{CG*FHz^79Bs$%I29B`;vzw}`6r@;U<~7{2g?D~L+$g{ zx08d#2ct}!{uUcF)x1_vxRQS{7nT(I)ZDB;=Try3G}RP;4zX%r=iDe?+pn)+PoiT#I41U zkfAgMX7l}GUexAi%@Jl`)}IggljSx0HwA3>8-7|&VnHpBy3|A|1!*Tsf>2l}Iu8yb zXswAZ^nTIVPEKV~T#Dc6$-B~8hQJlqRU>}5r`5=XDGr1Z0DpwhSC|Vg{bR3_4I5yFwLkT{y0eLkYSkpAZ@Iv3;X_1ixZ=6 ztLOe5U4iJZqpDJoSUJFy!mTImIC>Xk1(%BJueLcrb|;^-6C9fNbBau_tqsSCVg;?a zni6+rGr@Addt^fQV)QwW-hXj&)1@Ll{$a;S@S;!f*}lJ$7OiYDuHU!_p4`VmFxT6J zLIzHt&-XSjE;0D!_koN$pj#8hM9hmiWaGt@iZ%|oW5`B^*uBWVG5IrdERU0~W)+gb zdW}EUT{AC~071$Aw7{QrD}43xY4vghQ7xDU-iMJoExy1H1zhm4k}6~O;cQji-ArAo z+75|9Vl(W%dO-HPsi62bLh}&ilZRrUY$;kPlaujns=>?Vy82SRVCJ#zQS)3aUFV{p z&E1YAGyoX1nbLDnVg!%GeC$(v@~)lP)YS{sAKrk zW{&zPfBO%uz@5eS2E;1;QRk{7_cJLVGHCOj9zq1${N})N=Q`lzsyO^{bKaqE276e+ zt`_@GEk*z;G{}fKINp>OZ0NR`*EKGiQw9^a{EL@o5rjIsX{S1>+pNR*ZmmpIh_W~l;$hB|WS{29Y z?LSYolr~DP-tT$RGBAiJ-BP`Z6b2SvFn(__Ia>AgWJTiW;BV)-dc+dcnSDXmi_4y( z!&bj9IK_-(kB91sPs3colR5b^kq+FP;!z`@oDfEx=E>hmJxnGu(-xo2(=^NG9yfyc zf6M{ZQoD@BS0LntIJMGz_$WrdX>Ijwa{kz567HqtNY; z0=$rA+m~;%!mawi1?$t^P#fXYjd?M8V1EnFSOSEf-UvzwPx*sCLgCf~k}a#2;)yk} za~ssY^7X-8mq3V>X3Y)3Dlr+>xI45t^<0wE^pr!5qS8i+*%lC=x{;)7;{NJ$9CRUu zUWQ3U&YSI&iDC3ueD=6jkqsvuWTNFm^y1OM{PlP$_og>XrRPY*Ap~Yc_vgP8>AZzL zor9y8(+e+7RYK-=napaK^D2ws?zgBx0^+>3BQXJdzN(b3pmEuvi5CahA%7@tKd(uq z`K@B;4~kCSG({RaTCd^NF&hnH(=OPYhU%I%ttOQNo&`+8Kcfe~JhmIPRnNs4iG?u) zQ{jVGl&7wni4#yc*S6NR(l(Bf+)j_-Ot8UAPCB)?uvu<*Mpq9yvIe3F+_TF`!3CUN zXAv+F!4Yd!KFH{k=Z&E;e|)Vs2ttlj;@+Mi1Js7$tCB&` zeADNyd%HI7!UMx)B{E|`%Vuisb^$$FbkTX(@`bT68rIxjud&p;4fL8R$`EK-E0iU7 zQLJSD8#_R{|8o!=zEIdJtM$eTlD^hEOe!-OX~lSFs=macT8j&UwCd88DF~(%D51S% z@;Zn}PimiE@H;3rmztYrgP>T;aO(OMWho5il3GgLgL09dzxY!JsV3&-h@*X!VE=qlkSgE(O@68YT~_&6$DxgH_SLB!$P)Ye|56Tu zUq63QC!ESy4X=j4J}<6oCs7M{Vn0kI8>eoly0lW@NNG@JaMt-@R#?+PVET8FpShzc zEGDV7n0{+K&QtYEl2-yM;56_*88$FwAWHd2zAaYYJ)ivEDrI%)<(_vctk0pOdHO2t z?W!W2iMTTF{d6^vR9n({E@r5@fJ1%f@|ojcdp1@8T+ziCFCxK-IVRnm7*ZOV(p&V) z*}<;qv6EF#^qSgwgG8Dw5Pw-d+v(nbaA`9qikq% z&K>91zO9!0z(buxduNA~lmZ_>R@M2ikOs}ux+XK*wlqwwjUpzia0Ln%8==YbYjSYM!!oZ~UKJD2_WPYP z#fY$JW>A)^>&_yte19$CK{Uo$i4~Ahrt{Y`y*0Ad97x(&tmj8})*V@_tS0-tC~MzL z8$d_!=V3%H+(Uz@BJcMcCs^B#{pjqq`HLaPmou{;5>{pu1rfN^Ny9E|*su)q1M7DN zFAq-)=^Uo+Q)d>G&hn!ZgV_9RbW*Y!KZ!L$%ljPULte-F3|@{_ehmIfI<9jvgfH%$ z=ZW$?bHQNvph#$b{ICBuEp~9yPyi=0bLDdGg9OvXg`XeBo;bl@fuBfM%iYh??_6_f zpM`S!YV2}jr*pUjO76Lo_Grin)%xoNj8Jw(_9>w2Vrv1fg^aisKuLPD*=;L801ZQ( z2a*t*PR_nCa*>Fv={`^2GY5ZW&h2|T&7sF^<+u+c*c@+A96yaA{Wef5BlOTP&VJB0 zyHwkN^epgXboDAIMf#R2(6+PG(txz1P};L`mL0=T!e=)1XDb-imJkuiq?L_LN?idO2gd=nFB=bvwC{C`+Q>xpj)!)!^+?iSJCD{A9Y~B00KgCWPYZCQ zy;tWE96ui(x3es4dEjD^;o;I`aJQtD%?pJl^4c|3;zWj6GkiPnM~lCn`iW##pPF{o z)V-`bi*+^4lV|>>P2X0oywNq=+MV2aaQ{|&uz&UI3XfT7x9V+=3yV2v7@+#) z&yuHpT9@DWtheFAT-%C}iN3yaR{os{h$=xJ z3^C)$=T3f?Qo@UB%=&woX11`s_NS_p@pAKwA~z{%aLY1((pm%~6{*sjf_l|(RKtmn z;XJS*6HA`hee?2<`^lcX``e^V%Toc4!`Y!k{{C}WHG=iZ88UvyFATQsX4K3vCH$++ z*z??&JW*a*KeZHNKT$uCR0hGTZ;u>?k3RpN=`i^h9gO!q=)k~;4UtxS8gYU%&u<8C zHxt7xPk|rOIXsYs_|5C_D_8`*F4D|2Oh&_=|EuhIa0kB#*mjy)Dk!S|ecwxo>$Ma; zptw$%R^*i!y9r2X{dD}2P)dKjbtmfMKW6W#d=(Vu7c45=h?q8I-lvU2qO7{rp|70N z!;P?DYdQRqwy^WsScUwgSITlK0y2Jiuqrw5t~ThJvKQ?Mt+#dP89NC}IUozM z&DnaS$#O6;IcuiM@YSKR9P@dI^I8urW`u@w#_6zrKE80d-Y#6UF;%?>#hAmJZR|V* z4SBqoeO^p%J0ZMHMr%#vE&7a%vYr0$f7^HXe5}#Cu2ZD>{T6I;9GDFkV-x+E;>MHa z@B1CY^Av}#?aq4A_hqtObWExnf|UE2F5BNlFhz5l;VJCS#eG63ia-Rx@CJrWsMDQ| zWIw}_H#@jOjs6aNv1BC=n}m+rJ@2Qjl%n<-5-uoU{A4~s?1|^(cWoZNIIS4oDQL)Y z%29`)yzIN3_Z%5 z+xTgPii$KMLOJk-CpWy0fLe$+!2Db~uWcZxbt5ZQRp)A__RsVC6U@3^Bj%RanP{3+ zA1;DQ|`-6p@$BYQN3u^Jy_@c2SJNht(S#XaXX{>+K5W(@8WX zslB)=5qC;{`2-v*b!xRme-_hSLGeV8w8^pk)99^vDSGcg{%t~nIj~}}d24b{@N)e~ zgBl&?hwfmW<@@`gQv@xv_HDmsmc{WLsO-^@GTsoyyV=UyoL@hX)XgGJg7^9>G{~Yn z5HiujM&U^!+Il(BVPT1GMc-TX?)xd%%ZJLh-5wo~N1guGWE$OjFuQqg8BU9U&$1qk zP-FW=KZL+6S1n9c$CATQi$D3}(YXw@e5KxEWD&*bU?Qd~6*kv@#lvT3cg_t7mE!I~ zXrj)_jI<=SvQLwZB5bJ5-j>TR{twAt`{N&?pG{l<3R<3)Qur*dxYLhs4RMU+pJeS1 zD$`7&^V@kNwr<5=o>u0ad_5;hXjDk!gqw-44VU3T)MH#fBc8i`h{m0LfDv7#0gwqX zzRjVft)g^?zed~`jFJ-a^at~N^%1BMHtk-u##Tu9Y-(gd>W=er2)~ff(ba#h6w0u(wRSVrO zOW{pwLmdoK6@)utU)=a*m&9y;&)|Hm6Gf=mohnza1EH=k!e4WmdF^4>?CyTrkrnDt zut#son0WR?qKS1vQ*jt)R<%OyM}q7rMKgO|KOD;Dm+%JM>Iz(JwSB5w`5Pikrc5sv zFkIDF#1OWoz(>p*&kg?touT&xRbk)($0~1sIc=^!&UL4o!W&b(8)HyB=LA}3O5Zo} zd*eZ1Uf~#;!IRD_Dnr}o_H{IH9-xphQzT{UZbe}0Zif@Ry9NDQ+?rD_m0EgV;YQe& z#wm_h!b8{t5o98z89{sqgDfQo*Oemcu`#*TM=exUkWrFQou#msIvS8xTwP3{D7j#F z4E9n4>LEi_4U1J|_0tx9lk?mN1t>WF0|T>vTAaUdDG+Mp^1iAe>9#rY`d;-2A|tKw z|B!L0gjUhh`v}{f6HAf3?2ntL!PZ!iU4JdoTu4}L<42BKNHU~o zPMkSmdxjeU^aC}8#ui${oYf)#yGR0PK$v|nm|z%!KwnLbFVrFMp3jNlpH=@I$`;Ti zidjifG@YIe?&}MipUO~T^B575LUThkxq%#J5||ovV!L6A36m(YZaG&P9>p zh|vePGPZBq-*mdzz*Px14;mUGQM@CMFPsdzb#o&03W?M@J?A2KIW1-ps^Ew<<-Ye) zB^>%5!M!KOXikrrrx$acSVnF4cC++jzMn=1bmxVv>vZ8XzfG$^Sy^IU1t2h`pZ8+? zwku3q5xbP}erv}@_+eE(>f*lnli7WMskE0STJ!1?BeCU6JTqo)R*W^3q}5!7#QV0*^WxhJga%?xIXtV+-RCB^ zskZRm)qRX;!w^_PwZmaHa$ihcSJwjpL9HfFwl1%gik9O9JZO3JK}birTXZ-Ib^!p% zFyPi#-yg)OvF=mf@WS^q_yrX9Da+nH2%*Wkc&Nxy#=pW9^Mkks!?L~%uhRUB+20p_ zyx8%1I6IAU7`Lf0u``2JFIq3qp-r*5I|);V*z`%ns}wMw1Y%)BG1-6EaNYk}!EV58 znlRKDy{Ku|c(2W;Tw zEK4Wks`8p?1nG@TGm;Pa9|M!WoSu_7Y}YzYqzf@y)vPVx4M#S5)jo8dy8G!P;TF=7XwJB@r{)Q- zvFy88U9`;y>=wDXZr8Bce3tHsahTjoceRAeL`=&sU)`vo;SRf^aAWzR>xR802AbHZ zi%rIsu#$KW|F+ZwXxTW$hTtlp^(t-r6*%I?is8;Jr}i{ZoCqz7&?yp;A#+b4 zRNIJ}<>qW6`~A{|`a4*iNUtsO3HUC~1hDSP7osZKQJiGxiO_;eHaJFn5MuPspkad& z6j{yl{=~g@n4!E1AlR1-&zRSe=>^Jc^O;XVrjG-sfA$`@7(eIQz8q%6DXX3pW&Yuq z!9`4h5$$}JU*$ef8^A`~M!}hN2X^{MJKqh|)lh{B+xYy8ApR$tjs*s*&b5R8wK*DH z5Bxfrm|;U(NOOsT!$;q^3oB-v=>Woty!M0{$`~1%kqYXXu($Xd1Ji|apu#KM1t`Rw?3(xaOI#`kKnc6-Xk3H-*pre>oL%&OCPK zv(C%PVbu|YMsSJm4u6zhcY-a4Bd1sSJkPq0~tik zhTBud4^Xdz>P#2XoQ|C7{{J2NU*DFTkP&WMaa10%eUTC52R;_2YZ)$7iSi)fLglH5 zuE{R{pZi$Csx1|Via_n3lyAWR#?vrK$Sl@EHEp2Sy(|Cu=XW8r`vrQIov0V)jF>ewj_4^XDV2MzXaN&N{jZZ4`(gpkMkm(g2RHz?ym z3loWT@)}(tpw=N=y!aEz-ba%1awrHQOdt8*g5aLJqks&`jHT4Q{=RV2x(jV(}J-@s>4wp6L-3{LmGTb@Molp(~J< z{*4XaEGri`%9#(_%=_v5V1xfy6YZ)(CD2kw+ep!_Wx%jC13R93FhIqamVr9`+s;(? zrJuw@@}t|NCj{Ang&Hm>@w!7Nlljc0nZ{`Hhu|>+q@$ev`F^P2b6IU-GHK?xK91VW zC|@vwli7QM?2a|a!_7Di&WbA4<{BM0lw!$+1?(t}jDu}`xApcM*j}T>3_o=cc%EM* zG(6nof4j8SkmhLHF@Vc*umO`yubmK#6(65u53e|p^@<@&WR}&p+KbC`;L-F^dvt*) zrxRsIXDSBXMI;fNoME+e5km6rdY0g8`}V3?BU|{u2YTRCcUn$rg*CS7@x09E_v%Te zSn-etTT{`fsbfM?a$J8=_}sl!w59h>ZHHcBBUHUL_)Ja&wwt|vk-7Aqt#1B^ATI+$ zyT||fxcqoOdF17NR(ai$;VG|NDQeK`slkivb~QR}4^5DNtjVM#eyv z<7>KN_Y&Y$RkX-tI(Ve8uje!0vsS+f^ho1H?p-ne6^x6^0E2km?Y&d;?#kTVWVDW# zmR`22A6X6)d%DvoveCN!WeW&;U|1?Qw8Fz3`Fwy=Zim2rSK~5TtYjXwd(#E z3>z&zNAa|?DXN!lB;?V5nHom7Z*XhI@Ia$?MUQKij3l@#-vjFpz371FUn4VmPcMgH zF6u6WA+LfgHU^jVL>5PP)_Nq#z@ckDJD8q%?ImFO-{OK8ATR^8*zY5e@FzO!6_Bs* z;}e<66;>Rv4iaFa8RWU_+^r|X48Cu5Fy)%|pfR}XuHRqlkXHH&p=mv{q`U2QbRyiHe)#=xRC@jbLIPKtWcIl74TCC2cm6p8+737nX_uVmSg-p)aO^toVZdZ z)5zE*l|k@+*1a7}nC*j8V*IQ|WQfmcS#JW$nH>r;`$?I<)0OC56S5N%Ife>@hu*s` zs`{<{kJ_w`fBA3YyYxN5bP{#vhDjCG4=Feh=BCW$?gMC3F>T;#{R?aVQ@fjJ-A|?{=-(miM|i!vWEuTMvn8fj@~9*?@|h{{mxRFRaGzhv zqn>v@;Z8lu9>N&{P5#0`Jq2*7z^g_`u`sdQY$TX@95bIj{^t=2sI~6mjo&a8`~t!4 zF}VD%2e7E;?N0}QuHBo??VKzp@Cb*t^Z6gYV72d%QNe6aUs$NI$dSJ18gG4*E4AK9 z)AId}`9%h!4=UgGH?9X+Hn(Btx!<;aW#a$WaHbEbYpLzudPPabs(U~gBQ;#TgJbNV zEXsdBn8@vLn|fS@yb^=I+chJhD))RW91-?-=h-kZT9jp&^rjG>IA8q$wywMAs-VD^ zn@Ug_y1I`?{qMO%mz=$BZ=^F!C$Fx)Nt?aYHNjbU5rMXhww^d*H; zGgF0i<5Zv?{3S{9-p2v^U>{XZ`MRi^3;^xlh_R5z2Ep_};Jf&|keJ^WEE_TCo&-lN z#kKpv;|aABT8PI@(n8fnWdL-@cSmx)H~+T6p1h+l2s#M|LjG&2rnn(`0HU3+Dq`2g zlkDAE3He2V52D5tdfaqT6ouZ4i=O?;ebh$We+INJO3u2!hqF)m6=sFq*&_eX!UWW6 zrbS?upFA(->3>@<9QATNH~%upPx%#D+5)2YpxPivvj7WCGA1RB_DS%8=TSDG)W*2{js$wKjef@v$0{d@MSR&jzg-Osg W;m literal 0 HcmV?d00001 From 05a3c7f1656bbedd8dc56b8173a440f41f718296 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 14:01:04 +0100 Subject: [PATCH 067/191] 3.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de833ea73..cfc032ca8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.0.3", + "version": "3.1.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 1176ca702218063eba7ab3caff5290c36e432310 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 26 Aug 2015 16:48:29 +0100 Subject: [PATCH 068/191] added toString --- lib/channel.js | 5 +++++ lib/server.js | 5 +++++ src/channel.js | 3 +++ src/server.js | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/lib/channel.js b/lib/channel.js index d3c3d2dc7..89eb76ffa 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -61,6 +61,11 @@ var Channel = (function () { return null; } + }, { + key: "toString", + value: function toString() { + return "#" + this.name; + } }, { key: "client", get: function get() { diff --git a/lib/server.js b/lib/server.js index 9c9903843..5bf3beca1 100644 --- a/lib/server.js +++ b/lib/server.js @@ -137,6 +137,11 @@ var Server = (function () { } return member; } + }, { + key: "toString", + value: function toString() { + return this.name; + } }, { key: "iconURL", get: function get() { diff --git a/src/channel.js b/src/channel.js index 4b92e834b..1f446d074 100644 --- a/src/channel.js +++ b/src/channel.js @@ -33,6 +33,9 @@ class Channel { return null; } + toString(){ + return "#" + this.name; + } } module.exports = Channel; \ No newline at end of file diff --git a/src/server.js b/src/server.js index eba1b2e14..248a04683 100644 --- a/src/server.js +++ b/src/server.js @@ -84,6 +84,10 @@ class Server { } return member; } + + toString(){ + return this.name; + } } module.exports = Server; \ No newline at end of file From 2137981bb98ed5fd6899904c18ce5b6bf87bed2b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 27 Aug 2015 12:43:25 +0100 Subject: [PATCH 069/191] Added the new gateway capability --- lib/Client.js | 32 ++++++++++++++++++++++++++------ src/Client.js | 36 ++++++++++++++++++++++++++++++------ test/bot.js | 12 ++++++++++-- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 7d2c96445..3ff17e858 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -120,7 +120,6 @@ var Client = (function () { var self = this; - this.createws(); return new Promise(function (resolve, reject) { if (self.state === 0 || self.state === 4) { @@ -143,9 +142,15 @@ var Client = (function () { } else { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token - self.trySendConnData(); - callback(null, self.token); - resolve(self.token); + + getGateway().then(function (url) { + self.createws(url); + callback(null, self.token); + resolve(self.token); + })["catch"](function (err) { + callback(err); + reject(err); + }); } }); } else { @@ -687,13 +692,13 @@ var Client = (function () { //def createws }, { key: "createws", - value: function createws() { + value: function createws(url) { if (this.websocket) return false; var self = this; //good to go - this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + this.websocket = new WebSocket(url); //open this.websocket.onopen = function () { @@ -1413,4 +1418,19 @@ var Client = (function () { return Client; })(); +function getGateway() { + + var self = this; + + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); +} + module.exports = Client; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index e2e99d0b9..0fdc18539 100644 --- a/src/Client.js +++ b/src/Client.js @@ -132,7 +132,6 @@ class Client { var self = this; - this.createws(); return new Promise(function (resolve, reject) { if (self.state === 0 || self.state === 4) { @@ -157,9 +156,16 @@ class Client { } else { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token - self.trySendConnData(); - callback(null, self.token); - resolve(self.token); + + getGateway().then(function (url) { + self.createws(url); + callback(null, self.token); + resolve(self.token); + }).catch(function (err) { + callback(err); + reject(err); + }); + } }); @@ -666,14 +672,14 @@ class Client { } //def createws - createws() { + createws(url) { if (this.websocket) return false; var self = this; //good to go - this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + this.websocket = new WebSocket(url); //open this.websocket.onopen = function () { @@ -1106,4 +1112,22 @@ class Client { } +function getGateway() { + + var self = this; + + return new Promise(function (resolve, reject) { + request + .get(`${Endpoints.API}/gateway`) + .end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + +} + module.exports = Client; \ No newline at end of file diff --git a/test/bot.js b/test/bot.js index b04c7ac29..f11b4a015 100644 --- a/test/bot.js +++ b/test/bot.js @@ -7,8 +7,16 @@ var mybot = new Discord.Client(); var server, channel, message, sentMessage = false; -function success1(){ //make server +function init(){ console.log("preparing..."); +} + +mybot.on("ready", function(){ + console.log("ready! beginning tests"); + success1(); +}); + +function success1(){ //make server mybot.createServer("test-server", "london").then(success2).catch(error); } @@ -123,4 +131,4 @@ mybot.on("message", function(message){ }); -mybot.login(process.env["ds_email"], process.env["ds_password"]).then(success1).catch(error); \ No newline at end of file +mybot.login(process.env["ds_email"], process.env["ds_password"]).then(init).catch(error); \ No newline at end of file From 70b20b74673e8fd0fc8988c15ae9fb4449b312d6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 27 Aug 2015 12:48:16 +0100 Subject: [PATCH 070/191] Updated README --- README.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a6360ef6..9b7fb74f9 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ discord.js is a node module used as a way of interfacing with [Discord](https://discordapp.com/). It is a very useful module for creating bots. +**Updating to 3.1.1 is essential as it has new changes to be compatible with Discord's API, +and to make sure your application still works an update is a good idea.** + ### Installation `npm install --save discord.js` diff --git a/package.json b/package.json index cfc032ca8..b653297ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.0", + "version": "3.1.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 96846654df06226354f981f6527dac5efaa18221 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 27 Aug 2015 18:30:14 +0100 Subject: [PATCH 071/191] update package references to new home --- README.md | 2 +- package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9b7fb74f9..9043677f8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # discord.js -[![Build Status](https://travis-ci.org/discord-js/discord.js.svg)](https://travis-ci.org/discord-js/discord.js) +[![Build Status](https://travis-ci.org/hydrabolt/discord.js.svg)](https://travis-ci.org/hydrabolt/discord.js) discord.js is a node module used as a way of interfacing with [Discord](https://discordapp.com/). It is a very useful module for creating diff --git a/package.json b/package.json index b653297ed..0ed47ba64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.1", + "version": "3.1.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { @@ -8,7 +8,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/discord-js/discord.js.git" + "url": "git+https://github.com/hydrabolt/discord.js.git" }, "keywords": [ "discord", @@ -21,9 +21,9 @@ "author": "Amish Shah ", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/discord-js/discord.js/issues" + "url": "https://github.com/hydrabolt/discord.js/issues" }, - "homepage": "https://github.com/discord-js/discord.js#readme", + "homepage": "https://github.com/hydrabolt/discord.js#readme", "dependencies": { "superagent": "^1.3.0", "ws": "^0.7.2" From 6b3cbdbde8f065f0b95ef860bf51f7858b6dfaae Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 27 Aug 2015 21:21:35 +0100 Subject: [PATCH 072/191] Added web and grunt scripts --- gruntfile.js | 48 + lib/Client.js | 4 +- lib/Endpoints.js | 2 +- lib/PMChannel.js | 2 +- lib/channel.js | 2 +- lib/index.js | 8 +- lib/internal.js | 2 +- lib/invite.js | 2 +- lib/message.js | 2 +- lib/server.js | 2 +- lib/user.js | 2 +- package.json | 7 + src/Client.js | 2 +- src/index.js | 8 +- web-dist/discord.js | 3335 +++++++++++++++++++++++++++++++++++++++ web-dist/discord.min.js | 2 + 16 files changed, 3415 insertions(+), 15 deletions(-) create mode 100644 gruntfile.js create mode 100644 web-dist/discord.js create mode 100644 web-dist/discord.min.js diff --git a/gruntfile.js b/gruntfile.js new file mode 100644 index 000000000..2cf6001aa --- /dev/null +++ b/gruntfile.js @@ -0,0 +1,48 @@ +module.exports = function (grunt) { + + require('load-grunt-tasks')(grunt); + + grunt.initConfig({ + + // define source files and their destinations + babel: { + dist: { + files: [{ + expand: true, + cwd: "src/", + src: ["**.*"], + dest: "lib/", + ext: ".js" + }] + } + }, + browserify: { + dist: { + files: { + 'web-dist/discord.js': ["lib/index.js"], + }, + options: { + browserifyOptions: { + standalone: "Discord" + } + } + } + }, + uglify: { + min: { + files: { + "./web-dist/discord.min.js": "./web-dist/discord.js" + } + } + } + }); + + // load plugins + grunt.loadNpmTasks('grunt-browserify'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + + // register at least this one task + grunt.registerTask('default', ['babel']); + grunt.registerTask('web', ['browserify', "uglify"]); + +}; \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js index 3ff17e858..15131d074 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1265,7 +1265,7 @@ var Client = (function () { key: "trySendConnData", value: function trySendConnData() { - if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { + if (this.token && !this.alreadySentData) { this.alreadySentData = true; @@ -1433,4 +1433,4 @@ function getGateway() { }); } -module.exports = Client; \ No newline at end of file +module.exports = Client; diff --git a/lib/Endpoints.js b/lib/Endpoints.js index 271b465eb..e55f0f580 100644 --- a/lib/Endpoints.js +++ b/lib/Endpoints.js @@ -10,4 +10,4 @@ exports.LOGIN = exports.AUTH + "/login"; exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; -exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file +exports.CHANNELS = exports.API + "/channels"; diff --git a/lib/PMChannel.js b/lib/PMChannel.js index ae44d3d60..232b83d1a 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -58,4 +58,4 @@ var PMChannel = (function () { return PMChannel; })(); -module.exports = PMChannel; \ No newline at end of file +module.exports = PMChannel; diff --git a/lib/channel.js b/lib/channel.js index 89eb76ffa..f413e03ca 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -76,4 +76,4 @@ var Channel = (function () { return Channel; })(); -module.exports = Channel; \ No newline at end of file +module.exports = Channel; diff --git a/lib/index.js b/lib/index.js index fa2343ae4..f0c3c0ab7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,5 +4,9 @@ var request = require("superagent"); var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); -exports.Endpoints = Endpoints; -exports.Client = Client; \ No newline at end of file +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; diff --git a/lib/internal.js b/lib/internal.js index 3acf5940b..e8b3385da 100644 --- a/lib/internal.js +++ b/lib/internal.js @@ -200,4 +200,4 @@ Internal.XHR.setUsername = function (token, avatar, email, newPassword, password }); }; -exports.Internal = Internal; \ No newline at end of file +exports.Internal = Internal; diff --git a/lib/invite.js b/lib/invite.js index 5f51dc1a9..7bc8204bd 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -32,4 +32,4 @@ var Invite = (function () { return Invite; })(); -module.exports = Invite; \ No newline at end of file +module.exports = Invite; diff --git a/lib/message.js b/lib/message.js index 24c54fbb3..fed46083a 100644 --- a/lib/message.js +++ b/lib/message.js @@ -69,4 +69,4 @@ var Message = (function () { return Message; })(); -module.exports = Message; \ No newline at end of file +module.exports = Message; diff --git a/lib/server.js b/lib/server.js index 5bf3beca1..5891d36df 100644 --- a/lib/server.js +++ b/lib/server.js @@ -170,4 +170,4 @@ var Server = (function () { return Server; })(); -module.exports = Server; \ No newline at end of file +module.exports = Server; diff --git a/lib/user.js b/lib/user.js index 2f363dd1e..282d63614 100644 --- a/lib/user.js +++ b/lib/user.js @@ -53,4 +53,4 @@ var User = (function () { return User; })(); -module.exports = User; \ No newline at end of file +module.exports = User; diff --git a/package.json b/package.json index 0ed47ba64..5725db81c 100644 --- a/package.json +++ b/package.json @@ -27,5 +27,12 @@ "dependencies": { "superagent": "^1.3.0", "ws": "^0.7.2" + }, + "devDependencies": { + "grunt": "~0.4.5", + "grunt-babel": "^5.0.1", + "grunt-browserify": "^4.0.0", + "grunt-contrib-uglify": "^0.9.2", + "load-grunt-tasks": "^3.2.0" } } diff --git a/src/Client.js b/src/Client.js index 0fdc18539..1993a81dd 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1045,7 +1045,7 @@ class Client { //def trySendConnData trySendConnData() { - if (this.token && this.websocket.readyState === WebSocket.OPEN && !this.alreadySentData) { + if (this.token && !this.alreadySentData) { this.alreadySentData = true; diff --git a/src/index.js b/src/index.js index 90103aa56..28df53ed9 100644 --- a/src/index.js +++ b/src/index.js @@ -2,5 +2,9 @@ var request = require("superagent"); var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); -exports.Endpoints = Endpoints; -exports.Client = Client; \ No newline at end of file +var Discord = { + Endpoints : Endpoints, + Client : Client +} + +module.exports = Discord; \ No newline at end of file diff --git a/web-dist/discord.js b/web-dist/discord.js new file mode 100644 index 000000000..e6ed8a595 --- /dev/null +++ b/web-dist/discord.js @@ -0,0 +1,3335 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var mention = _step4.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + return _mentions; + } + }); + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.guilds[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _server = _step5.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.private_channels[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var _pmc = _step6.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = data.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = info.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var mention = _step8.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener.get(data.id)) { + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener["delete"](data.id); + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = data.channels[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var channel = _step9.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; + + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +function getGateway() { + + var self = this; + + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); +} + +module.exports = Client; + +},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; + +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; + +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "#" + this.name; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }]); + + return Channel; +})(); + +module.exports = Channel; + +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; + +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; + +},{}],7:[function(require,module,exports){ +"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 Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }]); + + return Message; +})(); + +module.exports = Message; + +},{}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; + +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; + +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.js b/web-dist/discord.min.js new file mode 100644 index 000000000..435d52725 --- /dev/null +++ b/web-dist/discord.min.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}b=d+l(b);var o=m();e.resolveDestination(a).then(j)["catch"](i)})}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){ +return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 7300dec91220a4f7d0568c0ff17e044c2c448207 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 27 Aug 2015 21:22:29 +0100 Subject: [PATCH 073/191] Updated gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 763414655..693710211 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ hydrabot/config.json hydrabot/authority.json hydrabot/tokencache.json +.tmp/ + ### Node ### # Logs logs From 1c8c9d2da33b2b8f428d6b42bdfb3b9c840fdb14 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 28 Aug 2015 17:49:47 +0100 Subject: [PATCH 074/191] Join Server returns server properly Previously if the client was already part of a server and attempted to accept an invite to it again, it would stall and not work correctly. --- lib/Client.js | 8 ++++++-- lib/Endpoints.js | 2 +- lib/PMChannel.js | 2 +- lib/channel.js | 4 ++-- lib/index.js | 2 +- lib/internal.js | 2 +- lib/invite.js | 2 +- lib/message.js | 2 +- lib/server.js | 2 +- lib/user.js | 2 +- src/Client.js | 6 +++++- src/channel.js | 2 +- 12 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 15131d074..6f9ffb851 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -529,7 +529,11 @@ var Client = (function () { callback(err); reject(err); } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + if (self.getServer("id", res.body.guild.id)) { + resolve(self.getServer("id", res.body.guild.id)); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } } }); }); @@ -1433,4 +1437,4 @@ function getGateway() { }); } -module.exports = Client; +module.exports = Client; \ No newline at end of file diff --git a/lib/Endpoints.js b/lib/Endpoints.js index e55f0f580..271b465eb 100644 --- a/lib/Endpoints.js +++ b/lib/Endpoints.js @@ -10,4 +10,4 @@ exports.LOGIN = exports.AUTH + "/login"; exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; -exports.CHANNELS = exports.API + "/channels"; +exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 232b83d1a..ae44d3d60 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -58,4 +58,4 @@ var PMChannel = (function () { return PMChannel; })(); -module.exports = PMChannel; +module.exports = PMChannel; \ No newline at end of file diff --git a/lib/channel.js b/lib/channel.js index f413e03ca..f94925f0c 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -19,7 +19,7 @@ var Channel = (function () { _createClass(Channel, [{ key: "equals", value: function equals(object) { - return object.id === this.id; + return object && object.id === this.id; } }, { key: "addMessage", @@ -76,4 +76,4 @@ var Channel = (function () { return Channel; })(); -module.exports = Channel; +module.exports = Channel; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index f0c3c0ab7..6a2f82f05 100644 --- a/lib/index.js +++ b/lib/index.js @@ -9,4 +9,4 @@ var Discord = { Client: Client }; -module.exports = Discord; +module.exports = Discord; \ No newline at end of file diff --git a/lib/internal.js b/lib/internal.js index e8b3385da..3acf5940b 100644 --- a/lib/internal.js +++ b/lib/internal.js @@ -200,4 +200,4 @@ Internal.XHR.setUsername = function (token, avatar, email, newPassword, password }); }; -exports.Internal = Internal; +exports.Internal = Internal; \ No newline at end of file diff --git a/lib/invite.js b/lib/invite.js index 7bc8204bd..5f51dc1a9 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -32,4 +32,4 @@ var Invite = (function () { return Invite; })(); -module.exports = Invite; +module.exports = Invite; \ No newline at end of file diff --git a/lib/message.js b/lib/message.js index fed46083a..24c54fbb3 100644 --- a/lib/message.js +++ b/lib/message.js @@ -69,4 +69,4 @@ var Message = (function () { return Message; })(); -module.exports = Message; +module.exports = Message; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js index 5891d36df..5bf3beca1 100644 --- a/lib/server.js +++ b/lib/server.js @@ -170,4 +170,4 @@ var Server = (function () { return Server; })(); -module.exports = Server; +module.exports = Server; \ No newline at end of file diff --git a/lib/user.js b/lib/user.js index 282d63614..2f363dd1e 100644 --- a/lib/user.js +++ b/lib/user.js @@ -53,4 +53,4 @@ var User = (function () { return User; })(); -module.exports = User; +module.exports = User; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index 1993a81dd..21f5caa60 100644 --- a/src/Client.js +++ b/src/Client.js @@ -542,7 +542,11 @@ class Client { callback(err); reject(err); } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + if (self.getServer("id", res.body.guild.id)) { + resolve(self.getServer("id", res.body.guild.id)); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } } }); diff --git a/src/channel.js b/src/channel.js index 1f446d074..d32ab580d 100644 --- a/src/channel.js +++ b/src/channel.js @@ -14,7 +14,7 @@ class Channel { } equals(object) { - return object.id === this.id; + return (object && object.id === this.id); } addMessage(data){ From 07013fc4e32c04a7e315df09d2e18771051d3cef Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 28 Aug 2015 17:52:15 +0100 Subject: [PATCH 075/191] version bump to 3.1.3 --- package.json | 2 +- web-dist/discord.js | 17 ++++++----------- web-dist/discord.min.js | 4 ++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 5725db81c..fd5043bcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.2", + "version": "3.1.3", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/web-dist/discord.js b/web-dist/discord.js index e6ed8a595..2eb328b51 100644 --- a/web-dist/discord.js +++ b/web-dist/discord.js @@ -530,7 +530,11 @@ var Client = (function () { callback(err); reject(err); } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + if (self.getServer("id", res.body.guild.id)) { + resolve(self.getServer("id", res.body.guild.id)); + } else { + self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + } } }); }); @@ -1435,7 +1439,6 @@ function getGateway() { } module.exports = Client; - },{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ "use strict"; @@ -1450,7 +1453,6 @@ exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; exports.CHANNELS = exports.API + "/channels"; - },{}],3:[function(require,module,exports){ "use strict"; @@ -1513,7 +1515,6 @@ var PMChannel = (function () { })(); module.exports = PMChannel; - },{}],4:[function(require,module,exports){ "use strict"; @@ -1536,7 +1537,7 @@ var Channel = (function () { _createClass(Channel, [{ key: "equals", value: function equals(object) { - return object.id === this.id; + return object && object.id === this.id; } }, { key: "addMessage", @@ -1594,7 +1595,6 @@ var Channel = (function () { })(); module.exports = Channel; - },{}],5:[function(require,module,exports){ "use strict"; @@ -1608,7 +1608,6 @@ var Discord = { }; module.exports = Discord; - },{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ "use strict"; @@ -1645,7 +1644,6 @@ var Invite = (function () { })(); module.exports = Invite; - },{}],7:[function(require,module,exports){ "use strict"; @@ -1719,7 +1717,6 @@ var Message = (function () { })(); module.exports = Message; - },{}],8:[function(require,module,exports){ "use strict"; @@ -1894,7 +1891,6 @@ var Server = (function () { })(); module.exports = Server; - },{}],9:[function(require,module,exports){ "use strict"; @@ -1952,7 +1948,6 @@ var User = (function () { })(); module.exports = User; - },{}],10:[function(require,module,exports){ },{}],11:[function(require,module,exports){ diff --git a/web-dist/discord.min.js b/web-dist/discord.min.js index 435d52725..37ba4d200 100644 --- a/web-dist/discord.min.js +++ b/web-dist/discord.min.js @@ -1,2 +1,2 @@ -!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}b=d+l(b);var o=m();e.resolveDestination(a).then(j)["catch"](i)})}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){ -return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}b=d+l(b);var o=m();e.resolveDestination(a).then(j)["catch"](i)})}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this), +c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 0ce51f778163a86640a6a4d2e5fb6a538417594b Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Sat, 29 Aug 2015 11:58:36 +0100 Subject: [PATCH 076/191] Update invite reference --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9043677f8..f62b29c2e 100644 --- a/README.md +++ b/README.md @@ -71,4 +71,4 @@ Here is a list of other Discord APIs: ### Contact If you would like to contact me, you can create an issue on the GitHub repo -or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTY66OLO). \ No newline at end of file +or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTYd2XyW). From 8a1f99b049f0ff7b38e72e10e0a9ae2587c88df8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 29 Aug 2015 16:19:53 +0100 Subject: [PATCH 077/191] Added queue as a setup option --- lib/Client.js | 7 ++++++- src/Client.js | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 6f9ffb851..fa15db196 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -19,7 +19,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - cache_tokens: false + queue: false }; var Client = (function () { @@ -35,6 +35,7 @@ var Client = (function () { further efforts will be made to connect. */ this.options = options; + this.options.queue = this.options.queue || false; this.token = token; this.state = 0; this.websocket = null; @@ -60,6 +61,7 @@ var Client = (function () { this.serverCache = []; this.pmChannelCache = []; this.readyTime = null; + this.optionsQueue = {}; } _createClass(Client, [{ @@ -603,6 +605,9 @@ var Client = (function () { function send(destination) { + if (self.options.queue) { + //we're QUEUEING messages, so sending them sequentially based on servers. + } request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ content: message, mentions: mentions diff --git a/src/Client.js b/src/Client.js index 21f5caa60..ff8057340 100644 --- a/src/Client.js +++ b/src/Client.js @@ -13,7 +13,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - cache_tokens: false + queue: false } class Client { @@ -25,6 +25,7 @@ class Client { further efforts will be made to connect. */ this.options = options; + this.options.queue = this.options.queue || false; this.token = token; this.state = 0; this.websocket = null; @@ -50,6 +51,7 @@ class Client { this.serverCache = []; this.pmChannelCache = []; this.readyTime = null; + this.optionsQueue = {}; } get uptime() { @@ -620,7 +622,10 @@ class Client { } function send(destination) { - + + if(self.options.queue){ + //we're QUEUEING messages, so sending them sequentially based on servers. + } request .post(`${Endpoints.CHANNELS}/${destination}/messages`) .set("authorization", self.token) From c14b2fafb6ab16205819a88e17bee9d412d9a2c8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 29 Aug 2015 16:30:25 +0100 Subject: [PATCH 078/191] Beginning to move send message functions to unified function --- lib/Client.js | 349 ++++++++++++++++++++++---------------------------- src/Client.js | 47 ++----- 2 files changed, 170 insertions(+), 226 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index fa15db196..f832da526 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -607,55 +607,10 @@ var Client = (function () { if (self.options.queue) { //we're QUEUEING messages, so sending them sequentially based on servers. + self.addMessageQueue(destination); + } else { + self._sendMessage("text", destination, message, mentions); } - request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ - content: message, - mentions: mentions - }).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var data = res.body; - - var mentions = []; - - data.mentions = data.mentions || []; //for some reason this was not defined at some point? - - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - var channel = self.getChannel("id", data.channel_id); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - callback(null, msg); - resolve(msg); - } - } - }); } function resolveMessage() { @@ -668,27 +623,27 @@ var Client = (function () { function resolveMentions() { var _mentions = []; - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; try { - for (var _iterator4 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var mention = _step4.value; + for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; _mentions.push(mention.substring(2, mention.length - 1)); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError3 = true; + _iteratorError3 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError3) { + throw _iteratorError3; } } } @@ -741,15 +696,40 @@ var Client = (function () { self.user = self.addUser(data.user); + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = data.guilds[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var _server = _step5.value; + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; - var server = self.addServer(_server); + var pmc = self.addPMChannel(_pmc); } } catch (err) { _didIteratorError5 = true; @@ -766,31 +746,6 @@ var Client = (function () { } } - var _iteratorNormalCompletion6 = true; - var _didIteratorError6 = false; - var _iteratorError6 = undefined; - - try { - for (var _iterator6 = data.private_channels[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var _pmc = _step6.value; - - var pmc = self.addPMChannel(_pmc); - } - } catch (err) { - _didIteratorError6 = true; - _iteratorError6 = err; - } finally { - try { - if (!_iteratorNormalCompletion6 && _iterator6["return"]) { - _iterator6["return"](); - } - } finally { - if (_didIteratorError6) { - throw _iteratorError6; - } - } - } - self.trigger("ready"); self.readyTime = Date.now(); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); @@ -805,27 +760,27 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; try { - for (var _iterator7 = data.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var mention = _step7.value; + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError6 = true; + _iteratorError6 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError6) { + throw _iteratorError6; } } } @@ -870,27 +825,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator8 = info.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var mention = _step8.value; + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError7) { + throw _iteratorError7; } } } @@ -1105,27 +1060,27 @@ var Client = (function () { server = new Server(data, this); this.serverCache.push(server); if (data.channels) { - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator9 = data.channels[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var channel = _step9.value; + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError9) { - throw _iteratorError9; + if (_didIteratorError8) { + throw _iteratorError8; } } } @@ -1139,16 +1094,50 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var user = _step9.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { - for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var user = _step10.value; + for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -1166,19 +1155,17 @@ var Client = (function () { } } - return null; + return this.getPMChannel(key, value); //might be a PM } - - //def getChannel }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getPMChannel", + value: function getPMChannel(key, value) { var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { - for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var channel = _step11.value; if (channel[key] === value) { @@ -1200,21 +1187,23 @@ var Client = (function () { } } - return this.getPMChannel(key, value); //might be a PM + return null; } + + //def getServer }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { + key: "getServer", + value: function getServer(key, value) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { - for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { - var channel = _step12.value; + for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var server = _step12.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -1235,40 +1224,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion13 = true; - var _didIteratorError13 = false; - var _iteratorError13 = undefined; - - try { - for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var server = _step13.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError13 = true; - _iteratorError13 = err; - } finally { - try { - if (!_iteratorNormalCompletion13 && _iterator13["return"]) { - _iterator13["return"](); - } - } finally { - if (_didIteratorError13) { - throw _iteratorError13; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -1321,13 +1276,13 @@ var Client = (function () { } else if (destination instanceof User) { //check if we have a PM - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; try { - for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var pmc = _step14.value; + for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var pmc = _step13.value; if (pmc.user.equals(destination)) { return pmc.id; @@ -1336,16 +1291,16 @@ var Client = (function () { //we don't, at this point we're late } catch (err) { - _didIteratorError14 = true; - _iteratorError14 = err; + _didIteratorError13 = true; + _iteratorError13 = err; } finally { try { - if (!_iteratorNormalCompletion14 && _iterator14["return"]) { - _iterator14["return"](); + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); } } finally { - if (_didIteratorError14) { - throw _iteratorError14; + if (_didIteratorError13) { + throw _iteratorError13; } } } @@ -1359,6 +1314,14 @@ var Client = (function () { if (channId) resolve(channId); }); } + }, { + key: "_sendMessage", + value: function _sendMessage(messageType, destination, content, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) {}); + } }, { key: "uptime", get: function get() { @@ -1395,27 +1358,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion15 = true; - var _didIteratorError15 = false; - var _iteratorError15 = undefined; + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; try { - for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { - var channel = _step15.value; + for (var _iterator14 = this.channelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var channel = _step14.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError15 = true; - _iteratorError15 = err; + _didIteratorError14 = true; + _iteratorError14 = err; } finally { try { - if (!_iteratorNormalCompletion15 && _iterator15["return"]) { - _iterator15["return"](); + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); } } finally { - if (_didIteratorError15) { - throw _iteratorError15; + if (_didIteratorError14) { + throw _iteratorError14; } } } diff --git a/src/Client.js b/src/Client.js index ff8057340..4a7e86571 100644 --- a/src/Client.js +++ b/src/Client.js @@ -625,40 +625,11 @@ class Client { if(self.options.queue){ //we're QUEUEING messages, so sending them sequentially based on servers. + self.addMessageQueue(destination); + }else{ + self._sendMessage("text", destination, message, mentions); } - request - .post(`${Endpoints.CHANNELS}/${destination}/messages`) - .set("authorization", self.token) - .send({ - content: message, - mentions: mentions - }) - .end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var data = res.body; - - 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); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - callback(null, msg); - resolve(msg); - } - } - - }); - + } function resolveMessage() { @@ -1118,6 +1089,16 @@ class Client { resolve(channId); }); } + + _sendMessage(messageType, destination, content, mentions){ + + var self = this; + + return new Promise(function(resolve, reject){ + + }); + + } } From 7b124901c6e0ce47f2a65e9be725e30f8ead7d44 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 29 Aug 2015 16:48:25 +0100 Subject: [PATCH 079/191] Delocalised message sending, moved to one uniform function --- lib/Client.js | 85 ++++++++++++++++++++++++++++++++++++++++++--------- src/Client.js | 45 +++++++++++++++++++++++++-- 2 files changed, 113 insertions(+), 17 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index f832da526..40a50d048 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -609,10 +609,20 @@ var Client = (function () { //we're QUEUEING messages, so sending them sequentially based on servers. self.addMessageQueue(destination); } else { - self._sendMessage("text", destination, message, mentions); + self._sendMessage(destination, message, mentions).then(mgood)["catch"](mbad); } } + function mgood(msg) { + callback(null, msg); + resolve(msg); + } + + function mbad(error) { + callback(error); + reject(error); + } + function resolveMessage() { var msg = message; if (message instanceof Array) { @@ -1316,11 +1326,58 @@ var Client = (function () { } }, { key: "_sendMessage", - value: function _sendMessage(messageType, destination, content, mentions) { + value: function _sendMessage(destination, content, mentions) { var self = this; - return new Promise(function (resolve, reject) {}); + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var mention = _step14.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); } }, { key: "uptime", @@ -1358,27 +1415,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; try { - for (var _iterator14 = this.channelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var channel = _step14.value; + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError14 = true; - _iteratorError14 = err; + _didIteratorError15 = true; + _iteratorError15 = err; } finally { try { - if (!_iteratorNormalCompletion14 && _iterator14["return"]) { - _iterator14["return"](); + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); } } finally { - if (_didIteratorError14) { - throw _iteratorError14; + if (_didIteratorError15) { + throw _iteratorError15; } } } diff --git a/src/Client.js b/src/Client.js index 4a7e86571..d0aa5d768 100644 --- a/src/Client.js +++ b/src/Client.js @@ -627,10 +627,20 @@ class Client { //we're QUEUEING messages, so sending them sequentially based on servers. self.addMessageQueue(destination); }else{ - self._sendMessage("text", destination, message, mentions); + self._sendMessage(destination, message, mentions).then(mgood).catch(mbad); } } + + function mgood(msg){ + callback(null, msg); + resolve(msg); + } + + function mbad(error){ + callback(error); + reject(error); + } function resolveMessage() { var msg = message; @@ -1090,12 +1100,41 @@ class Client { }); } - _sendMessage(messageType, destination, content, mentions){ + _sendMessage(destination, content, mentions){ var self = this; return new Promise(function(resolve, reject){ - + request + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .send({ + content: content, + mentions: mentions + }) + .end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + 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); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + + }); }); } From b45d60eee8f237835a30b6edd8444cece4c53909 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 29 Aug 2015 17:22:17 +0100 Subject: [PATCH 080/191] Added message queue handling --- lib/Client.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/Client.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++--- test/bot.1.js | 27 +++++++++++++++++++++++++ test/msgbot.js | 0 4 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 test/bot.1.js create mode 100644 test/msgbot.js diff --git a/lib/Client.js b/lib/Client.js index 40a50d048..1eb4e953b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -61,7 +61,8 @@ var Client = (function () { this.serverCache = []; this.pmChannelCache = []; this.readyTime = null; - this.optionsQueue = {}; + this.checkingQueue = {}; + this.messageQueue = {}; } _createClass(Client, [{ @@ -607,7 +608,18 @@ var Client = (function () { if (self.options.queue) { //we're QUEUEING messages, so sending them sequentially based on servers. - self.addMessageQueue(destination); + if (!self.messageQueue[destination]) { + self.messageQueue[destination] = []; + } + + self.messageQueue[destination].push({ + content: message, + mentions: mentions, + then: [resolve, callback], + error: [reject, callback] + }); + + self.checkQueue(destination); } else { self._sendMessage(destination, message, mentions).then(mgood)["catch"](mbad); } @@ -1379,6 +1391,45 @@ var Client = (function () { }); }); } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.messageQueue[channelID].length === 0) { + done(); + return; + } + var msgToSend = self.messageQueue[channelID][0]; + self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { + msgToSend.then[0](msg); + msgToSend.then[1](null, msg); + self.messageQueue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend["catch"][0](err); + msgToSend["catch"][1](err); + self.messageQueue[channelID].shift(); + doNext(); + }); + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } }, { key: "uptime", get: function get() { diff --git a/src/Client.js b/src/Client.js index d0aa5d768..c58cdc2ab 100644 --- a/src/Client.js +++ b/src/Client.js @@ -51,7 +51,8 @@ class Client { this.serverCache = []; this.pmChannelCache = []; this.readyTime = null; - this.optionsQueue = {}; + this.checkingQueue = {}; + this.messageQueue = {}; } get uptime() { @@ -625,7 +626,18 @@ class Client { if(self.options.queue){ //we're QUEUEING messages, so sending them sequentially based on servers. - self.addMessageQueue(destination); + if(!self.messageQueue[destination]){ + self.messageQueue[destination] = []; + } + + self.messageQueue[destination].push({ + content : message, + mentions : mentions, + then : [resolve, callback], + error : [reject, callback] + }); + + self.checkQueue(destination); }else{ self._sendMessage(destination, message, mentions).then(mgood).catch(mbad); } @@ -1138,7 +1150,43 @@ class Client { }); } - + + checkQueue(channelID){ + + var self = this; + + if(!this.checkingQueue[channelID]){ + //if we aren't already checking this queue. + this.checkingQueue[channelID] = true; + doNext(); + + function doNext(){ + if(self.messageQueue[channelID].length === 0){ + done(); + return; + } + var msgToSend = self.messageQueue[channelID][0]; + self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) + .then(function(msg){ + msgToSend.then[0](msg); + msgToSend.then[1](null, msg); + self.messageQueue[channelID].shift(); + doNext(); + }) + .catch(function(err){ + msgToSend.catch[0](err); + msgToSend.catch[1](err); + self.messageQueue[channelID].shift(); + doNext(); + }); + } + + function done(){ + self.checkingQueue[channelID] = false; + return; + } + } + } } function getGateway() { diff --git a/test/bot.1.js b/test/bot.1.js new file mode 100644 index 000000000..046cdaa3b --- /dev/null +++ b/test/bot.1.js @@ -0,0 +1,27 @@ +var Discord = require("../"); +var mybot = new Discord.Client({ + queue : true +}); + +var server, channel, message, sentMessage = false; + +mybot.on("message", function(message){ + + if(message.content === "$$$"){ + mybot.sendMessage(message.channel, "this is part 1"); + mybot.sendMessage(message.channel, "this is part 2"); + mybot.sendMessage(message.channel, "this is part 3"); + mybot.sendMessage(message.channel, "this is part 4"); + mybot.sendMessage(message.channel, "this is part 5"); + mybot.sendMessage(message.channel, "this is part 6"); + mybot.sendMessage(message.channel, "this is part 7"); + mybot.sendMessage(message.channel, "this is part 8"); + } + +}); + +function error(err){ + console.log(err); +} + +mybot.login(process.env["ds_email"], process.env["ds_password"]).catch(error); \ No newline at end of file diff --git a/test/msgbot.js b/test/msgbot.js new file mode 100644 index 000000000..e69de29bb From bb53b65cf5bdb9395c4f43b2295386adb15c0a56 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 29 Aug 2015 19:47:11 +0100 Subject: [PATCH 081/191] Implemented queuing --- lib/Client.js | 40 ++++++++------ src/Client.js | 148 ++++++++++++++++++++++++++------------------------ test/bot.1.js | 13 ++--- 3 files changed, 106 insertions(+), 95 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 1eb4e953b..7511a6d27 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -19,7 +19,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - queue: false + queue: [] }; var Client = (function () { @@ -35,7 +35,7 @@ var Client = (function () { further efforts will be made to connect. */ this.options = options; - this.options.queue = this.options.queue || false; + this.options.queue = this.options.queue || []; this.token = token; this.state = 0; this.websocket = null; @@ -605,14 +605,14 @@ var Client = (function () { } function send(destination) { - - if (self.options.queue) { + if (~self.options.queue.indexOf("sendMessage")) { //we're QUEUEING messages, so sending them sequentially based on servers. if (!self.messageQueue[destination]) { self.messageQueue[destination] = []; } self.messageQueue[destination].push({ + action: "sendMessage", content: message, mentions: mentions, then: [resolve, callback], @@ -1405,18 +1405,26 @@ var Client = (function () { done(); return; } - var msgToSend = self.messageQueue[channelID][0]; - self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { - msgToSend.then[0](msg); - msgToSend.then[1](null, msg); - self.messageQueue[channelID].shift(); - doNext(); - })["catch"](function (err) { - msgToSend["catch"][0](err); - msgToSend["catch"][1](err); - self.messageQueue[channelID].shift(); - doNext(); - }); + var queuedEvent = self.messageQueue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { + msgToSend.then[0](msg); + msgToSend.then[1](null, msg); + self.messageQueue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend["catch"][0](err); + msgToSend["catch"][1](err); + self.messageQueue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } }; var done = function done() { diff --git a/src/Client.js b/src/Client.js index c58cdc2ab..021b9d4e3 100644 --- a/src/Client.js +++ b/src/Client.js @@ -13,7 +13,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - queue: false + queue: [] } class Client { @@ -25,7 +25,7 @@ class Client { further efforts will be made to connect. */ this.options = options; - this.options.queue = this.options.queue || false; + this.options.queue = this.options.queue || []; this.token = token; this.state = 0; this.websocket = null; @@ -623,33 +623,33 @@ class Client { } function send(destination) { - - if(self.options.queue){ + if (~self.options.queue.indexOf("sendMessage")) { //we're QUEUEING messages, so sending them sequentially based on servers. - if(!self.messageQueue[destination]){ + if (!self.messageQueue[destination]) { self.messageQueue[destination] = []; } - + self.messageQueue[destination].push({ - content : message, - mentions : mentions, - then : [resolve, callback], - error : [reject, callback] + action: "sendMessage", + content: message, + mentions: mentions, + then: [resolve, callback], + error: [reject, callback] }); - + self.checkQueue(destination); - }else{ + } else { self._sendMessage(destination, message, mentions).then(mgood).catch(mbad); } - + } - - function mgood(msg){ + + function mgood(msg) { callback(null, msg); resolve(msg); } - - function mbad(error){ + + function mbad(error) { callback(error); reject(error); } @@ -1111,79 +1111,87 @@ class Client { resolve(channId); }); } - - _sendMessage(destination, content, mentions){ - + + _sendMessage(destination, content, mentions) { + var self = this; - - return new Promise(function(resolve, reject){ + + return new Promise(function (resolve, reject) { request - .post(`${Endpoints.CHANNELS}/${destination}/messages`) - .set("authorization", self.token) - .send({ - content: content, - mentions: mentions - }) - .end(function (err, res) { + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .send({ + content: content, + mentions: mentions + }) + .end(function (err, res) { - if (err) { - reject(err); - } else { - var data = res.body; + if (err) { + reject(err); + } else { + var data = res.body; - var mentions = []; + var mentions = []; - data.mentions = data.mentions || []; //for some reason this was not defined at some point? + 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); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - resolve(msg); - } + for (var mention of data.mentions) { + mentions.push(self.addUser(mention)); } - }); + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + + }); }); - + } - - checkQueue(channelID){ - + + checkQueue(channelID) { + var self = this; - if(!this.checkingQueue[channelID]){ + if (!this.checkingQueue[channelID]) { //if we aren't already checking this queue. this.checkingQueue[channelID] = true; doNext(); - - function doNext(){ - if(self.messageQueue[channelID].length === 0){ + + function doNext() { + if (self.messageQueue[channelID].length === 0) { done(); return; } - var msgToSend = self.messageQueue[channelID][0]; - self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) - .then(function(msg){ - msgToSend.then[0](msg); - msgToSend.then[1](null, msg); - self.messageQueue[channelID].shift(); - doNext(); - }) - .catch(function(err){ - msgToSend.catch[0](err); - msgToSend.catch[1](err); - self.messageQueue[channelID].shift(); - doNext(); - }); + var queuedEvent = self.messageQueue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) + .then(function (msg) { + msgToSend.then[0](msg); + msgToSend.then[1](null, msg); + self.messageQueue[channelID].shift(); + doNext(); + }) + .catch(function (err) { + msgToSend.catch[0](err); + msgToSend.catch[1](err); + self.messageQueue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } } - - function done(){ + + function done() { self.checkingQueue[channelID] = false; - return; + return; } } } diff --git a/test/bot.1.js b/test/bot.1.js index 046cdaa3b..ad985f505 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,6 +1,6 @@ var Discord = require("../"); var mybot = new Discord.Client({ - queue : true + queue : ["sendMessage"] }); var server, channel, message, sentMessage = false; @@ -8,14 +8,9 @@ var server, channel, message, sentMessage = false; mybot.on("message", function(message){ if(message.content === "$$$"){ - mybot.sendMessage(message.channel, "this is part 1"); - mybot.sendMessage(message.channel, "this is part 2"); - mybot.sendMessage(message.channel, "this is part 3"); - mybot.sendMessage(message.channel, "this is part 4"); - mybot.sendMessage(message.channel, "this is part 5"); - mybot.sendMessage(message.channel, "this is part 6"); - mybot.sendMessage(message.channel, "this is part 7"); - mybot.sendMessage(message.channel, "this is part 8"); + for(var x=1;x<=10;x++){ + mybot.sendMessage(message.channel, "this is message " + x); + } } }); From c2e282c813e48568a07af3fccd05ca0dac3457ff Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 16:25:42 +0100 Subject: [PATCH 082/191] Added result storing in promise - useful for queue code --- lib/Client.js | 12 +++++++----- src/Client.js | 12 +++++++----- test/bot.1.js | 13 +++++++++---- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 7511a6d27..2087799c0 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -593,7 +593,7 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { message = premessage + resolveMessage(message); var mentions = resolveMentions(); @@ -615,8 +615,8 @@ var Client = (function () { action: "sendMessage", content: message, mentions: mentions, - then: [resolve, callback], - error: [reject, callback] + then: [mgood], + error: [mbad] }); self.checkQueue(destination); @@ -626,11 +626,13 @@ var Client = (function () { } function mgood(msg) { + prom.message = msg; callback(null, msg); resolve(msg); } function mbad(error) { + prom.error = error; callback(error); reject(error); } @@ -673,6 +675,8 @@ var Client = (function () { return _mentions; } }); + + return prom; } //def createws @@ -1411,12 +1415,10 @@ var Client = (function () { var msgToSend = queuedEvent; self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { msgToSend.then[0](msg); - msgToSend.then[1](null, msg); self.messageQueue[channelID].shift(); doNext(); })["catch"](function (err) { msgToSend["catch"][0](err); - msgToSend["catch"][1](err); self.messageQueue[channelID].shift(); doNext(); }); diff --git a/src/Client.js b/src/Client.js index 021b9d4e3..382f0d4f3 100644 --- a/src/Client.js +++ b/src/Client.js @@ -611,7 +611,7 @@ class Client { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { message = premessage + resolveMessage(message); var mentions = resolveMentions(); @@ -633,8 +633,8 @@ class Client { action: "sendMessage", content: message, mentions: mentions, - then: [resolve, callback], - error: [reject, callback] + then: [mgood], + error: [mbad] }); self.checkQueue(destination); @@ -645,11 +645,13 @@ class Client { } function mgood(msg) { + prom.message = msg; callback(null, msg); resolve(msg); } function mbad(error) { + prom.error = error; callback(error); reject(error); } @@ -671,6 +673,8 @@ class Client { } }); + + return prom; } //def createws @@ -1172,13 +1176,11 @@ class Client { self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) .then(function (msg) { msgToSend.then[0](msg); - msgToSend.then[1](null, msg); self.messageQueue[channelID].shift(); doNext(); }) .catch(function (err) { msgToSend.catch[0](err); - msgToSend.catch[1](err); self.messageQueue[channelID].shift(); doNext(); }); diff --git a/test/bot.1.js b/test/bot.1.js index ad985f505..6d4c5734d 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -7,10 +7,15 @@ var server, channel, message, sentMessage = false; mybot.on("message", function(message){ - if(message.content === "$$$"){ - for(var x=1;x<=10;x++){ - mybot.sendMessage(message.channel, "this is message " + x); - } + if( mybot.user.equals(message.sender) ){ + return; + } + + var action1 = mybot.sendMessage(message.channel, "this is message " + 1); + var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); + + function log(){ + mybot.sendMessage(message.channel, action1.message ? action1.message : action1.error); } }); From d8b7365e1fb6de98481a773c309a3222999c0c3f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 16:31:21 +0100 Subject: [PATCH 083/191] Added authentication for examples and moved promise --- examples/auth.json | 6 ++++++ src/Client.js | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 examples/auth.json diff --git a/examples/auth.json b/examples/auth.json new file mode 100644 index 000000000..ce847c692 --- /dev/null +++ b/examples/auth.json @@ -0,0 +1,6 @@ +{ + //this is an authentication file used for the examples, + //just add your email and password and the examples should work! + "email" : "discord@js.com", + "password" : "my discord password" +} \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index 382f0d4f3..8e2159b1d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -375,8 +375,8 @@ class Client { deleteMessage(message, timeout, callback = function (err, msg) { }) { var self = this; - - return new Promise(function (resolve, reject) { + + var prom = new Promise(function (resolve, reject) { if (timeout) { setTimeout(remove, timeout) } else { @@ -398,6 +398,8 @@ class Client { }); } }); + + return prom; } updateMessage(message, content, callback = function (err, msg) { }) { From b32d526937c9f4aa1924090b6a75a95ef79dddb7 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 16:42:15 +0100 Subject: [PATCH 084/191] ping pong example --- examples/auth.json | 6 ++---- examples/pingpong.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 examples/pingpong.js diff --git a/examples/auth.json b/examples/auth.json index ce847c692..32a7e16e6 100644 --- a/examples/auth.json +++ b/examples/auth.json @@ -1,6 +1,4 @@ { - //this is an authentication file used for the examples, - //just add your email and password and the examples should work! - "email" : "discord@js.com", - "password" : "my discord password" + "email" : "your discord email here", + "password" : "your discord password here" } \ No newline at end of file diff --git a/examples/pingpong.js b/examples/pingpong.js new file mode 100644 index 000000000..5a9ddc9ec --- /dev/null +++ b/examples/pingpong.js @@ -0,0 +1,34 @@ +/* + this bot is a ping pong bot, and every time a message + beginning with "ping" is sent, it will reply with + "pong". +*/ + +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.substring(0,4) === "ping"){ + + //send a message to the channel the ping message was sent in. + bot.sendMessage( msg.channel, "pong!" ); + + } +}); + +bot.login(AuthDetails.email, AuthDetails.password); \ No newline at end of file From 5968958ba43f4ebd1bd978a6e843b05e21b61420 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 17:31:18 +0100 Subject: [PATCH 085/191] added avatar bot working on cat --- examples/avatar.js | 41 +++++++++++++++++++++++++++++++++++++++++ examples/catapi.js | 36 ++++++++++++++++++++++++++++++++++++ examples/pingpong.js | 15 +++++++++------ 3 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 examples/avatar.js create mode 100644 examples/catapi.js diff --git a/examples/avatar.js b/examples/avatar.js new file mode 100644 index 000000000..b0eb1bb27 --- /dev/null +++ b/examples/avatar.js @@ -0,0 +1,41 @@ +/* + this bot is an avatar bot, and will give a user their avatar's URL +*/ + +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 === "$avatar") { + + //see if the user has an avatar + if( msg.sender.avatarURL ){ + bot.reply(msg, msg.sender.avatarURL); + }else{ + //using reply with a message automatically does: + // '@sender, ' for you! + bot.reply(msg, "you don't have an avatar!"); + } + + //alert the console + console.log("served " + msg.sender.username); + + } +}); + +bot.login(AuthDetails.email, AuthDetails.password); \ No newline at end of file diff --git a/examples/catapi.js b/examples/catapi.js new file mode 100644 index 000000000..ae5b7f6aa --- /dev/null +++ b/examples/catapi.js @@ -0,0 +1,36 @@ +/* + this bot will send an image of a cat to a channel. + may be slow depending on your internet connection. +*/ + +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 === "$cat") { + + //send a message to the channel the ping message was sent in. + bot.sendMessage(msg.channel, "pong!"); + + //alert the console + console.log("pong-ed " + msg.sender.username); + + } +}); + +bot.login(AuthDetails.email, AuthDetails.password); \ No newline at end of file diff --git a/examples/pingpong.js b/examples/pingpong.js index 5a9ddc9ec..d5d90588f 100644 --- a/examples/pingpong.js +++ b/examples/pingpong.js @@ -11,23 +11,26 @@ var AuthDetails = require("./auth.json"); var bot = new Discord.Client(); -bot.on("ready", function(){ +bot.on("ready", function () { console.log("Ready to begin! Serving in " + bot.channels.length + " channels"); }); -bot.on("disconnected", function(){ - +bot.on("disconnected", function () { + console.log("Disconnected!"); process.exit(1); //exit node.js with an error }); -bot.on("message", function(msg){ - if(msg.content.substring(0,4) === "ping"){ +bot.on("message", function (msg) { + if (msg.content.substring(0, 4) === "ping") { //send a message to the channel the ping message was sent in. - bot.sendMessage( msg.channel, "pong!" ); + bot.sendMessage(msg.channel, "pong!"); + //alert the console + console.log("pong-ed " + msg.sender.username); + } }); From 7b1e7d2efa624479a76a1dfba9ada8ac75f56dad Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 20:27:47 +0100 Subject: [PATCH 086/191] Added sendFile queue --- lib/Client.js | 103 +++++++++++++++++++++++++++++++++------------- src/Client.js | 112 +++++++++++++++++++++++++++++++++++--------------- test/bot.1.js | 15 ++++++- 3 files changed, 167 insertions(+), 63 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 2087799c0..64cc60127 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -62,7 +62,7 @@ var Client = (function () { this.pmChannelCache = []; this.readyTime = null; this.checkingQueue = {}; - this.messageQueue = {}; + this.queue = {}; } _createClass(Client, [{ @@ -339,7 +339,7 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { if (timeout) { setTimeout(remove, timeout); } else { @@ -358,6 +358,8 @@ var Client = (function () { }); } }); + + return prom; } }, { key: "updateMessage", @@ -563,23 +565,33 @@ var Client = (function () { self.resolveDestination(destination).then(send)["catch"](error); function send(destination) { - request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", fstream, fileName).end(function (err, res) { - - if (err) { - error(err); - } else { - - var chann = self.getChannel("id", destination); - if (chann) { - var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); - callback(null, msg); - resolve(msg); - } + if (~self.options.queue.indexOf("send")) { + //queue send file too + if (!self.queue[destination]) { + self.queue[destination] = []; } - }); + + self.queue[destination].push({ + action: "sendFile", + attachment: fstream, + attachmentName: fileName, + then: good, + error: bad + }); + + self.checkQueue(destination); + } else { + //not queue + self._sendFile(destination, fstream, fileName).then(good)["catch"](bad); + } } - function error(err) { + function good(msg) { + callback(null, msg); + resolve(msg); + } + + function bad(err) { callback(err); reject(err); } @@ -605,18 +617,18 @@ var Client = (function () { } function send(destination) { - if (~self.options.queue.indexOf("sendMessage")) { + if (~self.options.queue.indexOf("send")) { //we're QUEUEING messages, so sending them sequentially based on servers. - if (!self.messageQueue[destination]) { - self.messageQueue[destination] = []; + if (!self.queue[destination]) { + self.queue[destination] = []; } - self.messageQueue[destination].push({ + self.queue[destination].push({ action: "sendMessage", content: message, mentions: mentions, - then: [mgood], - error: [mbad] + then: mgood, + error: mbad }); self.checkQueue(destination); @@ -1395,6 +1407,29 @@ var Client = (function () { }); }); } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } }, { key: "checkQueue", value: function checkQueue(channelID) { @@ -1405,21 +1440,33 @@ var Client = (function () { if (!this.checkingQueue[channelID]) { (function () { var doNext = function doNext() { - if (self.messageQueue[channelID].length === 0) { + if (self.queue[channelID].length === 0) { done(); return; } - var queuedEvent = self.messageQueue[channelID][0]; + var queuedEvent = self.queue[channelID][0]; switch (queuedEvent.action) { case "sendMessage": var msgToSend = queuedEvent; self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { - msgToSend.then[0](msg); - self.messageQueue[channelID].shift(); + msgToSend.then(msg); + self.queue[channelID].shift(); doNext(); })["catch"](function (err) { - msgToSend["catch"][0](err); - self.messageQueue[channelID].shift(); + msgToSend["catch"](err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend["catch"](err); + self.queue[channelID].shift(); doNext(); }); break; diff --git a/src/Client.js b/src/Client.js index 8e2159b1d..46628e344 100644 --- a/src/Client.js +++ b/src/Client.js @@ -52,7 +52,7 @@ class Client { this.pmChannelCache = []; this.readyTime = null; this.checkingQueue = {}; - this.messageQueue = {}; + this.queue = {}; } get uptime() { @@ -577,30 +577,33 @@ class Client { self.resolveDestination(destination).then(send).catch(error); function send(destination) { - request - .post(`${Endpoints.CHANNELS}/${destination}/messages`) - .set("authorization", self.token) - .attach("file", fstream, fileName) - .end(function (err, res) { - - if (err) { - error(err); - } else { - - var chann = self.getChannel("id", destination); - if (chann) { - var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); - callback(null, msg); - resolve(msg); - } - - - } + if(~self.options.queue.indexOf("send")){ + //queue send file too + if (!self.queue[destination]) { + self.queue[destination] = []; + } + self.queue[destination].push({ + action: "sendFile", + attachment : fstream, + attachmentName : fileName, + then: good, + error: bad }); + + self.checkQueue(destination); + }else{ + //not queue + self._sendFile(destination, fstream, fileName).then(good).catch(bad); + } } - function error(err) { + function good(msg) { + callback(null, msg); + resolve(msg); + } + + function bad(err) { callback(err); reject(err); } @@ -625,18 +628,18 @@ class Client { } function send(destination) { - if (~self.options.queue.indexOf("sendMessage")) { + if (~self.options.queue.indexOf("send")) { //we're QUEUEING messages, so sending them sequentially based on servers. - if (!self.messageQueue[destination]) { - self.messageQueue[destination] = []; + if (!self.queue[destination]) { + self.queue[destination] = []; } - self.messageQueue[destination].push({ + self.queue[destination].push({ action: "sendMessage", content: message, mentions: mentions, - then: [mgood], - error: [mbad] + then: mgood, + error: mbad }); self.checkQueue(destination); @@ -1156,6 +1159,35 @@ class Client { }); } + + _sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png"){ + + var self = this; + + return new Promise(function(resolve, reject){ + request + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .attach("file", attachment, attachmentName) + .end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + + + } + + }); + }); + + } checkQueue(channelID) { @@ -1167,23 +1199,37 @@ class Client { doNext(); function doNext() { - if (self.messageQueue[channelID].length === 0) { + if (self.queue[channelID].length === 0) { done(); return; } - var queuedEvent = self.messageQueue[channelID][0]; + var queuedEvent = self.queue[channelID][0]; switch (queuedEvent.action) { case "sendMessage": var msgToSend = queuedEvent; self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) .then(function (msg) { - msgToSend.then[0](msg); - self.messageQueue[channelID].shift(); + msgToSend.then(msg); + self.queue[channelID].shift(); doNext(); }) .catch(function (err) { - msgToSend.catch[0](err); - self.messageQueue[channelID].shift(); + msgToSend.catch(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName) + .then(function (msg){ + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + }) + .catch(function(err){ + fileToSend.catch(err); + self.queue[channelID].shift(); doNext(); }); break; diff --git a/test/bot.1.js b/test/bot.1.js index 6d4c5734d..472a22cf6 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,7 +1,8 @@ var Discord = require("../"); var mybot = new Discord.Client({ - queue : ["sendMessage"] + queue : ["send"] }); +var fs = require("fs"); var server, channel, message, sentMessage = false; @@ -11,11 +12,21 @@ mybot.on("message", function(message){ return; } + if( message.content !== "$$$" ){ + return; + } + var action1 = mybot.sendMessage(message.channel, "this is message " + 1); + var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); + var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); + var action2 = mybot.sendMessage(message.channel, "this is message " + 3).then(log); + var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); + var action2 = mybot.sendMessage(message.channel, "this is message " + 4).then(log); + var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); + var action2 = mybot.sendMessage(message.channel, "this is message " + 5).then(log); function log(){ - mybot.sendMessage(message.channel, action1.message ? action1.message : action1.error); } }); From 2fdc5a3ff66a635b79c3d34cfa02872f9e30bc9a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 21:29:27 +0100 Subject: [PATCH 087/191] Added queue update message --- lib/Client.js | 90 ++++++++++++++++++++++++++++++++++++----------- src/Client.js | 97 +++++++++++++++++++++++++++++++++++++++------------ test/bot.1.js | 36 +++++++++---------- 3 files changed, 162 insertions(+), 61 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 64cc60127..8bb9e87ba 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -368,26 +368,41 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { content = content instanceof Array ? content.join("\n") : content; - request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ - content: content, - mentions: [] - }).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - var msg = new Message(res.body, message.channel, message.mentions, message.sender); - callback(null, msg); - resolve(msg); - - message.channel.messages[message.channel.messages.indexOf(message)] = msg; + if (self.options.queue) { + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; } - }); + self.queue[message.channel.id].push({ + action: "updateMessage", + message: message, + content: content, + then: good, + error: bad + }); + + self.checkQueue(message.channel.id); + } else { + self._updateMessage(message, content).then(good)["catch"](bad); + } + + function good(msg) { + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function bad(error) { + prom.error = error; + callback(error); + reject(error); + } }); + + return prom; } }, { key: "setUsername", @@ -551,7 +566,7 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { var fstream; @@ -565,7 +580,7 @@ var Client = (function () { self.resolveDestination(destination).then(send)["catch"](error); function send(destination) { - if (~self.options.queue.indexOf("send")) { + if (self.options.queue) { //queue send file too if (!self.queue[destination]) { self.queue[destination] = []; @@ -587,15 +602,19 @@ var Client = (function () { } function good(msg) { + prom.message = msg; callback(null, msg); resolve(msg); } function bad(err) { + prom.error = err; callback(err); reject(err); } }); + + return prom; } }, { key: "sendMessage", @@ -617,7 +636,7 @@ var Client = (function () { } function send(destination) { - if (~self.options.queue.indexOf("send")) { + if (self.options.queue) { //we're QUEUEING messages, so sending them sequentially based on servers. if (!self.queue[destination]) { self.queue[destination] = []; @@ -1430,6 +1449,25 @@ var Client = (function () { }); }); } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } }, { key: "checkQueue", value: function checkQueue(channelID) { @@ -1453,7 +1491,7 @@ var Client = (function () { self.queue[channelID].shift(); doNext(); })["catch"](function (err) { - msgToSend["catch"](err); + msgToSend.error(err); self.queue[channelID].shift(); doNext(); }); @@ -1465,7 +1503,19 @@ var Client = (function () { self.queue[channelID].shift(); doNext(); })["catch"](function (err) { - fileToSend["catch"](err); + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); self.queue[channelID].shift(); doNext(); }); diff --git a/src/Client.js b/src/Client.js index 46628e344..52ec644d9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -406,31 +406,42 @@ class Client { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { content = (content instanceof Array ? content.join("\n") : content); - request - .patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) - .set("authorization", self.token) - .send({ + if(self.options.queue){ + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; + } + self.queue[message.channel.id].push({ + action: "updateMessage", + message: message, content: content, - mentions: [] - }) - .end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - var msg = new Message(res.body, message.channel, message.mentions, message.sender); - callback(null, msg); - resolve(msg); - - message.channel.messages[message.channel.messages.indexOf(message)] = msg; - } + then: good, + error: bad }); + + self.checkQueue(message.channel.id); + }else{ + self._updateMessage(message, content).then(good).catch(bad); + } + + function good(msg){ + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function bad(error){ + prom.error = error; + callback(error); + reject(error); + } }); + + return prom; } setUsername(newName, callback = function (err) { }) { @@ -563,7 +574,7 @@ class Client { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { var fstream; @@ -577,7 +588,7 @@ class Client { self.resolveDestination(destination).then(send).catch(error); function send(destination) { - if(~self.options.queue.indexOf("send")){ + if(self.options.queue){ //queue send file too if (!self.queue[destination]) { self.queue[destination] = []; @@ -599,16 +610,20 @@ class Client { } function good(msg) { + prom.message = msg; callback(null, msg); resolve(msg); } function bad(err) { + prom.error = err; callback(err); reject(err); } }); + + return prom; } @@ -628,7 +643,7 @@ class Client { } function send(destination) { - if (~self.options.queue.indexOf("send")) { + if (self.options.queue) { //we're QUEUEING messages, so sending them sequentially based on servers. if (!self.queue[destination]) { self.queue[destination] = []; @@ -1188,6 +1203,28 @@ class Client { }); } + + _updateMessage(message, content){ + var self = this; + return new Promise(function(resolve, reject){ + request + .patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) + .set("authorization", self.token) + .send({ + content: content, + mentions: [] + }) + .end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } checkQueue(channelID) { @@ -1214,7 +1251,7 @@ class Client { doNext(); }) .catch(function (err) { - msgToSend.catch(err); + msgToSend.error(err); self.queue[channelID].shift(); doNext(); }); @@ -1228,11 +1265,25 @@ class Client { doNext(); }) .catch(function(err){ - fileToSend.catch(err); + fileToSend.error(err); self.queue[channelID].shift(); doNext(); }); break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content) + .then(function(msg){ + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + }) + .catch(function(err){ + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; default: done(); break; diff --git a/test/bot.1.js b/test/bot.1.js index 472a22cf6..31f344fac 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,37 +1,37 @@ var Discord = require("../"); var mybot = new Discord.Client({ - queue : ["send"] + queue: ["send"] }); var fs = require("fs"); var server, channel, message, sentMessage = false; -mybot.on("message", function(message){ - - if( mybot.user.equals(message.sender) ){ +mybot.on("message", function (message) { + + if (mybot.user.equals(message.sender)) { return; } - - if( message.content !== "$$$" ){ + + if (message.content !== "$$$") { return; } - + var action1 = mybot.sendMessage(message.channel, "this is message " + 1); - var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); - var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); - var action2 = mybot.sendMessage(message.channel, "this is message " + 3).then(log); - var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); - var action2 = mybot.sendMessage(message.channel, "this is message " + 4).then(log); - var action1 = mybot.sendFile(message.channel, fs.createReadStream("./test/image.png")); - var action2 = mybot.sendMessage(message.channel, "this is message " + 5).then(log); - - function log(){ + + function log() { + console.log("w", action1.message); + mybot.updateMessage(action1.message, "blurg"); + mybot.sendMessage(message.channel, "This is message 3 million minus the million so basically just 3"); } - + }); -function error(err){ +function dump(msg) { + console.log(msg); +} + +function error(err) { console.log(err); } From be0be60947f74c969b9d55ea11ce157cfbe7d47f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 21:42:09 +0100 Subject: [PATCH 088/191] added deletion queue --- lib/Client.js | 60 +++++++++++++++++++++++++++++++++++++++------ src/Client.js | 67 ++++++++++++++++++++++++++++++++++++++++++--------- test/bot.1.js | 4 +-- 3 files changed, 110 insertions(+), 21 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 8bb9e87ba..059d09628 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -347,15 +347,33 @@ var Client = (function () { } function remove() { - request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - callback(null); - resolve(); + if (self.options.queue) { + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; } - }); + self.queue[message.channel.id].push({ + action: "deleteMessage", + message: message, + then: good, + error: bad + }); + + self.checkQueue(message.channel.id); + } else { + self._deleteMessage(message).then(good)["catch"](bad); + } + } + + function good() { + prom.success = true; + callback(null); + resolve(); + } + + function bad(err) { + prom.error = err; + callback(err); + reject(err); } }); @@ -1468,6 +1486,20 @@ var Client = (function () { }); }); } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } }, { key: "checkQueue", value: function checkQueue(channelID) { @@ -1520,6 +1552,18 @@ var Client = (function () { doNext(); }); break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; default: done(); break; diff --git a/src/Client.js b/src/Client.js index 52ec644d9..3d6523b78 100644 --- a/src/Client.js +++ b/src/Client.js @@ -384,18 +384,33 @@ class Client { } function remove() { - request - .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) - .set("authorization", self.token) - .end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - callback(null); - resolve(); - } + if(self.options.queue){ + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; + } + self.queue[message.channel.id].push({ + action: "deleteMessage", + message: message, + then: good, + error: bad }); + + self.checkQueue(message.channel.id); + }else{ + self._deleteMessage(message).then(good).catch(bad); + } + } + + function good(){ + prom.success = true; + callback(null); + resolve(); + } + + function bad(err){ + prom.error = err; + callback(err); + reject(err); } }); @@ -1225,6 +1240,22 @@ class Client { }); }); } + + _deleteMessage(message){ + var self = this; + return new Promise(function(resolve, reject){ + request + .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) + .set("authorization", self.token) + .end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } checkQueue(channelID) { @@ -1284,6 +1315,20 @@ class Client { doNext(); }); break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message) + .then(function(msg){ + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + }) + .catch(function(err){ + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; default: done(); break; diff --git a/test/bot.1.js b/test/bot.1.js index 31f344fac..2805bdc78 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -20,11 +20,11 @@ mybot.on("message", function (message) { var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); function log() { - console.log("w", action1.message); mybot.updateMessage(action1.message, "blurg"); mybot.sendMessage(message.channel, "This is message 3 million minus the million so basically just 3"); + mybot.deleteMessage(action1.message); + mybot.sendMessage(message.channel, "This is message RJNGEIKGNER").then(log2); } - }); function dump(msg) { From 68fd2ee9dd016fdab75ff98f369b84c4dc3c4670 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 21:51:02 +0100 Subject: [PATCH 089/191] 3.1.4 - finalised message queueing --- README.md | 34 ++++++++++++++++++++++++++++++++++ lib/Client.js | 4 ++-- package.json | 2 +- src/Client.js | 4 ++-- test/bot.1.js | 2 +- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f62b29c2e..c0a68bdaa 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,40 @@ Here is a list of other Discord APIs: --- +### Changes in 3.1.4 + +No, not π. But instead, pseduo-synchronous messaging was added! This means that +you can tell your Client to make a queue of "actions" per channel, and it will +work through them one by one. This is a really useful tool if you need to send +messages in a specific order without callback hell. + +It also allows you to store responses - such as created messages - in the returned +promise - named action. Example: + +```js +var mybot = new Discord.Client({ + queue : true //enable queueing, disabled by default +}); + +mybot.on("message", function(msg){ + + mybot.sendMessage(msg.channel, "this is message 1"); + var action = mybot.sendMessage(msg.channel, "this is message 2"); + mybot.sendMessage(msg.channel, "this is message 3").then(rmv); + + function rmv(){ + if(!action.error){ + mybot.deleteMessage(action.message); + } + } + +}); +``` + +This is still in development, and will see many more enhancements in future. + +--- + ### Links **[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)** diff --git a/lib/Client.js b/lib/Client.js index 059d09628..1c2bb688f 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -19,7 +19,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - queue: [] + queue: false }; var Client = (function () { @@ -35,7 +35,7 @@ var Client = (function () { further efforts will be made to connect. */ this.options = options; - this.options.queue = this.options.queue || []; + this.options.queue = this.options.queue; this.token = token; this.state = 0; this.websocket = null; diff --git a/package.json b/package.json index fd5043bcc..e5d2a0a8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.3", + "version": "3.1.4", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 3d6523b78..31a16fdd9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -13,7 +13,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - queue: [] + queue: false } class Client { @@ -25,7 +25,7 @@ class Client { further efforts will be made to connect. */ this.options = options; - this.options.queue = this.options.queue || []; + this.options.queue = this.options.queue; this.token = token; this.state = 0; this.websocket = null; diff --git a/test/bot.1.js b/test/bot.1.js index 2805bdc78..e9b9f9c9a 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,6 +1,6 @@ var Discord = require("../"); var mybot = new Discord.Client({ - queue: ["send"] + queue: true }); var fs = require("fs"); From 8a7629582a718add1a60b1c7b8c292f1b091448f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 21:59:00 +0100 Subject: [PATCH 090/191] Fixed bug which stopped file sending --- lib/Client.js | 2 +- package.json | 2 +- src/Client.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 1c2bb688f..e12f5a0ee 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -595,7 +595,7 @@ var Client = (function () { fstream = file; } - self.resolveDestination(destination).then(send)["catch"](error); + self.resolveDestination(destination).then(send)["catch"](bad); function send(destination) { if (self.options.queue) { diff --git a/package.json b/package.json index e5d2a0a8e..40a91a8c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.4", + "version": "3.1.5", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 31a16fdd9..72298886a 100644 --- a/src/Client.js +++ b/src/Client.js @@ -600,7 +600,7 @@ class Client { fstream = file; } - self.resolveDestination(destination).then(send).catch(error); + self.resolveDestination(destination).then(send).catch(bad); function send(destination) { if(self.options.queue){ From ebe3bd90ad17c8d2a541f598a9c22cd47510559e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 30 Aug 2015 22:03:54 +0100 Subject: [PATCH 091/191] test fix --- test/bot.1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bot.1.js b/test/bot.1.js index e9b9f9c9a..253e50c50 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -16,7 +16,7 @@ mybot.on("message", function (message) { return; } - var action1 = mybot.sendMessage(message.channel, "this is message " + 1); + var action1 = mybot.sendMessage(message.channel, "this is message " + 1); var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); function log() { From df744e7d54094be939095b8e53056302f66a9e7c Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 1 Sep 2015 17:06:12 +0100 Subject: [PATCH 092/191] 3.1.6, fixing login bug Fixed bug where the client attempts to close the websocket if there is an error whilst it is null --- package.json | 2 +- src/Client.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 40a91a8c9..e91f2c257 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.5", + "version": "3.1.6", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 72298886a..d88aab364 100644 --- a/src/Client.js +++ b/src/Client.js @@ -153,7 +153,9 @@ class Client { if (err) { self.state = 4; //set state to disconnected self.trigger("disconnected"); - self.websocket.close(); + if(self.websocket){ + self.websocket.close(); + } callback(err); reject(err); } else { From 705a77ed57aa1740d7813ec6a36a220d1cce42f6 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Tue, 1 Sep 2015 21:04:18 +0100 Subject: [PATCH 093/191] Fancy logo --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c0a68bdaa..b83cdabae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# discord.js +

+ + discord.js + +

[![Build Status](https://travis-ci.org/hydrabolt/discord.js.svg)](https://travis-ci.org/hydrabolt/discord.js) From f78c1b8a2f936412d4e1aabceb8963abb0d961e3 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 1 Sep 2015 22:12:23 +0100 Subject: [PATCH 094/191] Added isPrivate field --- src/message.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/message.js b/src/message.js index a979e87dd..3462ce88c 100644 --- a/src/message.js +++ b/src/message.js @@ -1,3 +1,5 @@ +var PMChannel = require("./PMChannel.js"); + class Message{ constructor(data, channel, mentions, author){ this.tts = data.tts; @@ -27,6 +29,10 @@ class Message{ get sender(){ return this.author; } + + get isPrivate(){ + return this.channel.isPrivate; + } } /*exports.Message.prototype.isPM = function() { From aa1db2403053d0e809ad0de6baa74034fe8cbe68 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 1 Sep 2015 22:13:09 +0100 Subject: [PATCH 095/191] Added isPrivate to channels --- src/PMChannel.js | 4 ++++ src/channel.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/PMChannel.js b/src/PMChannel.js index 6b069d50b..d82cf7932 100644 --- a/src/PMChannel.js +++ b/src/PMChannel.js @@ -20,6 +20,10 @@ class PMChannel { } return null; } + + get isPrivate(){ + return true; + } } module.exports = PMChannel; \ No newline at end of file diff --git a/src/channel.js b/src/channel.js index d32ab580d..0dc0b957a 100644 --- a/src/channel.js +++ b/src/channel.js @@ -36,6 +36,10 @@ class Channel { toString(){ return "#" + this.name; } + + get isPrivate(){ + return false; + } } module.exports = Channel; \ No newline at end of file From 67edc5f5e633762b94206df1803753f83766b025 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 1 Sep 2015 22:14:58 +0100 Subject: [PATCH 096/191] 3.2.0, major fixes to allow support for checking isPrivate --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e91f2c257..0bbf81be0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.1.6", + "version": "3.2.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 8d6ece0b3526891a217672a0d8b8d01c3b5a470a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 1 Sep 2015 22:30:34 +0100 Subject: [PATCH 097/191] Whoops, compiled the changes this time :P --- lib/Client.js | 4 +++- lib/PMChannel.js | 5 +++++ lib/channel.js | 5 +++++ lib/message.js | 7 +++++++ package.json | 2 +- test/bot.1.js | 7 +++++++ 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index e12f5a0ee..77a34e10c 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -139,7 +139,9 @@ var Client = (function () { if (err) { self.state = 4; //set state to disconnected self.trigger("disconnected"); - self.websocket.close(); + if (self.websocket) { + self.websocket.close(); + } callback(err); reject(err); } else { diff --git a/lib/PMChannel.js b/lib/PMChannel.js index ae44d3d60..7c30a7c34 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -53,6 +53,11 @@ var PMChannel = (function () { return null; } + }, { + key: "isPrivate", + get: function get() { + return true; + } }]); return PMChannel; diff --git a/lib/channel.js b/lib/channel.js index f94925f0c..dfb4f72d8 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -71,6 +71,11 @@ var Channel = (function () { get: function get() { return this.server.client; } + }, { + key: "isPrivate", + get: function get() { + return false; + } }]); return Channel; diff --git a/lib/message.js b/lib/message.js index 24c54fbb3..3dd4ddcae 100644 --- a/lib/message.js +++ b/lib/message.js @@ -4,6 +4,8 @@ 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 PMChannel = require("./PMChannel.js"); + var Message = (function () { function Message(data, channel, mentions, author) { _classCallCheck(this, Message); @@ -64,6 +66,11 @@ var Message = (function () { get: function get() { return this.author; } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } }]); return Message; diff --git a/package.json b/package.json index 0bbf81be0..120e83fcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.2.0", + "version": "3.2.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/test/bot.1.js b/test/bot.1.js index 253e50c50..9293b401d 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -27,6 +27,13 @@ mybot.on("message", function (message) { } }); +mybot.on("ready", function(){ + console.log("im ready"); + setInterval(function(){ + console.log(mybot.websocket.state, "state"); + }, 2000); +}) + function dump(msg) { console.log(msg); } From 5ef3adffb4aa795c71c115580404a2788b15a600 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 4 Sep 2015 22:14:08 +0100 Subject: [PATCH 098/191] 3.2.2., updated so works on older node hopefully --- package.json | 2 +- src/Client.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 120e83fcc..a83a52a24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.2.1", + "version": "3.2.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index d88aab364..582c6cb70 100644 --- a/src/Client.js +++ b/src/Client.js @@ -29,7 +29,7 @@ class Client { this.token = token; this.state = 0; this.websocket = null; - this.events = new Map(); + this.events = {}; this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); @@ -103,11 +103,11 @@ class Client { } on(event, fn) { - this.events.set(event, fn); + this.events[event] = fn; } - off(event, fn) { - this.events.delete(event); + off(event) { + this.events[event] = null; } keepAlive() { @@ -124,7 +124,7 @@ class Client { for (var arg in arguments) { args.push(arguments[arg]); } - var evt = this.events.get(event); + var evt = this.events[event]; if (evt) { evt.apply(this, args.slice(1)); } From 064bbb169ca8571e4db595e05c4fc845a43f01ab Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 4 Sep 2015 22:14:49 +0100 Subject: [PATCH 099/191] actually build 3.2.2 changes whoops --- lib/Client.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 77a34e10c..313e21686 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -39,7 +39,7 @@ var Client = (function () { this.token = token; this.state = 0; this.websocket = null; - this.events = new Map(); + this.events = {}; this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); @@ -82,12 +82,12 @@ var Client = (function () { }, { key: "on", value: function on(event, fn) { - this.events.set(event, fn); + this.events[event] = fn; } }, { key: "off", - value: function off(event, fn) { - this.events["delete"](event); + value: function off(event) { + this.events[event] = null; } }, { key: "keepAlive", @@ -107,7 +107,7 @@ var Client = (function () { for (var arg in arguments) { args.push(arguments[arg]); } - var evt = this.events.get(event); + var evt = this.events[event]; if (evt) { evt.apply(this, args.slice(1)); } From 012c706ab9dee4df5d419b35e20dcb13a6070c6e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 5 Sep 2015 13:57:15 +0100 Subject: [PATCH 100/191] 3.3.0 - added TTS capability --- lib/Client.js | 32 +++++++++++++++++++++++--------- package.json | 2 +- src/Client.js | 28 +++++++++++++++++++++------- test/bot.1.js | 5 +---- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 313e21686..85119d53a 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -323,13 +323,19 @@ var Client = (function () { } }, { key: "reply", - value: function reply(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + value: function reply(destination, message, tts) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3]; var self = this; return new Promise(function (response, reject) { + if (typeof tts === "function") { + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } + var user = destination.sender; self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); }); @@ -638,14 +644,20 @@ var Client = (function () { } }, { key: "sendMessage", - value: function sendMessage(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3]; + value: function sendMessage(destination, message, tts) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3]; + var premessage = arguments.length <= 4 || arguments[4] === undefined ? "" : arguments[4]; var self = this; var prom = new Promise(function (resolve, reject) { + if (typeof tts === "function") { + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } + message = premessage + resolveMessage(message); var mentions = resolveMentions(); self.resolveDestination(destination).then(send)["catch"](error); @@ -666,13 +678,14 @@ var Client = (function () { action: "sendMessage", content: message, mentions: mentions, + tts: !!tts, //incase it's not a boolean then: mgood, error: mbad }); self.checkQueue(destination); } else { - self._sendMessage(destination, message, mentions).then(mgood)["catch"](mbad); + self._sendMessage(destination, message, tts, mentions).then(mgood)["catch"](mbad); } } @@ -1393,14 +1406,15 @@ var Client = (function () { } }, { key: "_sendMessage", - value: function _sendMessage(destination, content, mentions) { + value: function _sendMessage(destination, content, tts, mentions) { var self = this; return new Promise(function (resolve, reject) { request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ content: content, - mentions: mentions + mentions: mentions, + tts: tts }).end(function (err, res) { if (err) { @@ -1520,7 +1534,7 @@ var Client = (function () { switch (queuedEvent.action) { case "sendMessage": var msgToSend = queuedEvent; - self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) { + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { msgToSend.then(msg); self.queue[channelID].shift(); doNext(); diff --git a/package.json b/package.json index a83a52a24..e1c2cc82f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.2.2", + "version": "3.3.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 582c6cb70..03cb6a577 100644 --- a/src/Client.js +++ b/src/Client.js @@ -361,12 +361,18 @@ class Client { } - reply(destination, message, callback = function (err, msg) { }) { + reply(destination, message, tts, callback = function (err, msg) { }) { var self = this; return new Promise(function (response, reject) { + if(typeof tts === "function"){ + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } + var user = destination.sender; self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject); @@ -644,12 +650,18 @@ class Client { } - sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") { + sendMessage(destination, message, tts, callback = function (err, msg) { }, premessage = "") { var self = this; var prom = new Promise(function (resolve, reject) { - + + if(typeof tts === "function"){ + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } + message = premessage + resolveMessage(message); var mentions = resolveMentions(); self.resolveDestination(destination).then(send).catch(error); @@ -670,13 +682,14 @@ class Client { action: "sendMessage", content: message, mentions: mentions, + tts : !!tts, //incase it's not a boolean then: mgood, error: mbad }); self.checkQueue(destination); } else { - self._sendMessage(destination, message, mentions).then(mgood).catch(mbad); + self._sendMessage(destination, message, tts, mentions).then(mgood).catch(mbad); } } @@ -1153,7 +1166,7 @@ class Client { }); } - _sendMessage(destination, content, mentions) { + _sendMessage(destination, content, tts, mentions) { var self = this; @@ -1163,7 +1176,8 @@ class Client { .set("authorization", self.token) .send({ content: content, - mentions: mentions + mentions: mentions, + tts : tts }) .end(function (err, res) { @@ -1277,7 +1291,7 @@ class Client { switch (queuedEvent.action) { case "sendMessage": var msgToSend = queuedEvent; - self._sendMessage(channelID, msgToSend.content, msgToSend.mentions) + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions) .then(function (msg) { msgToSend.then(msg); self.queue[channelID].shift(); diff --git a/test/bot.1.js b/test/bot.1.js index 9293b401d..eb99418bf 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -16,7 +16,7 @@ mybot.on("message", function (message) { return; } - var action1 = mybot.sendMessage(message.channel, "this is message " + 1); + var action1 = mybot.sendMessage(message.channel, "this is message " + 1, true); var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); function log() { @@ -29,9 +29,6 @@ mybot.on("message", function (message) { mybot.on("ready", function(){ console.log("im ready"); - setInterval(function(){ - console.log(mybot.websocket.state, "state"); - }, 2000); }) function dump(msg) { From a6e62b22a62e03936d1f01bc2fa061d0e0d34281 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 6 Sep 2015 20:16:16 +0100 Subject: [PATCH 101/191] Updated Web Distrib management --- gruntfile.js | 6 +- test/bot.1.js | 14 +- web-dist/README.md | 10 + web-dist/{discord.js => discord.3.3.0.js} | 732 +++++++++++++++------- web-dist/discord.min.js | 2 - 5 files changed, 513 insertions(+), 251 deletions(-) create mode 100644 web-dist/README.md rename web-dist/{discord.js => discord.3.3.0.js} (85%) delete mode 100644 web-dist/discord.min.js diff --git a/gruntfile.js b/gruntfile.js index 2cf6001aa..126762092 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -3,7 +3,7 @@ module.exports = function (grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ - + pkg: grunt.file.readJSON("package.json"), // define source files and their destinations babel: { dist: { @@ -19,7 +19,7 @@ module.exports = function (grunt) { browserify: { dist: { files: { - 'web-dist/discord.js': ["lib/index.js"], + 'web-dist/discord.<%= pkg.version %>.js': ["lib/index.js"], }, options: { browserifyOptions: { @@ -31,7 +31,7 @@ module.exports = function (grunt) { uglify: { min: { files: { - "./web-dist/discord.min.js": "./web-dist/discord.js" + "./web-dist/discord.min.<%= pkg.version %>.js": "./web-dist/discord.js" } } } diff --git a/test/bot.1.js b/test/bot.1.js index eb99418bf..1230b9bb6 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -16,18 +16,12 @@ mybot.on("message", function (message) { return; } - var action1 = mybot.sendMessage(message.channel, "this is message " + 1, true); - var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log); - - function log() { - mybot.updateMessage(action1.message, "blurg"); - mybot.sendMessage(message.channel, "This is message 3 million minus the million so basically just 3"); - mybot.deleteMessage(action1.message); - mybot.sendMessage(message.channel, "This is message RJNGEIKGNER").then(log2); - } + // we can go ahead :) + console.log(message.sender.username); + mybot.sendMessage(message.channel, message.sender.username); }); -mybot.on("ready", function(){ +mybot.on("ready", function () { console.log("im ready"); }) diff --git a/web-dist/README.md b/web-dist/README.md new file mode 100644 index 000000000..053576bab --- /dev/null +++ b/web-dist/README.md @@ -0,0 +1,10 @@ +## Web Distributions + +Here you can find the latest web-ready distributions of discord.js. These distributions will allow you to run discord.js +in your browser, which is very useful for making on-the-go bots or clients. For some reason, request times are also much +shorter in browsers, so your bots will reply much faster. + +Web Distributions aren't always fully functional, and sometimes catching errors is a pain. As discord.js's support for +browserifying is still maturing, please don't expect that it will work out of the box just yet. + +Also, if the versions in this folder are out-dated, you can always run `grunt web` to generate the latest library. \ No newline at end of file diff --git a/web-dist/discord.js b/web-dist/discord.3.3.0.js similarity index 85% rename from web-dist/discord.js rename to web-dist/discord.3.3.0.js index 2eb328b51..6753dcf6b 100644 --- a/web-dist/discord.js +++ b/web-dist/discord.3.3.0.js @@ -20,7 +20,7 @@ var WebSocket = require("ws"); var fs = require("fs"); var defaultOptions = { - cache_tokens: false + queue: false }; var Client = (function () { @@ -36,10 +36,11 @@ var Client = (function () { further efforts will be made to connect. */ this.options = options; + this.options.queue = this.options.queue; this.token = token; this.state = 0; this.websocket = null; - this.events = new Map(); + this.events = {}; this.user = null; this.alreadySentData = false; this.serverCreateListener = new Map(); @@ -61,6 +62,8 @@ var Client = (function () { this.serverCache = []; this.pmChannelCache = []; this.readyTime = null; + this.checkingQueue = {}; + this.queue = {}; } _createClass(Client, [{ @@ -80,12 +83,12 @@ var Client = (function () { }, { key: "on", value: function on(event, fn) { - this.events.set(event, fn); + this.events[event] = fn; } }, { key: "off", - value: function off(event, fn) { - this.events["delete"](event); + value: function off(event) { + this.events[event] = null; } }, { key: "keepAlive", @@ -105,7 +108,7 @@ var Client = (function () { for (var arg in arguments) { args.push(arguments[arg]); } - var evt = this.events.get(event); + var evt = this.events[event]; if (evt) { evt.apply(this, args.slice(1)); } @@ -137,7 +140,9 @@ var Client = (function () { if (err) { self.state = 4; //set state to disconnected self.trigger("disconnected"); - self.websocket.close(); + if (self.websocket) { + self.websocket.close(); + } callback(err); reject(err); } else { @@ -319,13 +324,19 @@ var Client = (function () { } }, { key: "reply", - value: function reply(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; + value: function reply(destination, message, tts) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3]; var self = this; return new Promise(function (response, reject) { + if (typeof tts === "function") { + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } + var user = destination.sender; self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); }); @@ -337,7 +348,7 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { if (timeout) { setTimeout(remove, timeout); } else { @@ -345,17 +356,37 @@ var Client = (function () { } function remove() { - request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - callback(null); - resolve(); + if (self.options.queue) { + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; } - }); + self.queue[message.channel.id].push({ + action: "deleteMessage", + message: message, + then: good, + error: bad + }); + + self.checkQueue(message.channel.id); + } else { + self._deleteMessage(message).then(good)["catch"](bad); + } + } + + function good() { + prom.success = true; + callback(null); + resolve(); + } + + function bad(err) { + prom.error = err; + callback(err); + reject(err); } }); + + return prom; } }, { key: "updateMessage", @@ -364,26 +395,41 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { content = content instanceof Array ? content.join("\n") : content; - request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ - content: content, - mentions: [] - }).end(function (err, res) { - if (err) { - callback(err); - reject(err); - } else { - var msg = new Message(res.body, message.channel, message.mentions, message.sender); - callback(null, msg); - resolve(msg); - - message.channel.messages[message.channel.messages.indexOf(message)] = msg; + if (self.options.queue) { + if (!self.queue[message.channel.id]) { + self.queue[message.channel.id] = []; } - }); + self.queue[message.channel.id].push({ + action: "updateMessage", + message: message, + content: content, + then: good, + error: bad + }); + + self.checkQueue(message.channel.id); + } else { + self._updateMessage(message, content).then(good)["catch"](bad); + } + + function good(msg) { + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function bad(error) { + prom.error = error; + callback(error); + reject(error); + } }); + + return prom; } }, { key: "setUsername", @@ -547,7 +593,7 @@ var Client = (function () { var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { var fstream; @@ -558,40 +604,60 @@ var Client = (function () { fstream = file; } - self.resolveDestination(destination).then(send)["catch"](error); + self.resolveDestination(destination).then(send)["catch"](bad); function send(destination) { - request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", fstream, fileName).end(function (err, res) { - - if (err) { - error(err); - } else { - - var chann = self.getChannel("id", destination); - if (chann) { - var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); - callback(null, msg); - resolve(msg); - } + if (self.options.queue) { + //queue send file too + if (!self.queue[destination]) { + self.queue[destination] = []; } - }); + + self.queue[destination].push({ + action: "sendFile", + attachment: fstream, + attachmentName: fileName, + then: good, + error: bad + }); + + self.checkQueue(destination); + } else { + //not queue + self._sendFile(destination, fstream, fileName).then(good)["catch"](bad); + } } - function error(err) { + function good(msg) { + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function bad(err) { + prom.error = err; callback(err); reject(err); } }); + + return prom; } }, { key: "sendMessage", - value: function sendMessage(destination, message) { - var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2]; - var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3]; + value: function sendMessage(destination, message, tts) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3]; + var premessage = arguments.length <= 4 || arguments[4] === undefined ? "" : arguments[4]; var self = this; - return new Promise(function (resolve, reject) { + var prom = new Promise(function (resolve, reject) { + + if (typeof tts === "function") { + // tts is a function, which means the developer wants this to be the callback + callback = tts; + tts = false; + } message = premessage + resolveMessage(message); var mentions = resolveMentions(); @@ -603,55 +669,37 @@ var Client = (function () { } function send(destination) { - - request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ - content: message, - mentions: mentions - }).end(function (err, res) { - - if (err) { - callback(err); - reject(err); - } else { - var data = res.body; - - var mentions = []; - - data.mentions = data.mentions || []; //for some reason this was not defined at some point? - - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var mention = _step3.value; - - mentions.push(self.addUser(mention)); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3["return"]) { - _iterator3["return"](); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - - var channel = self.getChannel("id", data.channel_id); - if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); - callback(null, msg); - resolve(msg); - } + if (self.options.queue) { + //we're QUEUEING messages, so sending them sequentially based on servers. + if (!self.queue[destination]) { + self.queue[destination] = []; } - }); + + self.queue[destination].push({ + action: "sendMessage", + content: message, + mentions: mentions, + tts: !!tts, //incase it's not a boolean + then: mgood, + error: mbad + }); + + self.checkQueue(destination); + } else { + self._sendMessage(destination, message, tts, mentions).then(mgood)["catch"](mbad); + } + } + + function mgood(msg) { + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function mbad(error) { + prom.error = error; + callback(error); + reject(error); } function resolveMessage() { @@ -664,27 +712,27 @@ var Client = (function () { function resolveMentions() { var _mentions = []; - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; try { - for (var _iterator4 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var mention = _step4.value; + for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; _mentions.push(mention.substring(2, mention.length - 1)); } } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; + _didIteratorError3 = true; + _iteratorError3 = err; } finally { try { - if (!_iteratorNormalCompletion4 && _iterator4["return"]) { - _iterator4["return"](); + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); } } finally { - if (_didIteratorError4) { - throw _iteratorError4; + if (_didIteratorError3) { + throw _iteratorError3; } } } @@ -692,6 +740,8 @@ var Client = (function () { return _mentions; } }); + + return prom; } //def createws @@ -737,15 +787,40 @@ var Client = (function () { self.user = self.addUser(data.user); + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { - for (var _iterator5 = data.guilds[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { - var _server = _step5.value; + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; - var server = self.addServer(_server); + var pmc = self.addPMChannel(_pmc); } } catch (err) { _didIteratorError5 = true; @@ -762,31 +837,6 @@ var Client = (function () { } } - var _iteratorNormalCompletion6 = true; - var _didIteratorError6 = false; - var _iteratorError6 = undefined; - - try { - for (var _iterator6 = data.private_channels[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { - var _pmc = _step6.value; - - var pmc = self.addPMChannel(_pmc); - } - } catch (err) { - _didIteratorError6 = true; - _iteratorError6 = err; - } finally { - try { - if (!_iteratorNormalCompletion6 && _iterator6["return"]) { - _iterator6["return"](); - } - } finally { - if (_didIteratorError6) { - throw _iteratorError6; - } - } - } - self.trigger("ready"); self.readyTime = Date.now(); self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); @@ -801,27 +851,27 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion7 = true; - var _didIteratorError7 = false; - var _iteratorError7 = undefined; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; try { - for (var _iterator7 = data.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { - var mention = _step7.value; + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError7 = true; - _iteratorError7 = err; + _didIteratorError6 = true; + _iteratorError6 = err; } finally { try { - if (!_iteratorNormalCompletion7 && _iterator7["return"]) { - _iterator7["return"](); + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); } } finally { - if (_didIteratorError7) { - throw _iteratorError7; + if (_didIteratorError6) { + throw _iteratorError6; } } } @@ -866,27 +916,27 @@ var Client = (function () { } var mentions = []; - var _iteratorNormalCompletion8 = true; - var _didIteratorError8 = false; - var _iteratorError8 = undefined; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; try { - for (var _iterator8 = info.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { - var mention = _step8.value; + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError8 = true; - _iteratorError8 = err; + _didIteratorError7 = true; + _iteratorError7 = err; } finally { try { - if (!_iteratorNormalCompletion8 && _iterator8["return"]) { - _iterator8["return"](); + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); } } finally { - if (_didIteratorError8) { - throw _iteratorError8; + if (_didIteratorError7) { + throw _iteratorError7; } } } @@ -1101,27 +1151,27 @@ var Client = (function () { server = new Server(data, this); this.serverCache.push(server); if (data.channels) { - var _iteratorNormalCompletion9 = true; - var _didIteratorError9 = false; - var _iteratorError9 = undefined; + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; try { - for (var _iterator9 = data.channels[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var channel = _step9.value; + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; server.channels.push(this.addChannel(channel, server.id)); } } catch (err) { - _didIteratorError9 = true; - _iteratorError9 = err; + _didIteratorError8 = true; + _iteratorError8 = err; } finally { try { - if (!_iteratorNormalCompletion9 && _iterator9["return"]) { - _iterator9["return"](); + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); } } finally { - if (_didIteratorError9) { - throw _iteratorError9; + if (_didIteratorError8) { + throw _iteratorError8; } } } @@ -1135,16 +1185,50 @@ var Client = (function () { }, { key: "getUser", value: function getUser(key, value) { + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var user = _step9.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { - for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var user = _step10.value; + for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; - if (user[key] === value) { - return user; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -1162,19 +1246,17 @@ var Client = (function () { } } - return null; + return this.getPMChannel(key, value); //might be a PM } - - //def getChannel }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getPMChannel", + value: function getPMChannel(key, value) { var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { - for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var channel = _step11.value; if (channel[key] === value) { @@ -1196,21 +1278,23 @@ var Client = (function () { } } - return this.getPMChannel(key, value); //might be a PM + return null; } + + //def getServer }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { + key: "getServer", + value: function getServer(key, value) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { - for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { - var channel = _step12.value; + for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var server = _step12.value; - if (channel[key] === value) { - return channel; + if (server[key] === value) { + return server; } } } catch (err) { @@ -1231,40 +1315,6 @@ var Client = (function () { return null; } - //def getServer - }, { - key: "getServer", - value: function getServer(key, value) { - var _iteratorNormalCompletion13 = true; - var _didIteratorError13 = false; - var _iteratorError13 = undefined; - - try { - for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var server = _step13.value; - - if (server[key] === value) { - return server; - } - } - } catch (err) { - _didIteratorError13 = true; - _iteratorError13 = err; - } finally { - try { - if (!_iteratorNormalCompletion13 && _iterator13["return"]) { - _iterator13["return"](); - } - } finally { - if (_didIteratorError13) { - throw _iteratorError13; - } - } - } - - return null; - } - //def trySendConnData }, { key: "trySendConnData", @@ -1317,13 +1367,13 @@ var Client = (function () { } else if (destination instanceof User) { //check if we have a PM - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; try { - for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var pmc = _step14.value; + for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var pmc = _step13.value; if (pmc.user.equals(destination)) { return pmc.id; @@ -1331,6 +1381,62 @@ var Client = (function () { } //we don't, at this point we're late + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var mention = _step14.value; + + mentions.push(self.addUser(mention)); + } } catch (err) { _didIteratorError14 = true; _iteratorError14 = err; @@ -1346,15 +1452,152 @@ var Client = (function () { } } - self.startPM(destination).then(function (pmc) { - resolve(pmc.id); - })["catch"](reject); - } else { - channId = destination; + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } } - if (channId) resolve(channId); + }); }); } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } }, { key: "uptime", get: function get() { @@ -1509,6 +1752,11 @@ var PMChannel = (function () { return null; } + }, { + key: "isPrivate", + get: function get() { + return true; + } }]); return PMChannel; @@ -1589,6 +1837,11 @@ var Channel = (function () { get: function get() { return this.server.client; } + }, { + key: "isPrivate", + get: function get() { + return false; + } }]); return Channel; @@ -1651,6 +1904,8 @@ 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 PMChannel = require("./PMChannel.js"); + var Message = (function () { function Message(data, channel, mentions, author) { _classCallCheck(this, Message); @@ -1711,13 +1966,18 @@ var Message = (function () { get: function get() { return this.author; } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } }]); return Message; })(); module.exports = Message; -},{}],8:[function(require,module,exports){ +},{"./PMChannel.js":3}],8:[function(require,module,exports){ "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; }; })(); diff --git a/web-dist/discord.min.js b/web-dist/discord.min.js deleted file mode 100644 index 37ba4d200..000000000 --- a/web-dist/discord.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}b=d+l(b);var o=m();e.resolveDestination(a).then(j)["catch"](i)})}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this), -c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 833f0478d412015d28a6f8c09acc657d6d594f30 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 6 Sep 2015 20:21:37 +0100 Subject: [PATCH 102/191] Fixed minify script --- gruntfile.js | 2 +- web-dist/discord.min.3.3.0.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 web-dist/discord.min.3.3.0.js diff --git a/gruntfile.js b/gruntfile.js index 126762092..a8972256f 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -31,7 +31,7 @@ module.exports = function (grunt) { uglify: { min: { files: { - "./web-dist/discord.min.<%= pkg.version %>.js": "./web-dist/discord.js" + "./web-dist/discord.min.<%= pkg.version %>.js": "./web-dist/discord.<%= pkg.version %>.js" } } } diff --git a/web-dist/discord.min.3.3.0.js b/web-dist/discord.min.3.3.0.js new file mode 100644 index 000000000..71f1235d5 --- /dev/null +++ b/web-dist/discord.min.3.3.0.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(), +this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 527947dbd3d939bd0685ae006b2254d7c88c41cf Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 15:46:22 +0100 Subject: [PATCH 103/191] 3.3.1 --- {.settings => .vscode}/settings.json | 0 {.settings => .vscode}/tasks.json | 0 lib/Client.js | 6 +- package.json | 2 +- src/Client.js | 6 +- test/bot.1.js | 3 +- web-dist/discord.3.3.1.js | 3590 ++++++++++++++++++++++++++ web-dist/discord.min.3.3.1.js | 2 + 8 files changed, 3602 insertions(+), 7 deletions(-) rename {.settings => .vscode}/settings.json (100%) rename {.settings => .vscode}/tasks.json (100%) create mode 100644 web-dist/discord.3.3.1.js create mode 100644 web-dist/discord.min.3.3.1.js diff --git a/.settings/settings.json b/.vscode/settings.json similarity index 100% rename from .settings/settings.json rename to .vscode/settings.json diff --git a/.settings/tasks.json b/.vscode/tasks.json similarity index 100% rename from .settings/tasks.json rename to .vscode/tasks.json diff --git a/lib/Client.js b/lib/Client.js index 85119d53a..36ac902e0 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1039,7 +1039,7 @@ var Client = (function () { server.members.push(user); } - self.trigger("serverNewMember", user); + self.trigger("serverNewMember", user, server); } break; @@ -1056,7 +1056,7 @@ var Client = (function () { server.members.splice(server.members.indexOf(user), 1); } - self.trigger("serverRemoveMember", user); + self.trigger("serverRemoveMember", user, server); } break; @@ -1396,6 +1396,7 @@ var Client = (function () { } self.startPM(destination).then(function (pmc) { + console.log(pmc); resolve(pmc.id); })["catch"](reject); } else { @@ -1507,6 +1508,7 @@ var Client = (function () { value: function _deleteMessage(message) { var self = this; return new Promise(function (resolve, reject) { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { if (err) { reject(err); diff --git a/package.json b/package.json index e1c2cc82f..0eddd6cfa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.3.0", + "version": "3.3.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 03cb6a577..f4c4c1287 100644 --- a/src/Client.js +++ b/src/Client.js @@ -943,7 +943,7 @@ class Client { server.members.push(user); } - self.trigger("serverNewMember", user); + self.trigger("serverNewMember", user, server); } break; @@ -960,7 +960,7 @@ class Client { server.members.splice(server.members.indexOf(user), 1); } - self.trigger("serverRemoveMember", user); + self.trigger("serverRemoveMember", user, server); } break; @@ -1155,6 +1155,7 @@ class Client { //we don't, at this point we're late self.startPM(destination).then(function (pmc) { + console.log(pmc); resolve(pmc.id); }).catch(reject); @@ -1260,6 +1261,7 @@ class Client { _deleteMessage(message){ var self = this; return new Promise(function(resolve, reject){ + request .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) .set("authorization", self.token) diff --git a/test/bot.1.js b/test/bot.1.js index 1230b9bb6..f99314baa 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -17,8 +17,7 @@ mybot.on("message", function (message) { } // we can go ahead :) - console.log(message.sender.username); - mybot.sendMessage(message.channel, message.sender.username); + mybot.sendMessage(message.author, message.sender.username); }); mybot.on("ready", function () { diff --git a/web-dist/discord.3.3.1.js b/web-dist/discord.3.3.1.js new file mode 100644 index 000000000..9992d6869 --- /dev/null +++ b/web-dist/discord.3.3.1.js @@ -0,0 +1,3590 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + + return prom; + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener.get(data.id)) { + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener["delete"](data.id); + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user, server); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user, server); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var user = _step9.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var server = _step12.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var pmc = _step13.value; + + if (pmc.user.equals(destination)) { + return pmc.id; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var mention = _step14.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +function getGateway() { + + var self = this; + + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); +} + +module.exports = Client; +},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "isPrivate", + get: function get() { + return true; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object && object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "#" + this.name; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }, { + key: "isPrivate", + get: function get() { + return false; + } + }]); + + return Channel; +})(); + +module.exports = Channel; +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; +},{}],7:[function(require,module,exports){ +"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 PMChannel = require("./PMChannel.js"); + +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } + }]); + + return Message; +})(); + +module.exports = Message; +},{"./PMChannel.js":3}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.3.3.1.js b/web-dist/discord.min.3.3.1.js new file mode 100644 index 000000000..2079f39b6 --- /dev/null +++ b/web-dist/discord.min.3.3.1.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(), +this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 8b88fd1ea59507b9912e33c2f1ff7f08e36e5b9a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 15:49:56 +0100 Subject: [PATCH 104/191] 3.3.2, fixed PMs. --- lib/Client.js | 3 +- package.json | 2 +- src/Client.js | 3 +- web-dist/discord.3.3.2.js | 3593 +++++++++++++++++++++++++++++++++ web-dist/discord.min.3.3.2.js | 2 + 5 files changed, 3600 insertions(+), 3 deletions(-) create mode 100644 web-dist/discord.3.3.2.js create mode 100644 web-dist/discord.min.3.3.2.js diff --git a/lib/Client.js b/lib/Client.js index 36ac902e0..80b9a925f 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1375,7 +1375,8 @@ var Client = (function () { var pmc = _step13.value; if (pmc.user.equals(destination)) { - return pmc.id; + resolve(pmc.id); + return; } } diff --git a/package.json b/package.json index 0eddd6cfa..4af3dbde8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.3.1", + "version": "3.3.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index f4c4c1287..6421121e6 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1149,7 +1149,8 @@ class Client { //check if we have a PM for (var pmc of self.pmChannelCache) { if (pmc.user.equals(destination)) { - return pmc.id; + resolve(pmc.id); + return; } } diff --git a/web-dist/discord.3.3.2.js b/web-dist/discord.3.3.2.js new file mode 100644 index 000000000..ee7512e4b --- /dev/null +++ b/web-dist/discord.3.3.2.js @@ -0,0 +1,3593 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + + return prom; + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener.get(data.id)) { + var cbs = self.serverCreateListener.get(data.id); + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener["delete"](data.id); + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user, server); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user, server); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var user = _step9.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var channel = _step10.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var server = _step12.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var pmc = _step13.value; + + if (pmc.user.equals(destination)) { + resolve(pmc.id); + return; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + self.startPM(destination).then(function (pmc) { + console.log(pmc); + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var mention = _step14.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var channel = _step15.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +function getGateway() { + + var self = this; + + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); +} + +module.exports = Client; +},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "isPrivate", + get: function get() { + return true; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object && object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "#" + this.name; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }, { + key: "isPrivate", + get: function get() { + return false; + } + }]); + + return Channel; +})(); + +module.exports = Channel; +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; +},{}],7:[function(require,module,exports){ +"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 PMChannel = require("./PMChannel.js"); + +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } + }]); + + return Message; +})(); + +module.exports = Message; +},{"./PMChannel.js":3}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }]); + + return Server; +})(); + +module.exports = Server; +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.3.3.2.js b/web-dist/discord.min.3.3.2.js new file mode 100644 index 000000000..9a41bcaad --- /dev/null +++ b/web-dist/discord.min.3.3.2.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return void d(o.id)}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){console.log(a),d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0, +this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From c4d9405f64621146ce0c06d366bb4b7dc773dbc1 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 16:00:38 +0100 Subject: [PATCH 105/191] Preparing for major API change, added authorisation param to request --- lib/Client.js | 31 ++++--- src/Client.js | 230 +++++++++++++++++++++++++------------------------- 2 files changed, 129 insertions(+), 132 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 80b9a925f..b14d8815d 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -148,7 +148,7 @@ var Client = (function () { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token - getGateway().then(function (url) { + self.getGateway().then(function (url) { self.createws(url); callback(null, self.token); resolve(self.token); @@ -1600,6 +1600,20 @@ var Client = (function () { })(); } } + }, { + key: "getGateway", + value: function getGateway() { + var self = this; + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + } }, { key: "uptime", get: function get() { @@ -1668,19 +1682,4 @@ var Client = (function () { return Client; })(); -function getGateway() { - - var self = this; - - return new Promise(function (resolve, reject) { - request.get(Endpoints.API + "/gateway").end(function (err, res) { - if (err) { - reject(err); - } else { - resolve(res.body.url); - } - }); - }); -} - module.exports = Client; \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index 6421121e6..1f46a0850 100644 --- a/src/Client.js +++ b/src/Client.js @@ -153,7 +153,7 @@ class Client { if (err) { self.state = 4; //set state to disconnected self.trigger("disconnected"); - if(self.websocket){ + if (self.websocket) { self.websocket.close(); } callback(err); @@ -162,7 +162,7 @@ class Client { self.state = 2; //set state to logged in (not yet ready) self.token = res.body.token; //set our token - getGateway().then(function (url) { + self.getGateway().then(function (url) { self.createws(url); callback(null, self.token); resolve(self.token); @@ -367,7 +367,7 @@ class Client { return new Promise(function (response, reject) { - if(typeof tts === "function"){ + if (typeof tts === "function") { // tts is a function, which means the developer wants this to be the callback callback = tts; tts = false; @@ -383,7 +383,7 @@ class Client { deleteMessage(message, timeout, callback = function (err, msg) { }) { var self = this; - + var prom = new Promise(function (resolve, reject) { if (timeout) { setTimeout(remove, timeout) @@ -392,7 +392,7 @@ class Client { } function remove() { - if(self.options.queue){ + if (self.options.queue) { if (!self.queue[message.channel.id]) { self.queue[message.channel.id] = []; } @@ -402,26 +402,26 @@ class Client { then: good, error: bad }); - + self.checkQueue(message.channel.id); - }else{ + } else { self._deleteMessage(message).then(good).catch(bad); } } - - function good(){ + + function good() { prom.success = true; callback(null); resolve(); } - - function bad(err){ + + function bad(err) { prom.error = err; callback(err); reject(err); } }); - + return prom; } @@ -433,7 +433,7 @@ class Client { content = (content instanceof Array ? content.join("\n") : content); - if(self.options.queue){ + if (self.options.queue) { if (!self.queue[message.channel.id]) { self.queue[message.channel.id] = []; } @@ -444,26 +444,26 @@ class Client { then: good, error: bad }); - + self.checkQueue(message.channel.id); - }else{ + } else { self._updateMessage(message, content).then(good).catch(bad); } - - function good(msg){ - prom.message = msg; - callback(null, msg); - resolve(msg); - } - - function bad(error){ - prom.error = error; - callback(error); - reject(error); - } + + function good(msg) { + prom.message = msg; + callback(null, msg); + resolve(msg); + } + + function bad(error) { + prom.error = error; + callback(error); + reject(error); + } }); - + return prom; } @@ -611,7 +611,7 @@ class Client { self.resolveDestination(destination).then(send).catch(bad); function send(destination) { - if(self.options.queue){ + if (self.options.queue) { //queue send file too if (!self.queue[destination]) { self.queue[destination] = []; @@ -619,14 +619,14 @@ class Client { self.queue[destination].push({ action: "sendFile", - attachment : fstream, - attachmentName : fileName, + attachment: fstream, + attachmentName: fileName, then: good, error: bad }); self.checkQueue(destination); - }else{ + } else { //not queue self._sendFile(destination, fstream, fileName).then(good).catch(bad); } @@ -645,7 +645,7 @@ class Client { } }); - + return prom; } @@ -655,13 +655,13 @@ class Client { var self = this; var prom = new Promise(function (resolve, reject) { - - if(typeof tts === "function"){ + + if (typeof tts === "function") { // tts is a function, which means the developer wants this to be the callback callback = tts; tts = false; } - + message = premessage + resolveMessage(message); var mentions = resolveMentions(); self.resolveDestination(destination).then(send).catch(error); @@ -682,7 +682,7 @@ class Client { action: "sendMessage", content: message, mentions: mentions, - tts : !!tts, //incase it's not a boolean + tts: !!tts, //incase it's not a boolean then: mgood, error: mbad }); @@ -723,7 +723,7 @@ class Client { } }); - + return prom; } @@ -1179,7 +1179,7 @@ class Client { .send({ content: content, mentions: mentions, - tts : tts + tts: tts }) .end(function (err, res) { @@ -1207,39 +1207,39 @@ class Client { }); } - - _sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png"){ - + + _sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png") { + var self = this; - - return new Promise(function(resolve, reject){ - request - .post(`${Endpoints.CHANNELS}/${destination}/messages`) - .set("authorization", self.token) - .attach("file", attachment, attachmentName) - .end(function (err, res) { - if (err) { - reject(err); - } else { - - var chann = self.getChannel("id", destination); - if (chann) { - var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); - resolve(msg); - } + return new Promise(function (resolve, reject) { + request + .post(`${Endpoints.CHANNELS}/${destination}/messages`) + .set("authorization", self.token) + .attach("file", attachment, attachmentName) + .end(function (err, res) { + if (err) { + reject(err); + } else { + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); } - }); + + } + + }); }); - + } - - _updateMessage(message, content){ + + _updateMessage(message, content) { var self = this; - return new Promise(function(resolve, reject){ + return new Promise(function (resolve, reject) { request .patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) .set("authorization", self.token) @@ -1258,28 +1258,28 @@ class Client { }); }); } - - _deleteMessage(message){ + + _deleteMessage(message) { var self = this; - return new Promise(function(resolve, reject){ - + return new Promise(function (resolve, reject) { + request - .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) - .set("authorization", self.token) - .end(function (err, res) { - if (err) { - reject(err); - } else { - resolve(); - } - }); + .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`) + .set("authorization", self.token) + .end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); }); } checkQueue(channelID) { var self = this; - + if (!this.checkingQueue[channelID]) { //if we aren't already checking this queue. this.checkingQueue[channelID] = true; @@ -1309,12 +1309,12 @@ class Client { case "sendFile": var fileToSend = queuedEvent; self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName) - .then(function (msg){ + .then(function (msg) { fileToSend.then(msg); self.queue[channelID].shift(); doNext(); }) - .catch(function(err){ + .catch(function (err) { fileToSend.error(err); self.queue[channelID].shift(); doNext(); @@ -1323,30 +1323,30 @@ class Client { case "updateMessage": var msgToUpd = queuedEvent; self._updateMessage(msgToUpd.message, msgToUpd.content) - .then(function(msg){ - msgToUpd.then(msg); - self.queue[channelID].shift(); - doNext(); - }) - .catch(function(err){ - msgToUpd.error(err); - self.queue[channelID].shift(); - doNext(); - }); + .then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + }) + .catch(function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); break; case "deleteMessage": var msgToDel = queuedEvent; self._deleteMessage(msgToDel.message) - .then(function(msg){ - msgToDel.then(msg); - self.queue[channelID].shift(); - doNext(); - }) - .catch(function(err){ - msgToDel.error(err); - self.queue[channelID].shift(); - doNext(); - }); + .then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + }) + .catch(function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); break; default: done(); @@ -1360,24 +1360,22 @@ class Client { } } } -} - -function getGateway() { - - var self = this; - - return new Promise(function (resolve, reject) { - request - .get(`${Endpoints.API}/gateway`) - .end(function (err, res) { - if (err) { - reject(err); - } else { - resolve(res.body.url); - } - }); - }); + getGateway() { + var self = this; + return new Promise(function (resolve, reject) { + request + .get(`${Endpoints.API}/gateway`) + .set("authorization", self.token) + .end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + } } module.exports = Client; \ No newline at end of file From c904bdb3c30c96bc3cf4b7bb19b0b39057f2f222 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 16:05:52 +0100 Subject: [PATCH 106/191] added .users as well as .members in Server class --- lib/server.js | 5 +++++ src/server.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/lib/server.js b/lib/server.js index 5bf3beca1..a5c90170d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -165,6 +165,11 @@ var Server = (function () { get: function get() { return this.client.getUser("id", this.ownerID); } + }, { + key: "users", + get: function get() { + return this.members; + } }]); return Server; diff --git a/src/server.js b/src/server.js index 248a04683..c0f24af27 100644 --- a/src/server.js +++ b/src/server.js @@ -50,6 +50,10 @@ class Server { return this.client.getUser("id", this.ownerID); } + get users() { + return this.members; + } + // get/set getChannel(key, value) { for (var channel of this.channels) { From 106addbb1a0293c23b6bfd8f80f883d89fd7e153 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 16:07:48 +0100 Subject: [PATCH 107/191] Added channel toString --- lib/channel.js | 2 +- src/channel.js | 2 +- test/bot.1.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/channel.js b/lib/channel.js index dfb4f72d8..79bc71b55 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -64,7 +64,7 @@ var Channel = (function () { }, { key: "toString", value: function toString() { - return "#" + this.name; + return "<#" + this.id + ">"; } }, { key: "client", diff --git a/src/channel.js b/src/channel.js index 0dc0b957a..d813e9b74 100644 --- a/src/channel.js +++ b/src/channel.js @@ -34,7 +34,7 @@ class Channel { } toString(){ - return "#" + this.name; + return "<#" + this.id + ">"; } get isPrivate(){ diff --git a/test/bot.1.js b/test/bot.1.js index f99314baa..38f25d390 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -17,7 +17,7 @@ mybot.on("message", function (message) { } // we can go ahead :) - mybot.sendMessage(message.author, message.sender.username); + mybot.reply(message, message.channel); }); mybot.on("ready", function () { From efe07dbfc5b890f4771131afbea4a2b8876b8b4a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 16:09:10 +0100 Subject: [PATCH 108/191] Fixed reply method --- lib/Client.js | 2 +- src/Client.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index b14d8815d..71124b2ce 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -337,7 +337,7 @@ var Client = (function () { } var user = destination.sender; - self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject); + self.sendMessage(destination, message, tts, callback, user + ", ").then(response)["catch"](reject); }); } }, { diff --git a/src/Client.js b/src/Client.js index 1f46a0850..89486be44 100644 --- a/src/Client.js +++ b/src/Client.js @@ -374,7 +374,7 @@ class Client { } var user = destination.sender; - self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject); + self.sendMessage(destination, message, tts, callback, user + ", ").then(response).catch(reject); }); From cc2470054a65e5c2e20dbb297acb09e93b4807f9 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 12 Sep 2015 16:10:09 +0100 Subject: [PATCH 109/191] Updated version to 3.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4af3dbde8..55f98889f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.3.2", + "version": "3.3.3", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From ae1202aa2d254876f677eb8c822da0012a83b840 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 13 Sep 2015 15:19:54 +0100 Subject: [PATCH 110/191] 3.3.4, added support for older node versions --- lib/Client.js | 12 ++++++------ package.json | 2 +- src/Client.js | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 71124b2ce..eff03e5aa 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -42,7 +42,7 @@ var Client = (function () { this.events = {}; this.user = null; this.alreadySentData = false; - this.serverCreateListener = new Map(); + this.serverCreateListener = {}; this.email = "abc"; this.password = "abc"; @@ -205,7 +205,7 @@ var Client = (function () { // potentially redundant in future // creating here does NOT give us the channels of the server // so we must wait for the guild_create event. - self.serverCreateListener.set(res.body.id, [resolve, callback]); + self.serverCreateListener[res.body.id] = [resolve, callback]; /*var srv = self.addServer(res.body); callback(null, srv); resolve(srv);*/ @@ -578,7 +578,7 @@ var Client = (function () { if (self.getServer("id", res.body.guild.id)) { resolve(self.getServer("id", res.body.guild.id)); } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + self.serverCreateListener[res.body.guild.id] = [resolve, callback]; } } }); @@ -1000,11 +1000,11 @@ var Client = (function () { }*/ - if (self.serverCreateListener.get(data.id)) { - var cbs = self.serverCreateListener.get(data.id); + if (self.serverCreateListener[data.id]) { + var cbs = self.serverCreateListener[data.id]; cbs[0](server); //promise then callback cbs[1](null, server); //legacy callback - self.serverCreateListener["delete"](data.id); + self.serverCreateListener[data.id] = null; } self.trigger("serverCreate", server); diff --git a/package.json b/package.json index 55f98889f..89ca0fba0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.3.3", + "version": "3.3.4", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { diff --git a/src/Client.js b/src/Client.js index 89486be44..f7919a653 100644 --- a/src/Client.js +++ b/src/Client.js @@ -32,7 +32,7 @@ class Client { this.events = {}; this.user = null; this.alreadySentData = false; - this.serverCreateListener = new Map(); + this.serverCreateListener = {}; this.email = "abc"; this.password = "abc"; @@ -227,7 +227,7 @@ class Client { // potentially redundant in future // creating here does NOT give us the channels of the server // so we must wait for the guild_create event. - self.serverCreateListener.set(res.body.id, [resolve, callback]); + self.serverCreateListener[res.body.id] = [resolve, callback]; /*var srv = self.addServer(res.body); callback(null, srv); resolve(srv);*/ @@ -584,7 +584,7 @@ class Client { if (self.getServer("id", res.body.guild.id)) { resolve(self.getServer("id", res.body.guild.id)); } else { - self.serverCreateListener.set(res.body.guild.id, [resolve, callback]); + self.serverCreateListener[res.body.guild.id] = [resolve, callback]; } } }); @@ -903,11 +903,11 @@ class Client { }*/ - if (self.serverCreateListener.get(data.id)) { - var cbs = self.serverCreateListener.get(data.id); + if (self.serverCreateListener[data.id]) { + var cbs = self.serverCreateListener[data.id]; cbs[0](server); //promise then callback cbs[1](null, server); //legacy callback - self.serverCreateListener.delete(data.id); + self.serverCreateListener[data.id] = null; } self.trigger("serverCreate", server); From e1458b6405936c9d6599edc1aba591c14fd62cb3 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:26:10 +0100 Subject: [PATCH 111/191] makethedocs commit 1 init --- docs/Makefile | 192 +++++++++++++++++++++++++++++++++ docs/conf.py | 284 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 22 ++++ docs/make.bat | 263 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 761 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..751136e57 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,192 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/discordjs.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/discordjs.qhc" + +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/discordjs" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/discordjs" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..a7c230819 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# +# discord.js documentation build configuration file, created by +# sphinx-quickstart on Fri Sep 25 17:25:49 2015. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'discord.js' +copyright = u'2015, hydrabolt' +author = u'hydrabolt' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '3.3.4' +# The full version, including alpha/beta/rc tags. +release = '3.3.4' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'discordjsdoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'discordjs.tex', u'discord.js Documentation', + u'hydrabolt', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'discordjs', u'discord.js Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'discordjs', u'discord.js Documentation', + author, 'discordjs', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..88345f66d --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +.. discord.js documentation master file, created by + sphinx-quickstart on Fri Sep 25 17:25:49 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to discord.js's documentation! +====================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..c3d1c3bcc --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,263 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 2> nul +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\discordjs.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\discordjs.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end From 88b4332583cc1ddcd6784167184e629754bca58d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:29:32 +0100 Subject: [PATCH 112/191] updated theme on docs --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index a7c230819..d3f40bee4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -108,7 +108,7 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'alabaster' +html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the From 8986b9d939c667974235fb9c79f9d10c65c35f50 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:38:36 +0100 Subject: [PATCH 113/191] added get started --- docs/get_started.rst | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/get_started.rst diff --git a/docs/get_started.rst b/docs/get_started.rst new file mode 100644 index 000000000..ce05adbb9 --- /dev/null +++ b/docs/get_started.rst @@ -0,0 +1,8 @@ +=========== +Get Started +=========== + +Overview +-------- + +todo \ No newline at end of file From 76772d987633c437e0a2a45af98f2dc780c16c10 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:40:56 +0100 Subject: [PATCH 114/191] added get started to contents --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index 88345f66d..76666f375 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,7 @@ Contents: .. toctree:: :maxdepth: 2 + get_started From 3ff02584222a5c368caed60d27ffae2950f93826 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:43:23 +0100 Subject: [PATCH 115/191] fixed get started? --- docs/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 76666f375..338583ef0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -9,7 +9,6 @@ Welcome to discord.js's documentation! Contents: .. toctree:: - :maxdepth: 2 get_started From a74276ffdd4d1ec43c624cae0d2c1cbae512a3b8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 17:57:42 +0100 Subject: [PATCH 116/191] updated get started --- docs/get_started.rst | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/get_started.rst b/docs/get_started.rst index ce05adbb9..687d5fcbf 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -2,7 +2,17 @@ Get Started =========== -Overview --------- +Installation +------------ -todo \ No newline at end of file +Linux / OS X +~~~~~~~~~~~~ +Run ``npm install discord.js --save`` in your project's directory and you should be good to go! + +Windows +~~~~~~~~~~~~ +Unfortunately, the Windows installation process is a little more lengthy. You need to have `Visual Studio Express`_ (or any of the other distributions of it). This is necessary for build tools for the WebSocket dependency. + +After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well! + +.. _`Visual Studio Express`: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx \ No newline at end of file From f5fec11758ae6cfd54b254472b66aad58c76f65e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 18:05:04 +0100 Subject: [PATCH 117/191] added small note --- docs/get_started.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/get_started.rst b/docs/get_started.rst index 687d5fcbf..a6d88d366 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -15,4 +15,6 @@ Unfortunately, the Windows installation process is a little more lengthy. You ne After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well! +.. note:: If you are using another version of Visual Studio, such as 2012, replace the flag with ``--msvs_version=2012`` + .. _`Visual Studio Express`: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx \ No newline at end of file From 5948e49445e7f87c1f294242164bf98c00d4e05f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 19:37:37 +0100 Subject: [PATCH 118/191] updated docs --- docs/get_started.rst | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/get_started.rst b/docs/get_started.rst index a6d88d366..8933558d1 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -13,8 +13,25 @@ Windows ~~~~~~~~~~~~ Unfortunately, the Windows installation process is a little more lengthy. You need to have `Visual Studio Express`_ (or any of the other distributions of it). This is necessary for build tools for the WebSocket dependency. -After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well! - .. note:: If you are using another version of Visual Studio, such as 2012, replace the flag with ``--msvs_version=2012`` -.. _`Visual Studio Express`: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx \ No newline at end of file +After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well! + +Cloning the Repo +---------------- +If you want to try some examples or make your own changes to discord.js, you can `clone the repo`_. + +Running Examples +~~~~~~~~~~~~~~~~ +If you've cloned the repo, you also have the option to run some examples. You can also do this by just copying the examples_ and then running them. I'd be more than happy to get some pull requests if you want to make any patches ;) + + +Before you run them though, you need to configure the ``examples/auth.json`` file. This should contain valid Discord credentials and passwords. + +After you've configured your credentials, just run ``node examples/pingpong.js`` to run the ping pong example. + + + +.. _Visual Studio Express: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx +.. _clone the repo: https://github.com/hydrabolt/discord.js.git +.. _examples: https://github.com/hydrabolt/discord.js/tree/master/examples \ No newline at end of file From cbfb78cc51f4a81e43418500035d24d053ce9830 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 19:43:42 +0100 Subject: [PATCH 119/191] Updated index.rst --- docs/index.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 338583ef0..adb6ebfd9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,6 +6,11 @@ Welcome to discord.js's documentation! ====================================== +discord.js is an easy-to-use and intuitive JavaScript API for Discord_. It should be able to +run in node.js / io.js and in the browser. + +.. note:: This documentation is still a work-in-progress, apologies if something isn't yet documented! + Contents: .. toctree:: @@ -17,6 +22,6 @@ Indices and tables ================== * :ref:`genindex` -* :ref:`modindex` * :ref:`search` +.. _Discord : https://discordapp.com/ From a8da6609db52c8a4cb09dae2c45ddd5f16ec9d03 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 20:00:05 +0100 Subject: [PATCH 120/191] Added troubleshooting to docs --- .vscode/settings.json | 3 +-- docs/get_started.rst | 2 +- docs/troubleshooting.rst | 10 ++++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 docs/troubleshooting.rst diff --git a/.vscode/settings.json b/.vscode/settings.json index 20af2f68a..81c4b4351 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,2 @@ // Place your settings in this file to overwrite default and user settings. -{ -} \ No newline at end of file +{ "editor.wrappingColumn": 0 } \ No newline at end of file diff --git a/docs/get_started.rst b/docs/get_started.rst index 8933558d1..96c7b1af6 100644 --- a/docs/get_started.rst +++ b/docs/get_started.rst @@ -19,7 +19,7 @@ After you have obtained these tools, you need to run ``npm install discord.js -- Cloning the Repo ---------------- -If you want to try some examples or make your own changes to discord.js, you can `clone the repo`_. +If you want to try some examples or make your own changes to discord.js, you can `clone the repo`_. After that run ``npm install`` to install dependencies. Running Examples ~~~~~~~~~~~~~~~~ diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst new file mode 100644 index 000000000..3f5fa02ad --- /dev/null +++ b/docs/troubleshooting.rst @@ -0,0 +1,10 @@ +Troubleshooting +=============== + +Occasionally, the API can stop working for whatever reason. If it was working previously and it stopped working on the same version, it means that there's been a change to the Discord API. In this case, please `make an issue`_ if one relating to a similar issue doesn't exist. Please post a stacktrace if there is one, and be as detailed as possible - *"the API isn't working"* doesn't help at all. + +If there is already an issue, feel free to comment that you're also experiencing the same thing. This helps to see how widespread the bug is. + +You can try reconnecting before submitting an issue, as sometimes some of the servers may be slightly different. + +.. _make an issue : https://github.com/hydrabolt/discord.js/issues \ No newline at end of file From d9528f19805022b76bb95bc0a9b581fb77b7c16f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 25 Sep 2015 20:27:45 +0100 Subject: [PATCH 121/191] Added simple bot --- docs/create_simple_bot.rst | 132 +++++++++++++++++++++++++++++++++++++ docs/index.rst | 2 + 2 files changed, 134 insertions(+) create mode 100644 docs/create_simple_bot.rst diff --git a/docs/create_simple_bot.rst b/docs/create_simple_bot.rst new file mode 100644 index 000000000..f1115cd12 --- /dev/null +++ b/docs/create_simple_bot.rst @@ -0,0 +1,132 @@ +Creating a Simple Bot +===================== + +This page will walk you through writing a simple bot and will introduce you to some of the most important functions and objects you will encounter in the API. + +Setting up a Project +-------------------- + +Before you start creating your bot, you need to create a directory, for example *discordbot*. + +After you've done that, open up the directory and have a look at how to `install the module`_. After you've installed the module, you can progress to the next step + +Creating the Bot +---------------- + +Now we can begin writing the bot. This bot will just server the user their avatar but at a higher resolution - assuming they have one. + +Firstly, create a file named ``bot.js`` in the directory you made earlier. Open it up, and type the following lines of code: + +.. code-block:: js + + var Discord = require("discord.js"); + var bot = new Discord.Client(); + +This code firstly imports the discord.js module, which contains classes to help you create clients for Discord. The second line creates a new Discord Client, which we can manipulate later. Now, we want the client to be alerted when there is a new message and do something, so we can type this: + +.. code-block:: js + + bot.on("message", function(message){ + + } ) + +This will simply get our client to listen out for new messages, but not yet do anything. Let's have a look at this: + +.. code-block:: js + + bot.on("message", function(message){ + + if( message.content === "avatar me!" ){ + + } + + } ) + +This code will now get our client to execute anything inside the if statement as long as the message sent was "avatar me!" We can now get it to see if the user has an avatar: + +.. code-block:: js + + bot.on("message", function(message){ + + if( message.content === "avatar me!" ){ + + var usersAvatar = message.sender.avatarURL; + + if(usersAvatar){ + // user has an avatar + }else{ + // user doesn't have an avatar + } + + } + + } ) + +This code will now see if the user has an avatar and then do something based on that, let's finalise it: + +.. code-block:: js + + bot.on("message", function(message){ + + if( message.content === "avatar me!" ){ + + var usersAvatar = message.sender.avatarURL; + + if(usersAvatar){ + // user has an avatar + + bot.reply(message, "your avatar can be found at " + usersAvatar); + + }else{ + // user doesn't have an avatar + + bot.reply(message, "you don't have an avatar!"); + } + + } + + } ) + +Let's have a look at the function we used here; *bot.reply*. This function takes 2 necessary parameters, a message object to reply to and a message to send. The first parameter we already have, and it is the message we have received. The second parameter is what we want to send. + +Now that we've finished the listener event, we need to log the client in: + +.. code-block:: js + + bot.login("your discord email", "your discord password"); + +And that's it! Run the code with ``node bot.js`` and wait a few seconds, and then try sending *avatar me!* to any of the channels that the user you provided has details to. + +Final Product +------------- +.. code-block:: js + + var Discord = require("discord.js"); + var bot = new Discord.Client(); + + bot.on("message", function(message){ + + if( message.content === "avatar me!" ){ + + var usersAvatar = message.sender.avatarURL; + + if(usersAvatar){ + // user has an avatar + + bot.reply(message, "your avatar can be found at " + usersAvatar); + + }else{ + // user doesn't have an avatar + + bot.reply(message, "you don't have an avatar!"); + } + + } + + } ); + + bot.login("your discord email", "your discord password"); + +.. note:: This page is still a WIP, check back later for more documentation on it. + +.. _install the module : http://discordjs.readthedocs.org/en/latest/get_started.html#installation \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index adb6ebfd9..af0d5dcf0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,8 @@ Contents: .. toctree:: get_started + troubleshooting + create_simple_bot From fc9c46d1a201016baf95f7587843299d07222441 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 13:45:22 +0100 Subject: [PATCH 122/191] updated docs --- docs/docs_client.rst | 33 +++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 34 insertions(+) create mode 100644 docs/docs_client.rst diff --git a/docs/docs_client.rst b/docs/docs_client.rst new file mode 100644 index 000000000..69d9bcda2 --- /dev/null +++ b/docs/docs_client.rst @@ -0,0 +1,33 @@ +Client Documentation +==================== + +Attributes +---------- + +``options`` +~~~~~~~~~~~ +An `Object` containing a configuration for the Client. Currently can only be configured like so: + +.. code-block:: js + + { + queue : false // whether messages should be sent one after the other or + // just send straight away. + } + +``token`` +~~~~~~~~~ +A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. + +``state`` +~~~~~~~~~ +An `Integer` representing what state of connection the Client is in. + +- **0** is idle, meaning the Client has been created but no login attempts have been made. +- **1** is logging in, meaning the Client is in the process of logging in. +- **2** is logged in, meaning the Client is logged in but not necessarily ready. +- **3** is ready, meaning the Client is ready to begin listening. +- **4** is disconnected, meaning the Client was disconnected due to any reason. + +Functions +--------- \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index af0d5dcf0..70b5f1698 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,6 +17,7 @@ Contents: get_started troubleshooting create_simple_bot + docs_client From 3e9af4454d6271dce77afc350af999487b4da25e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 13:47:42 +0100 Subject: [PATCH 123/191] Update to docs --- docs/docs_client.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 69d9bcda2..382528cf9 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -4,8 +4,8 @@ Client Documentation Attributes ---------- -``options`` -~~~~~~~~~~~ +options +~~~~~~~ An `Object` containing a configuration for the Client. Currently can only be configured like so: .. code-block:: js @@ -15,12 +15,12 @@ An `Object` containing a configuration for the Client. Currently can only be con // just send straight away. } -``token`` -~~~~~~~~~ +token +~~~~~ A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. -``state`` -~~~~~~~~~ +state +~~~~~ An `Integer` representing what state of connection the Client is in. - **0** is idle, meaning the Client has been created but no login attempts have been made. From 1ef4fa41a77f33af882baa140b2e6084d2f4a233 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:28:09 +0100 Subject: [PATCH 124/191] Channels now store 1000 messages maximum Will drastically improve the longevity of the process and reduce memory required --- src/channel.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/channel.js b/src/channel.js index d813e9b74..91e961547 100644 --- a/src/channel.js +++ b/src/channel.js @@ -18,9 +18,15 @@ class Channel { } addMessage(data){ + + if(this.messages.length > 1000){ + this.messages.splice(0,1); + } + if(!this.getMessage("id", data.id)){ this.messages.push(data); } + return this.getMessage("id", data.id); } From 2f9585a6b9ccd30e7bfe19b009b9a2e95d56a4c2 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:41:23 +0100 Subject: [PATCH 125/191] Added semi-functional statuses --- lib/Client.js | 158 ++++++++++++++++++++++++++++--------------------- lib/channel.js | 6 ++ lib/user.js | 1 + src/Client.js | 5 ++ src/user.js | 1 + 5 files changed, 105 insertions(+), 66 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index eff03e5aa..b80665556 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1144,6 +1144,7 @@ var Client = (function () { key: "addServer", value: function addServer(data) { + var self = this; var server = this.getServer("id", data.id); if (!server) { @@ -1177,24 +1178,15 @@ var Client = (function () { } } - return server; - } - - //def getUser - }, { - key: "getUser", - value: function getUser(key, value) { var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { - for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { - var user = _step9.value; + for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var presence = _step9.value; - if (user[key] === value) { - return user; - } + self.getUser("id", presence.user.id).status = presence.status; } } catch (err) { _didIteratorError9 = true; @@ -1211,23 +1203,23 @@ var Client = (function () { } } - return null; + return server; } - //def getChannel + //def getUser }, { - key: "getChannel", - value: function getChannel(key, value) { + key: "getUser", + value: function getUser(key, value) { var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { - for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { - var channel = _step10.value; + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; - if (channel[key] === value) { - return channel; + if (user[key] === value) { + return user; } } } catch (err) { @@ -1245,17 +1237,19 @@ var Client = (function () { } } - return this.getPMChannel(key, value); //might be a PM + return null; } + + //def getChannel }, { - key: "getPMChannel", - value: function getPMChannel(key, value) { + key: "getChannel", + value: function getChannel(key, value) { var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { - for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var channel = _step11.value; if (channel[key] === value) { @@ -1277,23 +1271,21 @@ var Client = (function () { } } - return null; + return this.getPMChannel(key, value); //might be a PM } - - //def getServer }, { - key: "getServer", - value: function getServer(key, value) { + key: "getPMChannel", + value: function getPMChannel(key, value) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { - for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { - var server = _step12.value; + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; - if (server[key] === value) { - return server; + if (channel[key] === value) { + return channel; } } } catch (err) { @@ -1314,6 +1306,40 @@ var Client = (function () { return null; } + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + //def trySendConnData }, { key: "trySendConnData", @@ -1366,13 +1392,13 @@ var Client = (function () { } else if (destination instanceof User) { //check if we have a PM - var _iteratorNormalCompletion13 = true; - var _didIteratorError13 = false; - var _iteratorError13 = undefined; + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; try { - for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { - var pmc = _step13.value; + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; if (pmc.user.equals(destination)) { resolve(pmc.id); @@ -1382,16 +1408,16 @@ var Client = (function () { //we don't, at this point we're late } catch (err) { - _didIteratorError13 = true; - _iteratorError13 = err; + _didIteratorError14 = true; + _iteratorError14 = err; } finally { try { - if (!_iteratorNormalCompletion13 && _iterator13["return"]) { - _iterator13["return"](); + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); } } finally { - if (_didIteratorError13) { - throw _iteratorError13; + if (_didIteratorError14) { + throw _iteratorError14; } } } @@ -1428,27 +1454,27 @@ var Client = (function () { data.mentions = data.mentions || []; //for some reason this was not defined at some point? - var _iteratorNormalCompletion14 = true; - var _didIteratorError14 = false; - var _iteratorError14 = undefined; + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; try { - for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { - var mention = _step14.value; + for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var mention = _step15.value; mentions.push(self.addUser(mention)); } } catch (err) { - _didIteratorError14 = true; - _iteratorError14 = err; + _didIteratorError15 = true; + _iteratorError15 = err; } finally { try { - if (!_iteratorNormalCompletion14 && _iterator14["return"]) { - _iterator14["return"](); + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); } } finally { - if (_didIteratorError14) { - throw _iteratorError14; + if (_didIteratorError15) { + throw _iteratorError15; } } } @@ -1650,27 +1676,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion15 = true; - var _didIteratorError15 = false; - var _iteratorError15 = undefined; + var _iteratorNormalCompletion16 = true; + var _didIteratorError16 = false; + var _iteratorError16 = undefined; try { - for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { - var channel = _step15.value; + for (var _iterator16 = this.channelCache[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { + var channel = _step16.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError15 = true; - _iteratorError15 = err; + _didIteratorError16 = true; + _iteratorError16 = err; } finally { try { - if (!_iteratorNormalCompletion15 && _iterator15["return"]) { - _iterator15["return"](); + if (!_iteratorNormalCompletion16 && _iterator16["return"]) { + _iterator16["return"](); } } finally { - if (_didIteratorError15) { - throw _iteratorError15; + if (_didIteratorError16) { + throw _iteratorError16; } } } diff --git a/lib/channel.js b/lib/channel.js index 79bc71b55..8e9ca5703 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -24,9 +24,15 @@ var Channel = (function () { }, { key: "addMessage", value: function addMessage(data) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + if (!this.getMessage("id", data.id)) { this.messages.push(data); } + return this.getMessage("id", data.id); } }, { diff --git a/lib/user.js b/lib/user.js index 2f363dd1e..5e38e132e 100644 --- a/lib/user.js +++ b/lib/user.js @@ -12,6 +12,7 @@ var User = (function () { this.discriminator = data.discriminator; this.id = data.id; this.avatar = data.avatar; + this.status = "offline"; } // access using user.avatarURL; diff --git a/src/Client.js b/src/Client.js index f7919a653..09a3f004c 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1044,6 +1044,7 @@ class Client { //def addServer addServer(data) { + var self = this; var server = this.getServer("id", data.id); if (!server) { @@ -1055,6 +1056,10 @@ class Client { } } } + + for(var presence of data.presences){ + self.getUser("id", presence.user.id).status = presence.status; + } return server; } diff --git a/src/user.js b/src/user.js index 375ec7c60..73eef604f 100644 --- a/src/user.js +++ b/src/user.js @@ -4,6 +4,7 @@ class User{ this.discriminator = data.discriminator; this.id = data.id; this.avatar = data.avatar; + this.status = "offline"; } // access using user.avatarURL; From ca1b4bdf0eb6705a620da2e01d47cfd2c6715718 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:43:49 +0100 Subject: [PATCH 126/191] Added shortcut to users from channel class --- lib/channel.js | 10 ++++++++++ src/channel.js | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/channel.js b/lib/channel.js index 8e9ca5703..17390e9e6 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -82,6 +82,16 @@ var Channel = (function () { get: function get() { return false; } + }, { + key: "users", + get: function get() { + return this.server.members; + } + }, { + key: "members", + get: function get() { + return this.server.members; + } }]); return Channel; diff --git a/src/channel.js b/src/channel.js index 91e961547..df266ba1c 100644 --- a/src/channel.js +++ b/src/channel.js @@ -46,6 +46,14 @@ class Channel { get isPrivate(){ return false; } + + get users(){ + return this.server.members; + } + + get members(){ + return this.server.members; + } } module.exports = Channel; \ No newline at end of file From 76e9cef7e1c213d83928e72dc9a1a010094ea9dd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:45:13 +0100 Subject: [PATCH 127/191] Added user presence tracking changes User status in cache is now updated as well as firing the event --- lib/Client.js | 1 + src/Client.js | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index b80665556..7d7bba771 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1087,6 +1087,7 @@ var Client = (function () { var presenceUser = new User(data.user); if (presenceUser.equalsStrict(userInCache)) { //they're exactly the same, an actual presence update + userInCache.status = data.status; self.trigger("presence", { user: userInCache, status: data.status, diff --git a/src/Client.js b/src/Client.js index 09a3f004c..5b5bc872f 100644 --- a/src/Client.js +++ b/src/Client.js @@ -992,6 +992,7 @@ class Client { var presenceUser = new User(data.user); if (presenceUser.equalsStrict(userInCache)) { //they're exactly the same, an actual presence update + userInCache.status = data.status; self.trigger("presence", { user: userInCache, status: data.status, From 4f928301ba164737c2537fa68e55bc17b63b393d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:45:51 +0100 Subject: [PATCH 128/191] Updated bot --- test/bot.1.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/bot.1.js b/test/bot.1.js index 38f25d390..ed608f092 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,13 +1,12 @@ var Discord = require("../"); -var mybot = new Discord.Client({ - queue: true -}); +var mybot = new Discord.Client(); var fs = require("fs"); var server, channel, message, sentMessage = false; mybot.on("message", function (message) { - + + console.log("Everyone mentioned? " + message.everyoneMentioned); if (mybot.user.equals(message.sender)) { return; } @@ -17,7 +16,14 @@ mybot.on("message", function (message) { } // we can go ahead :) - mybot.reply(message, message.channel); + + var onlineUsers = 0; + for(user of message.channel.users){ + if(user.status === "online" || user.status === "idle") + onlineUsers++; + } + + mybot.reply(message, onlineUsers); }); mybot.on("ready", function () { From ad60af6185bacf03cb80c5f248e45fe14bc359c8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:45:56 +0100 Subject: [PATCH 129/191] 3.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89ca0fba0..b9a82de25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.3.4", + "version": "3.4.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 8943a2fffcb4739fc8cc24ddba7b7d476c7a365f Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:47:02 +0100 Subject: [PATCH 130/191] Added 3.4.0 web dist --- web-dist/discord.3.4.0.js | 3641 +++++++++++++++++++++++++++++++++ web-dist/discord.min.3.4.0.js | 2 + 2 files changed, 3643 insertions(+) create mode 100644 web-dist/discord.3.4.0.js create mode 100644 web-dist/discord.min.3.4.0.js diff --git a/web-dist/discord.3.4.0.js b/web-dist/discord.3.4.0.js new file mode 100644 index 000000000..1cbe30419 --- /dev/null +++ b/web-dist/discord.3.4.0.js @@ -0,0 +1,3641 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + + return prom; + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener[data.id]) { + var cbs = self.serverCreateListener[data.id]; + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener[data.id] = null; + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user, server); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user, server); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + userInCache.status = data.status; + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var self = this; + var server = this.getServer("id", data.id); + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + } + } + + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var presence = _step9.value; + + self.getUser("id", presence.user.id).status = presence.status; + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 2, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; + + if (pmc.user.equals(destination)) { + resolve(pmc.id); + return; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + self.startPM(destination).then(function (pmc) { + console.log(pmc); + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var mention = _step15.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } + }, { + key: "getGateway", + value: function getGateway() { + var self = this; + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion16 = true; + var _didIteratorError16 = false; + var _iteratorError16 = undefined; + + try { + for (var _iterator16 = this.channelCache[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { + var channel = _step16.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError16 = true; + _iteratorError16 = err; + } finally { + try { + if (!_iteratorNormalCompletion16 && _iterator16["return"]) { + _iterator16["return"](); + } + } finally { + if (_didIteratorError16) { + throw _iteratorError16; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +module.exports = Client; +},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "isPrivate", + get: function get() { + return true; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object && object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "<#" + this.id + ">"; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }, { + key: "isPrivate", + get: function get() { + return false; + } + }, { + key: "users", + get: function get() { + return this.server.members; + } + }, { + key: "members", + get: function get() { + return this.server.members; + } + }]); + + return Channel; +})(); + +module.exports = Channel; +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; +},{}],7:[function(require,module,exports){ +"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 PMChannel = require("./PMChannel.js"); + +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } + }]); + + return Message; +})(); + +module.exports = Message; +},{"./PMChannel.js":3}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }, { + key: "users", + get: function get() { + return this.members; + } + }]); + + return Server; +})(); + +module.exports = Server; +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + this.status = "offline"; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.3.4.0.js b/web-dist/discord.min.3.4.0.js new file mode 100644 index 000000000..9028bea6a --- /dev/null +++ b/web-dist/discord.min.3.4.0.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new n(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,i=void 0;try{for(var k,l=d.guilds[Symbol.iterator]();!(f=(k=l.next()).done);f=!0)var m=k.value,n=b.addServer(m)}catch(e){h=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(h)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new j(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new j(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener[d.id]){var N=b.serverCreateListener[d.id];N[0](n),N[1](null,n),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new g(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new g(d.user);T.equalsStrict(S)?(S.status=d.status,b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof g){var f=!0,k=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return void d(o.id)}}catch(p){k=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(k)throw l}}c.startPM(a).then(function(a){console.log(a),d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){m.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){m.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){m.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){m.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){m.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=q},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a, +this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)}); \ No newline at end of file From 7f5050f9798c516f5d0e24d5e334da569dad97b4 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:53:23 +0100 Subject: [PATCH 131/191] Began to work on status setting --- lib/Client.js | 13 +++++++++++++ src/Client.js | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index 7d7bba771..a0629dced 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1641,6 +1641,19 @@ var Client = (function () { }); }); } + }, { + key: "setStatusIdle", + value: function setStatusIdle() { + this.setStatus("idle"); + } + }, { + key: "setStatusOnline", + value: function setStatusOnline() { + this.setStatus("online"); + } + }, { + key: "setStatus", + value: function setStatus() {} }, { key: "uptime", get: function get() { diff --git a/src/Client.js b/src/Client.js index 5b5bc872f..e06d5525d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1382,6 +1382,18 @@ class Client { }); }); } + + setStatusIdle(){ + this.setStatus("idle"); + } + + setStatusOnline(){ + this.setStatus("online"); + } + + setStatus(){ + + } } module.exports = Client; \ No newline at end of file From 3094c223ec90588ef3deefeef18fed4007322ea0 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 21:59:27 +0100 Subject: [PATCH 132/191] Added status setting You can now run bot.setStatusIdle() or bot.setStatusOnline() (or any aliases) to manually set the status of the bot. --- lib/Client.js | 28 +++++++++++++++++++++++++++- src/Client.js | 23 ++++++++++++++++++++++- test/bot.1.js | 10 ++++++---- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index a0629dced..035d49f07 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1651,9 +1651,35 @@ var Client = (function () { value: function setStatusOnline() { this.setStatus("online"); } + }, { + key: "setStatusActive", + value: function setStatusActive() { + this.setStatusOnline(); + } + }, { + key: "setStatusHere", + value: function setStatusHere() { + this.setStatusOnline(); + } + }, { + key: "setStatusAway", + value: function setStatusAway() { + this.setStatusIdle(); + } }, { key: "setStatus", - value: function setStatus() {} + value: function setStatus(stat) { + + var idleTime = stat === "online" ? null : Date.now(); + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: idleTime, + game_id: null + } + })); + } }, { key: "uptime", get: function get() { diff --git a/src/Client.js b/src/Client.js index e06d5525d..927c79bfa 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1391,8 +1391,29 @@ class Client { this.setStatus("online"); } - setStatus(){ + setStatusActive(){ + this.setStatusOnline(); + } + + setStatusHere(){ + this.setStatusOnline(); + } + + setStatusAway(){ + this.setStatusIdle(); + } + + setStatus(stat){ + var idleTime = (stat === "online" ? null : Date.now()); + + this.websocket.send(JSON.stringify({ + op : 3, + d : { + idle_since : idleTime, + game_id : null + } + })); } } diff --git a/test/bot.1.js b/test/bot.1.js index ed608f092..131ac7322 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -18,12 +18,14 @@ mybot.on("message", function (message) { // we can go ahead :) var onlineUsers = 0; - for(user of message.channel.users){ - if(user.status === "online" || user.status === "idle") - onlineUsers++; - } + + mybot.setStatusIdle(); mybot.reply(message, onlineUsers); + + setTimeout(function(){ + mybot.setStatusOnline(); + },5000); }); mybot.on("ready", function () { From 5fa7bace1089b983725438b60752ef99923b88d4 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 26 Sep 2015 22:41:33 +0100 Subject: [PATCH 133/191] Added startTyping and stopTyping --- lib/Client.js | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/Client.js | 47 +++++++++++++++++++++++++++++++++++++++++++++-- test/bot.1.js | 10 +++++----- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 035d49f07..29b5bb38f 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -43,7 +43,7 @@ var Client = (function () { this.user = null; this.alreadySentData = false; this.serverCreateListener = {}; - + this.typingIntervals = {}; this.email = "abc"; this.password = "abc"; @@ -1354,7 +1354,7 @@ var Client = (function () { op: 2, d: { token: this.token, - v: 2, + v: 3, properties: { "$os": "discord.js", "$browser": "discord.js", @@ -1666,6 +1666,47 @@ var Client = (function () { value: function setStatusAway() { this.setStatusIdle(); } + }, { + key: "startTyping", + value: function startTyping(chann) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (self.typingIntervals[channel]) { + return; + } + + var fn = function fn() { + console.log(Endpoints.CHANNELS + "/" + channel + "/typing"); + request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end(); + }; + + fn(); + + var interval = setInterval(fn, 3000); + + self.typingIntervals[channel] = interval; + } + } + }, { + key: "stopTyping", + value: function stopTyping(chann) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (!self.typingIntervals[channel]) { + return; + } + + clearInterval(self.typingIntervals[channel]); + + delete self.typingIntervals[channel]; + } + } }, { key: "setStatus", value: function setStatus(stat) { diff --git a/src/Client.js b/src/Client.js index 927c79bfa..f0a0aba1f 100644 --- a/src/Client.js +++ b/src/Client.js @@ -33,7 +33,7 @@ class Client { this.user = null; this.alreadySentData = false; this.serverCreateListener = {}; - + this.typingIntervals = {}; this.email = "abc"; this.password = "abc"; @@ -1115,7 +1115,7 @@ class Client { op: 2, d: { token: this.token, - v: 2, + v: 3, properties: { "$os": "discord.js", "$browser": "discord.js", @@ -1403,6 +1403,49 @@ class Client { this.setStatusIdle(); } + startTyping(chann){ + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel){ + if(self.typingIntervals[channel]){ + return; + } + + var fn = function(){ + console.log(`${Endpoints.CHANNELS}/${channel}/typing`); + request + .post(`${Endpoints.CHANNELS}/${channel}/typing`) + .set("authorization", self.token) + .end(); + }; + + fn(); + + var interval = setInterval(fn, 3000); + + self.typingIntervals[channel] = interval; + } + } + + stopTyping(chann){ + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel){ + if(!self.typingIntervals[channel]){ + return; + } + + clearInterval(self.typingIntervals[channel]); + + delete self.typingIntervals[channel]; + + } + } + setStatus(stat){ var idleTime = (stat === "online" ? null : Date.now()); diff --git a/test/bot.1.js b/test/bot.1.js index 131ac7322..464caec86 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -19,13 +19,13 @@ mybot.on("message", function (message) { var onlineUsers = 0; - mybot.setStatusIdle(); - - mybot.reply(message, onlineUsers); + mybot.startTyping(message.channel); setTimeout(function(){ - mybot.setStatusOnline(); - },5000); + mybot.reply(message, "stopping now k"); + mybot.stopTyping(message.channel); + }, 6000); + }); mybot.on("ready", function () { From 223753408c210ec8dce19018dbc474d560bc43e7 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:05:17 +0100 Subject: [PATCH 134/191] Added support for server unavailability it happened just now RIP discord server Date: Sun, 27 Sep 2015 17:05:31 +0100 Subject: [PATCH 135/191] 3.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b9a82de25..9d7b3fc10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.4.0", + "version": "3.4.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From bef49850640d704cc5327f5b9aa4c5122b077d9b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:06:16 +0100 Subject: [PATCH 136/191] Removed debug info whoops --- lib/Client.js | 2 -- src/Client.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index c6cbb5903..a885c6c28 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1430,7 +1430,6 @@ var Client = (function () { } self.startPM(destination).then(function (pmc) { - console.log(pmc); resolve(pmc.id); })["catch"](reject); } else { @@ -1685,7 +1684,6 @@ var Client = (function () { } var fn = function fn() { - console.log(Endpoints.CHANNELS + "/" + channel + "/typing"); request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end(); }; diff --git a/src/Client.js b/src/Client.js index 58ad78c49..f6b8859d1 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1168,7 +1168,6 @@ class Client { //we don't, at this point we're late self.startPM(destination).then(function (pmc) { - console.log(pmc); resolve(pmc.id); }).catch(reject); @@ -1420,7 +1419,6 @@ class Client { } var fn = function(){ - console.log(`${Endpoints.CHANNELS}/${channel}/typing`); request .post(`${Endpoints.CHANNELS}/${channel}/typing`) .set("authorization", self.token) From 007977588698d3d7f2bb141de3f9d4346d3c39d6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:06:27 +0100 Subject: [PATCH 137/191] 3.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d7b3fc10..861d7fc72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.4.1", + "version": "3.4.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 5819fb4dafdf9343bfe2c1b2607a1591306446a6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:17:03 +0100 Subject: [PATCH 138/191] Fixed unavailable message --- lib/Client.js | 4 +++- src/Client.js | 4 +++- test/bot.1.js | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index a885c6c28..ecacab82a 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -778,6 +778,8 @@ var Client = (function () { return; } + self.trigger("raw", dat); + //valid message switch (dat.t) { @@ -1150,7 +1152,7 @@ var Client = (function () { if (data.unavailable) { self.trigger("unavailable", data); - self.debug("Server ID" + +" has been marked unavailable by Discord. It was not cached."); + self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached."); return; } diff --git a/src/Client.js b/src/Client.js index f6b8859d1..483f9ec3d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -760,6 +760,8 @@ class Client { return; } + self.trigger("raw", dat); + //valid message switch (dat.t) { @@ -1050,7 +1052,7 @@ class Client { if(data.unavailable){ self.trigger("unavailable", data); - self.debug("Server ID" + + " has been marked unavailable by Discord. It was not cached."); + self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached."); return; } diff --git a/test/bot.1.js b/test/bot.1.js index a79a36505..b615255c1 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -36,7 +36,7 @@ mybot.on("debug", function(info){ console.log(info); }) -mybot.on("unavailable", function(info){ +mybot.on("unknown", function(info){ console.log("warning!", info); }) From 5559809aff6943715b774302cab09c3116e04576 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:18:09 +0100 Subject: [PATCH 139/191] Added channel.topic --- lib/channel.js | 1 + src/channel.js | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/channel.js b/lib/channel.js index 17390e9e6..bb67fcf4f 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -11,6 +11,7 @@ var Channel = (function () { this.server = server; this.name = data.name; this.type = data.type; + this.topic = data.topic; this.id = data.id; this.messages = []; //this.isPrivate = isPrivate; //not sure about the implementation of this... diff --git a/src/channel.js b/src/channel.js index df266ba1c..a7185e17f 100644 --- a/src/channel.js +++ b/src/channel.js @@ -4,6 +4,7 @@ class Channel { this.server = server; this.name = data.name; this.type = data.type; + this.topic = data.topic; this.id = data.id; this.messages = []; //this.isPrivate = isPrivate; //not sure about the implementation of this... From 16d24104502cfbc7e4cd6a003306d9c7de90d4f2 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:37:46 +0100 Subject: [PATCH 140/191] Added setting of channel topics --- lib/Client.js | 38 +++++++++++++++++++++++++++++++++++++- src/Client.js | 42 ++++++++++++++++++++++++++++++++++++++++++ test/bot.1.js | 4 ++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/lib/Client.js b/lib/Client.js index ecacab82a..32025062d 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1141,6 +1141,42 @@ var Client = (function () { } return this.getPMChannel("id", data.id); } + }, { + key: "setTopic", + value: function setTopic(channel, topic) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + self.resolveDestination(channel).then(next)["catch"](error); + + function error(e) { + callback(e); + reject(e); + } + + function next(destination) { + + var asChan = self.getChannel("id", destination); + + request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({ + name: asChan.name, + position: 0, + topic: topic + }).end(function (err, res) { + if (err) { + error(err); + } else { + asChan.topic = res.body.topic; + resolve(); + callback(); + } + }); + } + }); + } //def addServer }, { @@ -1437,7 +1473,7 @@ var Client = (function () { } else { channId = destination; } - if (channId) resolve(channId); + if (channId) resolve(channId);else reject(); }); } }, { diff --git a/src/Client.js b/src/Client.js index 483f9ec3d..08a0ecbde 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1044,6 +1044,46 @@ class Client { return this.getPMChannel("id", data.id); } + setTopic(channel, topic, callback = function(err){}){ + + var self = this; + + return new Promise(function(resolve, reject){ + + self.resolveDestination(channel).then(next).catch(error); + + function error(e){ + callback(e); + reject(e); + } + + function next(destination){ + + var asChan = self.getChannel("id", destination); + + request + .patch(`${Endpoints.CHANNELS}/${destination}`) + .set("authorization", self.token) + .send({ + name : asChan.name, + position : 0, + topic : topic + }) + .end(function(err, res){ + if(err){ + error(err); + }else{ + asChan.topic = res.body.topic; + resolve(); + callback(); + } + }); + } + + }); + + } + //def addServer addServer(data) { @@ -1178,6 +1218,8 @@ class Client { } if (channId) resolve(channId); + else + reject(); }); } diff --git a/test/bot.1.js b/test/bot.1.js index b615255c1..1e425423f 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -30,6 +30,10 @@ mybot.on("message", function (message) { mybot.on("ready", function () { console.log("im ready"); + + for(var chann of mybot.channels){ + mybot.setTopic(chann, "HELLO I AM A BOT BOOP BOOP"); + } }); mybot.on("debug", function(info){ From c32f600a6aba46731bc5110306c9995961e453f2 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 17:54:03 +0100 Subject: [PATCH 141/191] Added channelUpdate listener --- lib/Client.js | 17 +++++++++++++++++ src/Client.js | 17 +++++++++++++++++ test/bot.1.js | 8 +++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/Client.js b/lib/Client.js index 32025062d..54ed14d17 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1105,6 +1105,23 @@ var Client = (function () { break; + case "CHANNEL_UPDATE": + + var channelInCache = self.getChannel("id", data.id), + serverInCache = self.getServer("id", data.guild_id); + + if (channelInCache && serverInCache) { + + var newChann = new Channel(data, serverInCache); + newChann.messages = channelInCache.messages; + + self.trigger("channelUpdate", channelInCache, newChann); + + self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann; + } + + break; + default: self.debug("received unknown packet"); self.trigger("unknown", dat); diff --git a/src/Client.js b/src/Client.js index 08a0ecbde..67b36bd7d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1009,6 +1009,23 @@ class Client { } break; + + case "CHANNEL_UPDATE": + + var channelInCache = self.getChannel("id", data.id), + serverInCache = self.getServer("id", data.guild_id); + + if(channelInCache && serverInCache){ + + var newChann = new Channel(data, serverInCache); + newChann.messages = channelInCache.messages; + + self.trigger("channelUpdate", channelInCache, newChann); + + self.channelCache[ self.channelCache.indexOf(channelInCache) ] = newChann; + } + + break; default: self.debug("received unknown packet"); diff --git a/test/bot.1.js b/test/bot.1.js index 1e425423f..03c507889 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -32,7 +32,7 @@ mybot.on("ready", function () { console.log("im ready"); for(var chann of mybot.channels){ - mybot.setTopic(chann, "HELLO I AM A BOT BOOP BOOP"); + mybot.setTopic(chann, "THINGS"); } }); @@ -44,6 +44,12 @@ mybot.on("unknown", function(info){ console.log("warning!", info); }) +mybot.on("channelUpdate", function(oldChan, newChan){ + + console.log(oldChan.topic + " vs " + newChan.topic); + +}); + function dump(msg) { console.log(msg); } From a70d6f9b32e91350d857a5464917e739c9b2ae4c Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 18:03:43 +0100 Subject: [PATCH 142/191] added parameter for optional stopTypeTime in startTyping --- lib/Client.js | 8 +++++++- src/Client.js | 8 +++++++- test/bot.1.js | 7 +------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 54ed14d17..d3d6f1f78 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1728,7 +1728,7 @@ var Client = (function () { } }, { key: "startTyping", - value: function startTyping(chann) { + value: function startTyping(chann, stopTypeTime) { var self = this; this.resolveDestination(chann).then(next); @@ -1747,6 +1747,12 @@ var Client = (function () { var interval = setInterval(fn, 3000); self.typingIntervals[channel] = interval; + + if (stopTypeTime) { + setTimeout(function () { + self.stopTyping(channel); + }, stopTypeTime); + } } } }, { diff --git a/src/Client.js b/src/Client.js index 67b36bd7d..ef51e2c42 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1469,7 +1469,7 @@ class Client { this.setStatusIdle(); } - startTyping(chann){ + startTyping(chann, stopTypeTime){ var self = this; this.resolveDestination(chann).then(next); @@ -1491,6 +1491,12 @@ class Client { var interval = setInterval(fn, 3000); self.typingIntervals[channel] = interval; + + if(stopTypeTime){ + setTimeout(function(){ + self.stopTyping(channel); + }, stopTypeTime); + } } } diff --git a/test/bot.1.js b/test/bot.1.js index 03c507889..4eb5ab07f 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -19,12 +19,7 @@ mybot.on("message", function (message) { var onlineUsers = 0; - mybot.startTyping(message.channel); - - setTimeout(function(){ - mybot.reply(message, "stopping now k"); - mybot.stopTyping(message.channel); - }, 6000); + mybot.startTyping(message.channel, 6000); }); From f4a7b2b07c5d439e08e1a292fce56486c098d2ff Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 18:16:14 +0100 Subject: [PATCH 143/191] 3.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 861d7fc72..d2500be5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.4.2", + "version": "3.5.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From ffa415afdfced83a09a8e378f4049c165dcc4177 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 19:11:58 +0100 Subject: [PATCH 144/191] Updated doc index --- docs/index.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 70b5f1698..d9c10260b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,10 +13,20 @@ run in node.js / io.js and in the browser. Contents: +.. _general-docs: + .. toctree:: + :caption: General + get_started troubleshooting create_simple_bot + +.. _docs: + +.. toctree:: + :caption: Documentation + docs_client From d581bf4d630b209a7cd7a781be5cc27b324a321c Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 19:19:15 +0100 Subject: [PATCH 145/191] Updated, testing something --- docs/docs_client.rst | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 382528cf9..50ed4ef34 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -1,6 +1,8 @@ Client Documentation ==================== +This page contains documentation on the `Discord.Client` class. This should be used when you want to start creating things with the API. + Attributes ---------- @@ -17,7 +19,11 @@ An `Object` containing a configuration for the Client. Currently can only be con token ~~~~~ -A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. +A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. Example token: + +.. code-block:: js + + ODAzTOc4MTA2BjQ2MjY4ODg.COmrCA.fEtD_Tc0JU6iZJU_11coEWBOQHE state ~~~~~ @@ -29,5 +35,17 @@ An `Integer` representing what state of connection the Client is in. - **3** is ready, meaning the Client is ready to begin listening. - **4** is disconnected, meaning the Client was disconnected due to any reason. +.. code-block:: js + + if( bot.state === 3 ) // ready to go + +user +~~~~ +A `User`_ object representing the user of the signed in client. + + + Functions ---------- \ No newline at end of file +--------- + +.. _User : #user \ No newline at end of file From 626f7eab6be22043c156dc644c6c670498da81fa Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 19:35:55 +0100 Subject: [PATCH 146/191] Finalised attributes on docs --- docs/docs_client.rst | 60 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 50ed4ef34..b6a5ec28e 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -35,17 +35,73 @@ An `Integer` representing what state of connection the Client is in. - **3** is ready, meaning the Client is ready to begin listening. - **4** is disconnected, meaning the Client was disconnected due to any reason. +See also ready_. + .. code-block:: js if( bot.state === 3 ) // ready to go user ~~~~ -A `User`_ object representing the user of the signed in client. +A `User`_ object representing the account of the signed in client. This will only be available when the client is in the ready state (3). +.. code-block:: js + bot.user.username; // username of the account logged in + +email +~~~~~ +A `String` that is the email used to sign the client in. + +password +~~~~~~~~ +A `String` that is the password used to sign the client in. + +readyTime +~~~~~~~~~ +A `Number` representing the unix timestamp from when the client was ready. `Null` if not yet ready. + +.. code-block:: js + + bot.readyTime; // 1443378242464 + +uptime +~~~~~~ +A `Number` representing how many milliseconds have passed since the client was ready. `Null` if not yet ready. + +.. code-block:: js + + if( bot.uptime > 5000 ) // true if the client has been up for more than 5 seconds + +ready +~~~~~ +A `Boolean` that is true if the client is ready. A shortcut to checking if ``bot.state === 3``. + +servers +~~~~~~~ +An `Array` of Server_ objects that the client has access to. Represents the servers the client is in. + +channels +~~~~~~~~ +An `Array` of Channel_ objects that the client has access to. Represents the channels the client can access. + +users +~~~~~ +An `Array` of User_ objects that the client has access to. + +PMChannels +~~~~~~~~~~ +An `Array` of PMChannel_ objects the client has access to. + +messages +~~~~~~~~ +An `Array` of Message_ objects the client has received over its uptime. Functions --------- -.. _User : #user \ No newline at end of file +.. _User : #user +.. _ready : #ready +.. _Server : #server +.. _Channel : #channel +.. _Message : #message \ No newline at end of file From d27638b421e513aa285ed35db5496f8c13e080f5 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 19:48:45 +0100 Subject: [PATCH 147/191] docs --- docs/docs_client.rst | 14 +++++--------- docs/docs_resolvable.rst | 9 +++++++++ docs/vars.rst | 5 +++++ 3 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 docs/docs_resolvable.rst create mode 100644 docs/vars.rst diff --git a/docs/docs_client.rst b/docs/docs_client.rst index b6a5ec28e..35c929cb7 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -1,3 +1,5 @@ +.. include:: ./vars.rst + Client Documentation ==================== @@ -79,11 +81,11 @@ A `Boolean` that is true if the client is ready. A shortcut to checking if ``bot servers ~~~~~~~ -An `Array` of Server_ objects that the client has access to. Represents the servers the client is in. +An `Array` of Server_ objects that the client has access to. channels ~~~~~~~~ -An `Array` of Channel_ objects that the client has access to. Represents the channels the client can access. +An `Array` of Channel_ objects that the client has access to. users ~~~~~ @@ -98,10 +100,4 @@ messages An `Array` of Message_ objects the client has received over its uptime. Functions ---------- - -.. _User : #user -.. _ready : #ready -.. _Server : #server -.. _Channel : #channel -.. _Message : #message \ No newline at end of file +--------- \ No newline at end of file diff --git a/docs/docs_resolvable.rst b/docs/docs_resolvable.rst new file mode 100644 index 000000000..cb6e14e71 --- /dev/null +++ b/docs/docs_resolvable.rst @@ -0,0 +1,9 @@ +Resolvable Documentation +======================== + +To be robust, discord.js needs to handle a wide amount of ambiguous data that is supplied to it. This means you can use functions much more easily. Anything that is resolvable means it can be normalised without you having to do it explicitly. + +Channel Resolvable +------------------ + +A Channel Resolvable is data that can be resolved to a channel ID. Here is what is currently supported: \ No newline at end of file diff --git a/docs/vars.rst b/docs/vars.rst new file mode 100644 index 000000000..f99759fb4 --- /dev/null +++ b/docs/vars.rst @@ -0,0 +1,5 @@ +.. _User : #user +.. _ready : #ready +.. _Server : #server +.. _Channel : #channel +.. _Message : #message \ No newline at end of file From 2f52ca50bf86e1c4f0f55147e7af9c85645fef44 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:02:41 +0100 Subject: [PATCH 148/191] MORE DOCUMENTATION KANYE BELIEVE IT --- docs/docs_resolvable.rst | 12 +++++++++++- docs/index.rst | 3 +++ docs/vars.rst | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/docs_resolvable.rst b/docs/docs_resolvable.rst index cb6e14e71..6fcbc2903 100644 --- a/docs/docs_resolvable.rst +++ b/docs/docs_resolvable.rst @@ -1,3 +1,5 @@ +.. include:: ./vars.rst + Resolvable Documentation ======================== @@ -6,4 +8,12 @@ To be robust, discord.js needs to handle a wide amount of ambiguous data that is Channel Resolvable ------------------ -A Channel Resolvable is data that can be resolved to a channel ID. Here is what is currently supported: \ No newline at end of file +A Channel Resolvable is data that can be resolved to a channel ID. Here is what is currently supported: + +- A Channel_ object +- A Server_ object (the #general channel of the server will be used) +- A String_ representing the channel ID +- A Message_ (the channel the message was sent in will be used) +- A User_ (will get the PM channel with the specified user) + +.. note:: A User cannot always be specified in certain cases. For example, if using `bot.setTopic`, a User or PM Channel can't be specified as these do not support channel topics. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index d9c10260b..c0e0451a6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -16,6 +16,7 @@ Contents: .. _general-docs: .. toctree:: + :maxdepth: 2 :caption: General get_started @@ -25,9 +26,11 @@ Contents: .. _docs: .. toctree:: + :maxdepth: 2 :caption: Documentation docs_client + docs_resolvable diff --git a/docs/vars.rst b/docs/vars.rst index f99759fb4..2a45df682 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -2,4 +2,5 @@ .. _ready : #ready .. _Server : #server .. _Channel : #channel -.. _Message : #message \ No newline at end of file +.. _Message : #message +.. _PMChannel : #PMChannel \ No newline at end of file From 3e9a2bd3468e410f95ca44437ee8260b18689e0d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:10:15 +0100 Subject: [PATCH 149/191] Started work on function --- docs/docs_client.rst | 14 +++++++++++++- docs/docs_resolvable.rst | 2 +- docs/vars.rst | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 35c929cb7..d4377ad9a 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -100,4 +100,16 @@ messages An `Array` of Message_ objects the client has received over its uptime. Functions ---------- \ No newline at end of file +--------- + +.. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. For example, you can do: + +.. code-block:: js + + bot.login(email, password).then(success).catch(err); + + // OR use callbacks: + + bot.login(email, password, function(err, token){ + + }); \ No newline at end of file diff --git a/docs/docs_resolvable.rst b/docs/docs_resolvable.rst index 6fcbc2903..b52a358a5 100644 --- a/docs/docs_resolvable.rst +++ b/docs/docs_resolvable.rst @@ -12,7 +12,7 @@ A Channel Resolvable is data that can be resolved to a channel ID. Here is what - A Channel_ object - A Server_ object (the #general channel of the server will be used) -- A String_ representing the channel ID +- A `String` representing the channel ID - A Message_ (the channel the message was sent in will be used) - A User_ (will get the PM channel with the specified user) diff --git a/docs/vars.rst b/docs/vars.rst index 2a45df682..5aa029c1c 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -3,4 +3,6 @@ .. _Server : #server .. _Channel : #channel .. _Message : #message -.. _PMChannel : #PMChannel \ No newline at end of file +.. _PMChannel : #PMChannel +.. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable +.. _Promises : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise \ No newline at end of file From e0b9ab12da4fc4b940c7b5be9ad706c7f5a9be2e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:11:38 +0100 Subject: [PATCH 150/191] Retest --- docs/docs_client.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index d4377ad9a..181032ab3 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -103,7 +103,6 @@ Functions --------- .. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. For example, you can do: - .. code-block:: js bot.login(email, password).then(success).catch(err); From 9cdd1d416e76b2a36c0ec32e77a0d2a63f6e7be5 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:17:54 +0100 Subject: [PATCH 151/191] Test --- docs/docs_client.rst | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 181032ab3..4ac734955 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -102,13 +102,34 @@ An `Array` of Message_ objects the client has received over its uptime. Functions --------- -.. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. For example, you can do: +.. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. Promises take the exact same parameters for each use case, except errors are moved to catch statements instead of then. For example, you can do: + .. code-block:: js bot.login(email, password).then(success).catch(err); + function success(token){ + + } + + function err(error){ + + } + // OR use callbacks: - bot.login(email, password, function(err, token){ + bot.login(email, password, function(error, token){ - }); \ No newline at end of file + }); + +----- + +login(email, password, `callback`) +~~~~~ + +``Parameters``: +- `email` - A `String` which is the email you want to sign in with. +- `password` - A `String` which is the password you want to sign in with. +- `callback` - A `function` that can take the following parameters: + - `error` - null if there was no error, otherwise it is set. + - `token` - if successful, it is the received authorisation token. \ No newline at end of file From f10895680f4ef447892c25488040cc2322434e65 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:19:12 +0100 Subject: [PATCH 152/191] welp try to fix --- docs/docs_client.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 4ac734955..a2d1b4228 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -127,9 +127,11 @@ Functions login(email, password, `callback`) ~~~~~ -``Parameters``: +`Parameters`: + - `email` - A `String` which is the email you want to sign in with. - `password` - A `String` which is the password you want to sign in with. - `callback` - A `function` that can take the following parameters: + - `error` - null if there was no error, otherwise it is set. - `token` - if successful, it is the received authorisation token. \ No newline at end of file From 9588f5cbf5ec17b65910b3a64fb0f25f9188dd7a Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:21:22 +0100 Subject: [PATCH 153/191] doc formatting test --- docs/docs_client.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index a2d1b4228..3a900dd7a 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -125,13 +125,12 @@ Functions ----- login(email, password, `callback`) -~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `Parameters`: -- `email` - A `String` which is the email you want to sign in with. -- `password` - A `String` which is the password you want to sign in with. -- `callback` - A `function` that can take the following parameters: - - - `error` - null if there was no error, otherwise it is set. - - `token` - if successful, it is the received authorisation token. \ No newline at end of file +- **email** - A `String` which is the email you want to sign in with. +- **password** - A `String` which is the password you want to sign in with. +- **callback** - A `function` that can take the following parameters: + - **error** - null if there was no error, otherwise it is set. + - **token** - if successful, it is the received authorisation token. \ No newline at end of file From 66840c6a27e40f39ca16897f570e85af47954c87 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 27 Sep 2015 20:26:53 +0100 Subject: [PATCH 154/191] more docs --- docs/docs_client.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 3a900dd7a..376d6e964 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -127,10 +127,20 @@ Functions login(email, password, `callback`) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -`Parameters`: +Logs the client in to set it up. Use this after registering your event listeners to ensure they are called. - **email** - A `String` which is the email you want to sign in with. - **password** - A `String` which is the password you want to sign in with. - **callback** - A `function` that can take the following parameters: + - **error** - null if there was no error, otherwise it is set. - - **token** - if successful, it is the received authorisation token. \ No newline at end of file + - **token** - if successful, it is the received authorisation token. + +logout(`callback`) +~~~~~~~~~~~~~~~~~~ + +Logs the client out if it is logged in. If successful, ``bot.state == 4``. + +- **callback** - A `function` that can take the following parameters: + + - **error** - null if there was no error, otherwise it is set. \ No newline at end of file From afb2a66fe2b2ac1df2a5d889dbd2b9dfc558d8a9 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 17:05:02 +0100 Subject: [PATCH 155/191] Added createServer to documentation --- docs/docs_client.rst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 376d6e964..9b4064aab 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -133,7 +133,7 @@ Logs the client in to set it up. Use this after registering your event listeners - **password** - A `String` which is the password you want to sign in with. - **callback** - A `function` that can take the following parameters: - - **error** - null if there was no error, otherwise it is set. + - **error** - An error if one occurred, otherwise it is null. - **token** - if successful, it is the received authorisation token. logout(`callback`) @@ -143,4 +143,18 @@ Logs the client out if it is logged in. If successful, ``bot.state == 4``. - **callback** - A `function` that can take the following parameters: - - **error** - null if there was no error, otherwise it is set. \ No newline at end of file + - **error** - An error if one occurred, otherwise it is null. + +createServer(name, region, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates a server with the specified name or region. See valid regions below: + +- **name** - A `String` that will be the name of your server. +- **region** - A `String` that is a valid Discord region. Currently **``us-west``**, **``us-east``**, **``singapore``**, **``london``**, **``sydney``** or **``amsterdam``**. Providing an invalid region will result in an error. To find the latest available regions, check the `official API here`_. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **server** - A Server_ that represents the created Server. + +.. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From 00083e96edd07513b18bc39bf3afb8c9c93211ee Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 17:23:24 +0100 Subject: [PATCH 156/191] more documentation --- docs/docs_client.rst | 48 +++++++++++++++++++++++++++++++++++++++- docs/docs_resolvable.rst | 10 ++++++++- docs/vars.rst | 2 ++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 9b4064aab..84be2e411 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -151,10 +151,56 @@ createServer(name, region, `callback`) Creates a server with the specified name or region. See valid regions below: - **name** - A `String` that will be the name of your server. -- **region** - A `String` that is a valid Discord region. Currently **``us-west``**, **``us-east``**, **``singapore``**, **``london``**, **``sydney``** or **``amsterdam``**. Providing an invalid region will result in an error. To find the latest available regions, check the `official API here`_. +- **region** - A `String` that is a valid Discord region. Currently **us-west**, **us-east**, **singapore**, **london**, **sydney** or **amsterdam**. Providing an invalid region will result in an error. To find the latest available regions, check the `official API here`_. - **callback** - A `function` that can take the following parameters: - **error** - An error if one occurred, otherwise it is null. - **server** - A Server_ that represents the created Server. + +joinServer(invite, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Accepts a given invite to join a server. The server is automatically cached ASAP. + +- **invite** - An `Invite Resolvable`_ which is the invite that should be accepted. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **server** - A Server_ that represents the joined Server. + +leaveServer(server, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Leaves the given server. + +- **server** - A `Server Resolvable`_ that represents the server you want to leave. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + +createInvite(channel, options, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates an invite for the given channel and returns an Invite_. + +- **channel** - A `Channel Resolvable`_ that is the channel you want to create an invite for. +- **options** - An `object` containing configurable options for the invite. See below for possible configurations. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **invite** - An Invite_ object that contains the details about the created invite. + +.. code-block:: js + + // default configuration of the options variable: + + options = { + max_age : 0, //A number signifying the expiry time for the invite. 0 means infinite. + max_uses : 0, //A number signifying the amount of uses of the invite. 0 means infinite. + temporary : false, //boolean - whether users who use it are kicked unless promoted within 24h. + xkcd : false //boolean - whether the invite's URL should be human-readable + } + + .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file diff --git a/docs/docs_resolvable.rst b/docs/docs_resolvable.rst index b52a358a5..ebd1f2211 100644 --- a/docs/docs_resolvable.rst +++ b/docs/docs_resolvable.rst @@ -5,6 +5,8 @@ Resolvable Documentation To be robust, discord.js needs to handle a wide amount of ambiguous data that is supplied to it. This means you can use functions much more easily. Anything that is resolvable means it can be normalised without you having to do it explicitly. +Resolvables are not objects or classes, they are just ways of expressing what type of data is expected. + Channel Resolvable ------------------ @@ -16,4 +18,10 @@ A Channel Resolvable is data that can be resolved to a channel ID. Here is what - A Message_ (the channel the message was sent in will be used) - A User_ (will get the PM channel with the specified user) -.. note:: A User cannot always be specified in certain cases. For example, if using `bot.setTopic`, a User or PM Channel can't be specified as these do not support channel topics. \ No newline at end of file +.. note:: A User cannot always be specified in certain cases. For example, if using `bot.setTopic`, a User or PM Channel can't be specified as these do not support channel topics. + +Server Resolvable +----------------- + +Invite Resolvable +----------------- \ No newline at end of file diff --git a/docs/vars.rst b/docs/vars.rst index 5aa029c1c..60e2bc533 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -4,5 +4,7 @@ .. _Channel : #channel .. _Message : #message .. _PMChannel : #PMChannel +.. _Invite : #invite .. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable +.. _Invite Resolvable : ./docs_resolvable.html#invite-resolvable .. _Promises : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise \ No newline at end of file From 7f124f68db6da2bcf2689ab8bcf6f64f80dae7f8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 18:10:11 +0100 Subject: [PATCH 157/191] more more more docs --- docs/docs_client.rst | 96 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 84be2e411..3b2c0517a 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -201,6 +201,100 @@ Creates an invite for the given channel and returns an Invite_. xkcd : false //boolean - whether the invite's URL should be human-readable } - +createChannel(server, channelName, channelType, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates a channel in the given server. + +- **server** - A `Server Resolvable`_ that will be the server the channel is created in. +- **channelName** - A `String` that is the name of the channel. +- **channelType** - A `String` that is the type of the channel, either **voice** or **text**. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **channel** - An Channel_ object that represents the created channel. + +deleteChannel(channel, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Deletes the specified channel. + +- **channel** - A `Channel Resolvable`_ that will be the channel to delete. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + +getChannelLogs(channel, `amount`, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Gets previous messages from the specified channel. + +- **channel** - A `Channel Resolvable`_ to take logs from. +- **amount** - A `Number` that defaults to **500**. This is the amount of messages to try and get. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **logs** - An `Array` of Message_ objects that represent the previous messages. + +.. warning:: If the logs contain messages from a user who is no longer in the server, the user object *MAY* be malformed. + +sendMessage(channel, message, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sends a message to the specified channel. + +- **channel** - A `Channel Resolvable`_ to send the message to. +- **message** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **message** - A Message_ representing the sent message. + +sendFile(channel, file, `fileName`, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sends a file to the specified channel. Note that **fileName is necessary in certain cases** for when a file other than an image is sent. For example, if you send a file containing JS code, fileName should be something like ``myCode.js``. + +- **channel** - A `Channel Resolvable`_ to send the file to. +- **file** - The file to send, either a `Buffer` or `String` - if a String, it should be a relative (`./`) or absolute path to a file. +- **fileName** - A `String` containing the file's name and extension, used by Discord (I didn't make this please don't shoot me :s) Examples include `picture.png`, `text.txt`, `wowanamazingscript.js` + +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **message** - A Message_ representing the sent file. + +updateMessage(message, content, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Updates/edits a message with new content. + +- **message** - A Message_ that should be updated. +- **content** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **message** - A Message_ representing the updated message. + +reply(message, yourMessage, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alias for sendMessage, but prepends a mention to whoever sent the specified mention. Useful shortcut for directing a message at a user. + +.. code-block:: js + + // example usage: + + the user 'bob' sent a message + + bot.reply(message, "hello"); + // will send the message '@bob, hello' to the channel the message that bob sent was in. + +- **message** - A Message_ that should be replied to. +- **yourMessage** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + - **message** - A Message_ representing the sent message. .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From d318620b2d7c7cfd0166e6b65235ba9d2099bc6b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 18:42:51 +0100 Subject: [PATCH 158/191] Documentation is so fun /s --- docs/docs_client.rst | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 3b2c0517a..263a3d82f 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -296,5 +296,60 @@ Alias for sendMessage, but prepends a mention to whoever sent the specified ment - **error** - An error if one occurred, otherwise it is null. - **message** - A Message_ representing the sent message. + +setUsername(newName, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets the username of the logged in client. + +- **newName** - The new name of the client, a `String`. +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + +startTyping(channel, *stopTime*) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Makes the client appear to be typing in the specified channel. + +- **channel** - A `Channel Resolvable`_ that should be the channel to start typing in +- **stopTime** - A `Number` in ms which should make the client stop typing after. Allow 5 seconds. + +stopTyping(channel) +~~~~~~~~~~~~~~~~~~~ + +Makes the client stop typing in a specified channel. + +- **channel** - A `Channel Resolvable`_ that should be the channel to stop typing in. + +setStatusOnline() +~~~~~~~~~~~~~~~~~ + +**Aliases**: ``setStatusActive()`` and ``setStatusHere()`` + +Sets the client's status to online; green. + +setStatusIdle() +~~~~~~~~~~~~~~~~~ + +**Aliases**: ``setStatusAway()`` + +Sets the client's status to idle; orange. + +setTopic(channel, topic, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sets the topic of the specified channel + +- **channel** - A `Channel Resolvable`_ that is the channel you want to change the topic of +- **topic** - A `String` that is the topic you want +- **callback** - A `function` that can take the following parameters: + + - **error** - An error if one occurred, otherwise it is null. + +----- + +Events +------ .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From 9a3916428f8e62e908625db9fc4458dd61ef55f8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 18:47:53 +0100 Subject: [PATCH 159/191] finalised function doc --- docs/docs_client.rst | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 263a3d82f..916f8dc37 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -347,6 +347,56 @@ Sets the topic of the specified channel - **error** - An error if one occurred, otherwise it is null. +getUser(key, value) +~~~~~~~~~~~~~~~~~~~ + +Gets a User_ that matches the specified criteria. E.g: + +.. code-block:: js + + bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + +getServer(key, value) +~~~~~~~~~~~~~~~~~~~~~ + +Gets a Server_ that matches the specified criteria. E.g: + +.. code-block:: js + + bot.getServer("id", 1243987349) // returns a server where server.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + + +getChannel(key, value) +~~~~~~~~~~~~~~~~~~~~~~ + +Gets a Channel_ that matches the specified criteria. E.g: + +.. code-block:: js + + bot.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + + +getPMChannel(key, value) +~~~~~~~~~~~~~~~~~~~~~~~~ + +Gets a PMChannel_ that matches the specified criteria. E.g: + +.. code-block:: js + + bot.getPMChannel("id", 1243987349) // returns a PMChannel where pmchannel.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + ----- Events From 04fc4ce64898042a30ab17cfdb1ede193cecfeb8 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 18:52:57 +0100 Subject: [PATCH 160/191] working on events --- docs/docs_client.rst | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 916f8dc37..b03ae01cd 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -399,7 +399,33 @@ Gets a PMChannel_ that matches the specified criteria. E.g: ----- -Events ------- +Event Management +---------------- + +Events are a useful way of listening to events and are available in every API. + +Registering Events +~~~~~~~~~~~~~~~~~~ + +.. code-block:: js + + bot.on("eventName", function(arg1, arg2...){ + // code here is called when eventName is emitted. + }) + +.. note:: You can only have one listening function per event + +Unregistering Events +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: js + + bot.off("eventName") + // eventName is no longer listened for + +Event Types +----------- + + .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From 74a3cdcadec4604433fd3d9b92c22207027adf1d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 19:01:59 +0100 Subject: [PATCH 161/191] event docs --- docs/docs_client.rst | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index b03ae01cd..8a43c6d5a 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -426,6 +426,56 @@ Unregistering Events Event Types ----------- +ready +~~~~~ +Called when the bot is ready and you can begin working with it. + +disconnected +~~~~~~~~~~~~ + +Called when the bot is disconnected for whatever reason. + +error +~~~~~ + +Called whenever there is an error. + +**Parameters** + +- **error** - the encountered error + +.. note:: There may be more parameters supplied depending on the errors. Use the ``arguments`` variable to check for this for advanced debugging. + +debug +~~~~~ + +Called when the client debugs some information that might be useful for a developer but not for an end user. + +**Parameters** + +- **message** - the debug message as a `String` + +message +~~~~~~~ + +Called when a message has been received by the client. + +**Parameters** + +- **message** - the received Message_. + +messageDelete +~~~~~~~~~~~~~ + +Called when a message has been deleted. + +**Parameters** + +- **channel** - The Channel_ that the deleted message was in. +- ***message*** - *May* be available. If the message wasn't previously cached, this will not be supplied and all you would know is that a message was deleted in the channel. If it is available, it will be in the format of a Message_. + +messageUpdate +~~~~~~~~~~~~~ .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From ec6108a230b9dc86b752ab0fa6a6fc6945c8e936 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 20:34:07 +0100 Subject: [PATCH 162/191] CLIENT DOCS ARE DONE WOO --- docs/docs_client.rst | 107 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 8a43c6d5a..5774dfe53 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -473,9 +473,114 @@ Called when a message has been deleted. **Parameters** - **channel** - The Channel_ that the deleted message was in. -- ***message*** - *May* be available. If the message wasn't previously cached, this will not be supplied and all you would know is that a message was deleted in the channel. If it is available, it will be in the format of a Message_. +- **message** - *May* be available. If the message wasn't previously cached, this will not be supplied and all you would know is that a message was deleted in the channel. If it is available, it will be in the format of a Message_. messageUpdate ~~~~~~~~~~~~~ +Called when a message has been updated. + +**Parameters** + +- **newMessage** - The updated Message_. +- **oldMessage** - The old Message_ before it was updated. + +serverDelete +~~~~~~~~~~~~ + +Called when a server is deleted. + +**Parameters** + +- **server** - The deleted Server_. + +channelDelete +~~~~~~~~~~~~~ + +Called when a channel is deleted. + +**Parameters** + +- **channel** - The deleted Channel_. + +serverCreate +~~~~~~~~~~~~ + +Called when a server is created/joined. + +**Parameters** + +- **server** - The created Server_. + +channelCreate +~~~~~~~~~~~~ + +Called when a channel is created. + +**Parameters** + +- **channel** - The created Channel_. + +serverNewMember +~~~~~~~~~~~~~~~ + +Called when a new member is added to a server. + +**Parameters** + +- **user** - The User_ that was added. +- **server** - The Server_ that the user was added to. + +serverRemoveMember +~~~~~~~~~~~~~~~~~~ + +Called when a member of a server leaves or is kicked out. + +**Parameters** + +- **user** - The User_ that was removed. +- **server** - The Server_ that the user was removed from. + +userUpdate +~~~~~~~~~~ + +Called when information about a user changes, such as their username. + +**Parameters** + +- **newUser** - A User_ object representing the changes to the old user (this will be in the cache) +- **oldUser** - A User_ object representing the user before the update. + +presence +~~~~~~~~ + +Called when a user goes online/offline/away or starts/stops playing a game. + +**Parameters** + +- **dataObject** - Instead of separate arguments, presence update takes an object containing the following information: + + - **user** - A User_ representing the User that had a presence update + - **status** - The status change as a `String`. + - **server** - The Server_ that the presence change occurred in. + - **gameId** - A `Number` representing the game they are playing if any. Currently, discord.js has no internal support for converting this into a game name. + +unknown +~~~~~~~ + +Called when an unknown packet was received or there is no handler for it. + +**Parameters** + +- **data** - A `JSON Object` which is the message received over WebSocket. + +raw +~~~ + +Called when a WebSocket message is received and it gives you the message. + +**Parameters** + +- **data** - A `JSON Object` which is the message received over WebSocket. + .. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file From 274d61a0616a37d1422e7d2b9cf3f1baef778791 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 20:37:18 +0100 Subject: [PATCH 163/191] client docs --- docs/docs_client.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 5774dfe53..4c0f19cae 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -5,6 +5,8 @@ Client Documentation This page contains documentation on the `Discord.Client` class. This should be used when you want to start creating things with the API. +It might be beneficial to use CTRL+F to search for what you're looking for, or use the navigation provided by readthedocs on the left. + Attributes ---------- From 32f6f31cdff0b2ae96d5cbcb32c5a92768ddc959 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 20:48:41 +0100 Subject: [PATCH 164/191] Added user documentation --- docs/docs_user.rst | 67 ++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 3 ++- docs/vars.rst | 2 +- 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 docs/docs_user.rst diff --git a/docs/docs_user.rst b/docs/docs_user.rst new file mode 100644 index 000000000..70cf51b2d --- /dev/null +++ b/docs/docs_user.rst @@ -0,0 +1,67 @@ +.. include:: ./vars.rst + +User Documentation +================== + +The User Class is used to represent data about users. + +Attributes +---------- + +username +~~~~~~~~ + +A `String` that is the username of the user. + +discriminator +~~~~~~~~~~~~~ + +Used to differentiate users with the same username, provided by Discord. If you want to differentiate users, we'd recommend using the `id` attribute. + +id +~~ + +A `String` UUID of the user, will never change. + +avatar +~~~~~~ + +A `String` that is the user's avatar's ID, or if they don't have one this is `null`. + +avatarURL +~~~~~~~~~ + +A `String` that points to the user's avatar's URL, or if they don't have an avatar this is `null`. + +status +~~~~~~ + +The status of the user as a `String`; offline/online/idle. + +----- + +Functions +--------- + +mention() +~~~~~~~~~ + +Returns a `String`. This function will generate the mention string for the user, which when sent will preview as a mention. E.g: + +.. code-block:: js + + user.mention(); // something like <@3245982345035> + +This is mainly used internally by the API to correct mentions when sending messages, however you can use it. + +.. note:: You can also just concatenate a User object with strings to get the mention code, as the `toString()` method points to this. This is useful when sending messages. + +equals(object) +~~~~~~~~~~~~~~ + +Returns a `Boolean` depending on whether the User's ID (``user.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare users. **NEVER** do ``user1 == user2``. + +equalsStrict(object) +~~~~~~~~~~~~~~~~~~~~ + +Sees if the supplied object has the same username, ID, avatar and discriminator of the user. Mainly used internally. Returns a `Boolean` depending on the result. diff --git a/docs/index.rst b/docs/index.rst index c0e0451a6..afcd0cfd1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,8 +29,9 @@ Contents: :maxdepth: 2 :caption: Documentation - docs_client docs_resolvable + docs_client + docs_user diff --git a/docs/vars.rst b/docs/vars.rst index 60e2bc533..a0b315c9a 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -1,4 +1,4 @@ -.. _User : #user +.. _User : ./docs_user.html .. _ready : #ready .. _Server : #server .. _Channel : #channel From f36e61ac2a263fe8fdfabff037de425fba62c160 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 20:59:53 +0100 Subject: [PATCH 165/191] Added equals object to documentation, counting as a minor --- docs/docs_server.rst | 107 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/vars.rst | 3 +- src/server.js | 4 ++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 docs/docs_server.rst diff --git a/docs/docs_server.rst b/docs/docs_server.rst new file mode 100644 index 000000000..0baa9d331 --- /dev/null +++ b/docs/docs_server.rst @@ -0,0 +1,107 @@ +.. include:: ./vars.rst + +Server Documentation +================== + +The Server Class is used to represent data about a server. + +Attributes +---------- + +client +~~~~~~ + +The Discord Client_ that the Server was cached by. + +region +~~~~~~ + +The region that the server is in, a `String`. + +name +~~~~ + +The server's name, as a `String`. + +id +~~ + +The server's id, as a `String`. + +members +~~~~~~~ + +**Aliases** : `users` + +The members in a server, an `Array` of User_ objects. + +channels +~~~~~~~~ + +The channels in a server, an `Array` of Channel_ objects. + +icon +~~~~ + +The icon ID of the server if it has one as a `String`, otherwise it is `null`. + +iconURL +~~~~~~~ + +A `String` that is the URL of the server icon if it has one, otherwise it is `null`. + +afkTimeout +~~~~~~~~~~ + +A `Number` that is the AFK Timeout of the Server. + +afkChannel +~~~~~~~~~~ + +A Channel_ that represents the AFK Channel of the server if it has one, otherwise it is `null`. + +defaultChannel +~~~~~~~~~~~~~~ + +The **#general** Channel_ of the server. + +owner +~~~~~ + +A User_ object representing the user that owns the server. + +----- + +Functions +--------- + +.. note:: When concatenated with a String, the object will become the server's name, e.g. ``"this is " + server`` would be ``this is Discord API`` if the server was called `Discord API`. + +getChannel(key, value) +~~~~~~~~~~~~~~~~~~~~~~ + +Gets a Channel_ that matches the specified criteria. E.g: + +.. code-block:: js + + server.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + +getMember(key, value) +~~~~~~~~~~~~~~~~~~~~~ + +Gets a User_ that matches the specified criteria. E.g: + +.. code-block:: js + + bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + +equals(object) +~~~~~~~~~~~~~~ + +Returns a `Boolean` depending on whether the Server's ID (``server.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare servers. **NEVER** do ``server1 == server2``. diff --git a/docs/index.rst b/docs/index.rst index afcd0cfd1..4db5e17e2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -32,6 +32,7 @@ Contents: docs_resolvable docs_client docs_user + docs_server diff --git a/docs/vars.rst b/docs/vars.rst index a0b315c9a..ef98675e4 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -1,6 +1,7 @@ +.. _Client : ./docs_client.html .. _User : ./docs_user.html .. _ready : #ready -.. _Server : #server +.. _Server : ./docs_server.html .. _Channel : #channel .. _Message : #message .. _PMChannel : #PMChannel diff --git a/src/server.js b/src/server.js index c0f24af27..d0d56578c 100644 --- a/src/server.js +++ b/src/server.js @@ -92,6 +92,10 @@ class Server { toString(){ return this.name; } + + equals(object){ + return object.id === this.id; + } } module.exports = Server; \ No newline at end of file From 751eb9095d3112f2f0ca1f06e6e6f53a3f4a26c5 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 28 Sep 2015 21:00:18 +0100 Subject: [PATCH 166/191] 3.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d2500be5a..458024ac2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.5.0", + "version": "3.6.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 55f4e33ada354f796c80ff3472190e6a2404d900 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 29 Sep 2015 17:26:33 +0100 Subject: [PATCH 167/191] Added channel documentation --- docs/docs_channel.rst | 75 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/vars.rst | 2 +- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 docs/docs_channel.rst diff --git a/docs/docs_channel.rst b/docs/docs_channel.rst new file mode 100644 index 000000000..b81ee763f --- /dev/null +++ b/docs/docs_channel.rst @@ -0,0 +1,75 @@ +.. include:: ./vars.rst + +Channel Documentation +===================== + +The Channel Class is used to represent data about a Channel. + +Attributes +---------- + +client +~~~~~~ + +The Discord Client_ that cached the channel + +server +~~~~~~ + +The Server_ that the channel belongs to + +name +~~~~ + +The channel's name, as a `String`. + +id +~~ + +The channel's id, as a `String`. + +type +~~~~ + +The type of the channel as a `String`, either ``text`` or ``voice``. + +topic +~~~~~ + +A `String` that is the topic of the channel, if the channel doesn't have a topic this will be `null`. + +messages +~~~~~~~~ + +An `Array` of Message_ objects received from the channel. There are up to a 1000 messages here, and the older messages will be deleted if necessary. + +members +~~~~~~~ + +**Aliases** : `users` + +The members in the channel's server, an `Array` of User_ objects. + +----- + +Functions +--------- + +.. note:: When concatenated with a String, the object will become the channel's embed code, e.g. ``"this is " + channel`` would be ``this is <#channelid>`` + +getMessage(key, value) +~~~~~~~~~~~~~~~~~~~~~~ + +Gets a Message_ from the channel that matches the specified criteria. E.g: + +.. code-block:: js + + channel.getMessage("id", 1243987349) // returns a Channel where message.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value + +equals(object) +~~~~~~~~~~~~~~ + +Returns a `Boolean` depending on whether the Channel's ID (``channel.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare channels. **NEVER** do ``channel1 == channel2``. diff --git a/docs/index.rst b/docs/index.rst index 4db5e17e2..2b08bfcca 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -33,6 +33,7 @@ Contents: docs_client docs_user docs_server + docs_channel diff --git a/docs/vars.rst b/docs/vars.rst index ef98675e4..7a59d8007 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -2,7 +2,7 @@ .. _User : ./docs_user.html .. _ready : #ready .. _Server : ./docs_server.html -.. _Channel : #channel +.. _Channel : ./docs_channel.html .. _Message : #message .. _PMChannel : #PMChannel .. _Invite : #invite From d50d8907d0ac28fb1fd743b3ad7aa8536e29bc8e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Tue, 29 Sep 2015 17:45:29 +0100 Subject: [PATCH 168/191] Added message documentation --- docs/docs_message.rst | 84 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/vars.rst | 2 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 docs/docs_message.rst diff --git a/docs/docs_message.rst b/docs/docs_message.rst new file mode 100644 index 000000000..7dbbbfc3d --- /dev/null +++ b/docs/docs_message.rst @@ -0,0 +1,84 @@ +.. include:: ./vars.rst + +Message Documentation +===================== + +The Message Class is used to represent data about a Message. + +Attributes +---------- + +tts +~~~ + +A `Boolean` that is ``true`` if the sent message was text-to-speech, otherwise ``false``. + +timestamp +~~~~~~~~~ + +A `unix timestamp` as a `Number` representing when the message was sent. + +mentions +~~~~~~~~ + +An `Array` of User_ objects that represent the users mentioned in the message. + +everyoneMentioned +~~~~~~~~~~~~~~~~~ + +A `Boolean` that is ``true`` if **@everyone** was used, otherwise ``false``. + +id +~~ + +A `String` UUID of the message, will never change. + +.. note:: Currently, message IDs are totally unique. However, in the future they may only be unique within a channel. Make sure to check periodically whether this has changed. + +embeds +~~~~~~ + +A raw, unhandled `JSON object` that will contain embeds of the message - if any. + +editedTimestamp +~~~~~~~~~~~~~~~ + +A `unix timestamp` as a `Number` that is when the message was last edited. + +content +~~~~~~~ + +The actual content of the message as a `String`. + +channel +~~~~~~~ + +The Channel_ that the message was sent in. + +author +~~~~~~ + +**Aliases** : `sender` + +The User_ that sent the message. + +attachments +~~~~~~~~~~~ + +A raw, unhandled `JSON object` that will contain attachments of the message - if any. + +isPrivate +~~~~~~~~~ + +A `Boolean` that is ``true`` if the message was sent in a PM / DM chat, or if it was sent in a group chat it will be ``false``. + +Functions +--------- + +isMentioned(user) +~~~~~~~~~~~~~~~~~ + +A `Boolean` that will return ``true`` if the specified user was mentioned in the message. If everyone is mentioned, this will be false - this function checks specifically for if they were mentioned. + + +- **user** - The User_ that you want to see is mentioned or not. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 2b08bfcca..1fe8e6be3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -34,6 +34,7 @@ Contents: docs_user docs_server docs_channel + docs_message diff --git a/docs/vars.rst b/docs/vars.rst index 7a59d8007..c6284a22b 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -3,7 +3,7 @@ .. _ready : #ready .. _Server : ./docs_server.html .. _Channel : ./docs_channel.html -.. _Message : #message +.. _Message : ./docs_message.html .. _PMChannel : #PMChannel .. _Invite : #invite .. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable From e7adc3ddbf12fca12c951be93b4f2dbda3372535 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 18:23:21 +0100 Subject: [PATCH 169/191] More documentation and updated some PM Channel code The PM Channel will now also trunc messages and cap the array size --- docs/docs_channel.rst | 2 +- docs/docs_pmchannel.rst | 41 +++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/vars.rst | 2 +- src/PMChannel.js | 5 +++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 docs/docs_pmchannel.rst diff --git a/docs/docs_channel.rst b/docs/docs_channel.rst index b81ee763f..063fb0790 100644 --- a/docs/docs_channel.rst +++ b/docs/docs_channel.rst @@ -64,7 +64,7 @@ Gets a Message_ from the channel that matches the specified criteria. E.g: .. code-block:: js - channel.getMessage("id", 1243987349) // returns a Channel where message.id === 1243987349 + channel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349 - **key** - a `String` that is the key - **value** - a `String` that is the value diff --git a/docs/docs_pmchannel.rst b/docs/docs_pmchannel.rst new file mode 100644 index 000000000..3f10acec2 --- /dev/null +++ b/docs/docs_pmchannel.rst @@ -0,0 +1,41 @@ +.. include:: ./vars.rst + +PMChannel Documentation +======================= + +The PMChannel Class is used to represent data about a Private Message Channel. + +.. note:: Beware! The PMChannel class does `not` extend the Channel_ class. + +Attributes +---------- + +user +~~~~ + +The recipient User_ of the PM Channel. + +id +~~ + +`String` UUID of the PM Channel. + +messages +~~~~~~~~ + +An `Array` of Message_ objects. Contains all the cached messages sent in this channel up to a limit of 1000. If the limit is reached, the oldest message is removed first to make space for it. + +Functions +--------- + +getMessage(key, value) +~~~~~~~~~~~~~~~~~~~~~~ + +Gets a Message_ from the PM Channel that matches the specified criteria. E.g: + +.. code-block:: js + + pmchannel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349 + +- **key** - a `String` that is the key +- **value** - a `String` that is the value \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 1fe8e6be3..ff7a59144 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -34,6 +34,7 @@ Contents: docs_user docs_server docs_channel + docs_pmchannel docs_message diff --git a/docs/vars.rst b/docs/vars.rst index c6284a22b..523c83d2d 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -4,7 +4,7 @@ .. _Server : ./docs_server.html .. _Channel : ./docs_channel.html .. _Message : ./docs_message.html -.. _PMChannel : #PMChannel +.. _PMChannel : ./docs_pmchannel.html .. _Invite : #invite .. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable .. _Invite Resolvable : ./docs_resolvable.html#invite-resolvable diff --git a/src/PMChannel.js b/src/PMChannel.js index d82cf7932..d7985f9c4 100644 --- a/src/PMChannel.js +++ b/src/PMChannel.js @@ -13,6 +13,11 @@ class PMChannel { } getMessage(key, value){ + + if(this.messages.length > 1000){ + this.messages.splice(0,1); + } + for(var message of this.messages){ if(message[key] === value){ return message; From ab5f0f8b7e720508f083358cd7322bfa3e467abc Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 18:31:50 +0100 Subject: [PATCH 170/191] Last of most of the documentation! --- docs/docs_invite.rst | 64 ++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/vars.rst | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 docs/docs_invite.rst diff --git a/docs/docs_invite.rst b/docs/docs_invite.rst new file mode 100644 index 000000000..4c1688b1e --- /dev/null +++ b/docs/docs_invite.rst @@ -0,0 +1,64 @@ +.. include:: ./vars.rst + +Invite Documentation +==================== + +The Invite Class is used to represent data about an Invite. + +Attributes +---------- + +max_age +~~~~~~~ + +A `Number` in minutes for how long the Invite should be valid for. E.g. a value of ``3600`` is equal to 30 minutes. + +code +~~~~ + +`String` an alphanumeric code for the Invite. + +revoked +~~~~~~~ + +`Boolean` that dictates whether the Invite has been cancelled or not + +created_at +~~~~~~~~~~ + +A unix timestamp as a `Number` which is the time that the invite was created. + +temporary +~~~~~~~~~ + +`Boolean` that dictates whether the invite is temporary. + +uses +~~~~ + +`Number` the number of uses of the Invite, a value of ``0`` is none. + +max_uses +~~~~~~~~ + +`Number` that is the maximum amount of uses of the invite, ``0`` is unlimited. + +inviter +~~~~~~~ + +The User_ that created the invite. + +xkcd +~~~~ + +`Boolean` that is true if the invite should be human-readable. + +channel +~~~~~~~ + +The Channel_ that the invite is inviting to. + +URL +~~~ + +A `String` that generates a clickable link to the invite. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index ff7a59144..34e8f71a9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -36,6 +36,7 @@ Contents: docs_channel docs_pmchannel docs_message + docs_invite diff --git a/docs/vars.rst b/docs/vars.rst index 523c83d2d..ad4b9720a 100644 --- a/docs/vars.rst +++ b/docs/vars.rst @@ -5,7 +5,7 @@ .. _Channel : ./docs_channel.html .. _Message : ./docs_message.html .. _PMChannel : ./docs_pmchannel.html -.. _Invite : #invite +.. _Invite : ./docs_invite.html .. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable .. _Invite Resolvable : ./docs_resolvable.html#invite-resolvable .. _Promises : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise \ No newline at end of file From a99b628fcf415cfd0de1e09311e290d83bdf2e19 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 18:51:07 +0100 Subject: [PATCH 171/191] Updated readme @ 3.6.1 --- README.md | 51 +++++++++------------------------------------------ package.json | 2 +- 2 files changed, 10 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index b83cdabae..38c7f8c09 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,13 @@

-[![Build Status](https://travis-ci.org/hydrabolt/discord.js.svg)](https://travis-ci.org/hydrabolt/discord.js) +[![Build Status](https://travis-ci.org/hydrabolt/discord.js.svg)](https://travis-ci.org/hydrabolt/discord.js) [![Documentation Status](https://readthedocs.org/projects/discordjs/badge/?version=latest)](http://discordjs.readthedocs.org/en/latest/?badge=latest) + discord.js is a node module used as a way of interfacing with [Discord](https://discordapp.com/). It is a very useful module for creating bots. -**Updating to 3.1.1 is essential as it has new changes to be compatible with Discord's API, -and to make sure your application still works an update is a good idea.** - ### Installation `npm install --save discord.js` @@ -46,7 +44,7 @@ Here is a list of other Discord APIs: [DiscordSharp](https://github.com/Luigifan/DiscordSharp) #### NodeJS -[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level) +[discord.io](https://github.com/izy521/node-discord) (similar to discord.js but lower level) #### PHP [DiscordPHP](https://github.com/teamreflex/DiscordPHP) @@ -59,42 +57,8 @@ Here is a list of other Discord APIs: --- -### Changes in 3.1.4 - -No, not π. But instead, pseduo-synchronous messaging was added! This means that -you can tell your Client to make a queue of "actions" per channel, and it will -work through them one by one. This is a really useful tool if you need to send -messages in a specific order without callback hell. - -It also allows you to store responses - such as created messages - in the returned -promise - named action. Example: - -```js -var mybot = new Discord.Client({ - queue : true //enable queueing, disabled by default -}); - -mybot.on("message", function(msg){ - - mybot.sendMessage(msg.channel, "this is message 1"); - var action = mybot.sendMessage(msg.channel, "this is message 2"); - mybot.sendMessage(msg.channel, "this is message 3").then(rmv); - - function rmv(){ - if(!action.error){ - mybot.deleteMessage(action.message); - } - } - -}); -``` - -This is still in development, and will see many more enhancements in future. - ---- - ### Links -**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)** +**[Documentation](http://discordjs.readthedocs.org/en/latest/)** **[GitHub](https://github.com/discord-js/discord.js)** @@ -108,5 +72,8 @@ This is still in development, and will see many more enhancements in future. ### Contact -If you would like to contact me, you can create an issue on the GitHub repo -or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTYd2XyW). +If you have an issue or want to know if a feature exists, [read the documentation](http://discordjs.readthedocs.org/en/latest/) before contacting me about any issues! If it's badly/wrongly implemented, let me know! + + +If you would like to contact me, you can create an issue on the GitHub repo, e-mail me via the one available on my NPM profile. +Or you could just send a DM to **hydrabolt** in [**Discord API**](https://discord.gg/0SBTUU1wZTYd2XyW). diff --git a/package.json b/package.json index 458024ac2..2059611ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.6.0", + "version": "3.6.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 46846fcacc2523488beb8f089ce1728d3ab24314 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 20:47:26 +0100 Subject: [PATCH 172/191] added setPlaying and now working on docs --- docs/docs_client.rst | 7 ++++ lib/Client.js | 90 +++++++++++++++++++++++++++++++++++++------- lib/PMChannel.js | 5 +++ lib/server.js | 5 +++ ref/gameMap.json | 1 + src/Client.js | 51 ++++++++++++++++++++++++- test/bot.1.js | 10 ++--- 7 files changed, 149 insertions(+), 20 deletions(-) create mode 100644 ref/gameMap.json diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 4c0f19cae..d312ab6a2 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -399,6 +399,13 @@ Gets a PMChannel_ that matches the specified criteria. E.g: - **key** - a `String` that is the key - **value** - a `String` that is the value +setPlayingGame(id) +~~~~~~~~~~~~~~~~~~ + +Sets the client as playing the specified game name/id. + +- **id** - Either a `Number` or a `String`. If it's a Number, it's assumed that you are using the Discord Game ID + ----- Event Management diff --git a/lib/Client.js b/lib/Client.js index d3d6f1f78..8b9c7f5c6 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -13,6 +13,8 @@ var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); +var gameMap = require("../ref/gameMap.json"); + //node modules var request = require("superagent"); var WebSocket = require("ws"); @@ -63,6 +65,9 @@ var Client = (function () { this.readyTime = null; this.checkingQueue = {}; this.queue = {}; + + this.__idleTime = null; + this.__gameId = null; } _createClass(Client, [{ @@ -1778,14 +1783,73 @@ var Client = (function () { var idleTime = stat === "online" ? null : Date.now(); + this.__idleTime = idleTime; + this.websocket.send(JSON.stringify({ op: 3, d: { - idle_since: idleTime, - game_id: null + idle_since: this.__idleTime, + game_id: this.__gameId } })); } + }, { + key: "setPlayingGame", + value: function setPlayingGame(id) { + + if (id instanceof String || typeof id === "string") { + + // working on names + var gid = id.trim().toUpperCase(); + + id = null; + + var _iteratorNormalCompletion16 = true; + var _didIteratorError16 = false; + var _iteratorError16 = undefined; + + try { + for (var _iterator16 = gameMap[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { + var game = _step16.value; + + if (game.name.trim().toUpperCase() === gid) { + + id = game.id; + break; + } + } + } catch (err) { + _didIteratorError16 = true; + _iteratorError16 = err; + } finally { + try { + if (!_iteratorNormalCompletion16 && _iterator16["return"]) { + _iterator16["return"](); + } + } finally { + if (_didIteratorError16) { + throw _iteratorError16; + } + } + } + } + + this.__gameId = id; + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: this.__idleTime, + game_id: this.__gameId + } + })); + } + }, { + key: "playingGame", + value: function playingGame(id) { + + this.setPlayingGame(id); + } }, { key: "uptime", get: function get() { @@ -1822,27 +1886,27 @@ var Client = (function () { get: function get() { var msgs = []; - var _iteratorNormalCompletion16 = true; - var _didIteratorError16 = false; - var _iteratorError16 = undefined; + var _iteratorNormalCompletion17 = true; + var _didIteratorError17 = false; + var _iteratorError17 = undefined; try { - for (var _iterator16 = this.channelCache[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { - var channel = _step16.value; + for (var _iterator17 = this.channelCache[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { + var channel = _step17.value; msgs = msgs.concat(channel.messages); } } catch (err) { - _didIteratorError16 = true; - _iteratorError16 = err; + _didIteratorError17 = true; + _iteratorError17 = err; } finally { try { - if (!_iteratorNormalCompletion16 && _iterator16["return"]) { - _iterator16["return"](); + if (!_iteratorNormalCompletion17 && _iterator17["return"]) { + _iterator17["return"](); } } finally { - if (_didIteratorError16) { - throw _iteratorError16; + if (_didIteratorError17) { + throw _iteratorError17; } } } diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 7c30a7c34..0dbc0405e 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -24,6 +24,11 @@ var PMChannel = (function () { }, { key: "getMessage", value: function getMessage(key, value) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; diff --git a/lib/server.js b/lib/server.js index a5c90170d..c8758d5da 100644 --- a/lib/server.js +++ b/lib/server.js @@ -142,6 +142,11 @@ var Server = (function () { value: function toString() { return this.name; } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } }, { key: "iconURL", get: function get() { diff --git a/ref/gameMap.json b/ref/gameMap.json new file mode 100644 index 000000000..8b351465f --- /dev/null +++ b/ref/gameMap.json @@ -0,0 +1 @@ +[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}] \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index ef51e2c42..ef3d7009c 100644 --- a/src/Client.js +++ b/src/Client.js @@ -7,6 +7,8 @@ var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); +var gameMap = require("../ref/gameMap.json"); + //node modules var request = require("superagent"); var WebSocket = require("ws"); @@ -53,6 +55,9 @@ class Client { this.readyTime = null; this.checkingQueue = {}; this.queue = {}; + + this.__idleTime = null; + this.__gameId = null; } get uptime() { @@ -1521,14 +1526,56 @@ class Client { var idleTime = (stat === "online" ? null : Date.now()); + this.__idleTime = idleTime; + this.websocket.send(JSON.stringify({ op : 3, d : { - idle_since : idleTime, - game_id : null + idle_since : this.__idleTime, + game_id : this.__gameId } })); } + + setPlayingGame(id){ + + if( id instanceof String || typeof id === `string` ){ + + // working on names + var gid = id.trim().toUpperCase(); + + id = null; + + for( var game of gameMap ){ + + if(game.name.trim().toUpperCase() === gid){ + + id = game.id; + break; + + } + + } + + } + + this.__gameId = id; + + this.websocket.send(JSON.stringify({ + op : 3, + d : { + idle_since : this.__idleTime, + game_id : this.__gameId + } + })); + + } + + playingGame(id){ + + this.setPlayingGame(id); + + } } module.exports = Client; \ No newline at end of file diff --git a/test/bot.1.js b/test/bot.1.js index 4eb5ab07f..289d3c7bb 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -4,6 +4,8 @@ var fs = require("fs"); var server, channel, message, sentMessage = false; +counter = 1; + mybot.on("message", function (message) { console.log("Everyone mentioned? " + message.everyoneMentioned); @@ -19,16 +21,14 @@ mybot.on("message", function (message) { var onlineUsers = 0; - mybot.startTyping(message.channel, 6000); + counter++; + + mybot.playingGame( "Minecraft" ); }); mybot.on("ready", function () { console.log("im ready"); - - for(var chann of mybot.channels){ - mybot.setTopic(chann, "THINGS"); - } }); mybot.on("debug", function(info){ From 32a9321cfdd6258abab0e14f445234bdf410aceb Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 20:52:07 +0100 Subject: [PATCH 173/191] Added setPlaying to docs --- docs/docs_client.rst | 19 +++++++++++++++++-- lib/Client.js | 5 +++++ src/Client.js | 4 ++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/docs_client.rst b/docs/docs_client.rst index d312ab6a2..cb5ed2bab 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -402,9 +402,22 @@ Gets a PMChannel_ that matches the specified criteria. E.g: setPlayingGame(id) ~~~~~~~~~~~~~~~~~~ +**Aliases** : `playGame`, `playingGame` + Sets the client as playing the specified game name/id. -- **id** - Either a `Number` or a `String`. If it's a Number, it's assumed that you are using the Discord Game ID +- **id** - Either a `Number` or a `String`. If it's a Number, it's assumed that you are using a `Discord Game ID`_ and know what you want. If you supply a `String`, it will assume you are entering a game name and try resolving it to a Discord Game ID if it's available. Example: + +.. code-block:: js + + client.setPlayingGame(18); + // sets the client as playing Minecraft, game ID 18 + + client.setPlayingGame("Minecraft"); + // sets the client as playing Minecraft by resolving the ID to 18 + + client.setPlayingGame("my magical made up game") + // will stop the client from playing anything as it is unresolved, not a valid game. ----- @@ -592,4 +605,6 @@ Called when a WebSocket message is received and it gives you the message. - **data** - A `JSON Object` which is the message received over WebSocket. -.. _official API here : https://discordapp.com/api/voice/regions \ No newline at end of file +.. _official API here : https://discordapp.com/api/voice/regions + +.. _Discord Game ID : https://raw.githubusercontent.com/hydrabolt/discord.js/master/ref/gameMap.json \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js index 8b9c7f5c6..67c27c047 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1844,6 +1844,11 @@ var Client = (function () { } })); } + }, { + key: "playGame", + value: function playGame(id) { + this.setPlayingGame(id); + } }, { key: "playingGame", value: function playingGame(id) { diff --git a/src/Client.js b/src/Client.js index ef3d7009c..336d704f9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -1571,6 +1571,10 @@ class Client { } + playGame(id){ + this.setPlayingGame(id); + } + playingGame(id){ this.setPlayingGame(id); From 8d69e769f6586cda75769fbb34fe3c147e5aaee6 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Wed, 30 Sep 2015 20:58:49 +0100 Subject: [PATCH 174/191] version bump docs --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d3f40bee4..6ce076bcb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,9 +55,9 @@ author = u'hydrabolt' # built documents. # # The short X.Y version. -version = '3.3.4' +version = '3.6' # The full version, including alpha/beta/rc tags. -release = '3.3.4' +release = '3.6.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 1b67678d4411beddd49ca6fc0399d3085beeb640 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 1 Oct 2015 17:05:19 +0100 Subject: [PATCH 175/191] Added SSL cert fix --- lib/Client.js | 2 +- src/Client.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 67c27c047..212386752 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -154,7 +154,7 @@ var Client = (function () { self.token = res.body.token; //set our token self.getGateway().then(function (url) { - self.createws(url); + self.createws(url.replace("discord.gg", "discordapp.net")); callback(null, self.token); resolve(self.token); })["catch"](function (err) { diff --git a/src/Client.js b/src/Client.js index 336d704f9..d0a9e3a79 100644 --- a/src/Client.js +++ b/src/Client.js @@ -168,7 +168,7 @@ class Client { self.token = res.body.token; //set our token self.getGateway().then(function (url) { - self.createws(url); + self.createws(url.replace("discord.gg", "discordapp.net")); callback(null, self.token); resolve(self.token); }).catch(function (err) { From 73dc5a5e22da94e51287fbb422c0f4e7304f9d18 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 1 Oct 2015 17:05:33 +0100 Subject: [PATCH 176/191] 3.6.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2059611ee..8d968f849 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.6.1", + "version": "3.6.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From ada3261918f731e46126772276f67073d71c2bf0 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Thu, 1 Oct 2015 18:16:48 +0100 Subject: [PATCH 177/191] Added permission --- src/Permissions.js | 38 ++++++++++++++++++++++++++++++++++++++ test/bot.1.js | 7 +++++++ 2 files changed, 45 insertions(+) create mode 100644 src/Permissions.js diff --git a/src/Permissions.js b/src/Permissions.js new file mode 100644 index 000000000..e0dc4d424 --- /dev/null +++ b/src/Permissions.js @@ -0,0 +1,38 @@ +class Permission { + + constructor(packedPermissions) { + + function getBit(x) { + return ((this.packed >>> x) & 1) === 1; + } + + this.packed = packedPermissions; + + this.createInstantInvite = getBit(0); + this.banMembers = getBit(1); + this.kickMembers = getBit(2); + this.manageRoles = getBit(3); + this.manageChannels = getBit(4); + this.manageServer = getBit(5); + this.readMessages = getBit(10); + this.sendMessages = getBit(11); + this.sendTTSMessages = getBit(12); + this.manageMessages = getBit(13); + this.embedLinks = getBit(14); + this.attachFiles = getBit(15); + this.readMessageHistory = getBit(16); + this.mentionEveryone = getBit(17); + + this.voiceConnect = getBit(20); + this.voiceSpeak = getBit(21); + this.voiceMuteMembers = getBit(22); + this.voiceDeafenMembers = getBit(23); + this.voiceMoveMembers = getBit(24); + this.voiceUseVoiceActivation = getBit(26); + + } + + getBit(x) { + return ((this.packed >>> x) & 1) === 1; + } +} \ No newline at end of file diff --git a/test/bot.1.js b/test/bot.1.js index 289d3c7bb..2531ad78e 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -29,6 +29,13 @@ mybot.on("message", function (message) { mybot.on("ready", function () { console.log("im ready"); + + for(var server of mybot.servers){ + if(server.name === "test-server"){ + mybot.leaveServer(server); + } + } + }); mybot.on("debug", function(info){ From ccb1798b7b2abb90e7bfe54b14ef97f16cae6f7b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 16:06:01 +0100 Subject: [PATCH 178/191] Roll back to previous WS url, it broke --- lib/Client.js | 2 +- lib/Permissions.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/Client.js | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 lib/Permissions.js diff --git a/lib/Client.js b/lib/Client.js index 212386752..67c27c047 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -154,7 +154,7 @@ var Client = (function () { self.token = res.body.token; //set our token self.getGateway().then(function (url) { - self.createws(url.replace("discord.gg", "discordapp.net")); + self.createws(url); callback(null, self.token); resolve(self.token); })["catch"](function (err) { diff --git a/lib/Permissions.js b/lib/Permissions.js new file mode 100644 index 000000000..a1f4f3083 --- /dev/null +++ b/lib/Permissions.js @@ -0,0 +1,48 @@ +"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 Permission = (function () { + function Permission(packedPermissions) { + _classCallCheck(this, Permission); + + function getBit(x) { + return (this.packed >>> x & 1) === 1; + } + + this.packed = packedPermissions; + + this.createInstantInvite = getBit(0); + this.banMembers = getBit(1); + this.kickMembers = getBit(2); + this.manageRoles = getBit(3); + this.manageChannels = getBit(4); + this.manageServer = getBit(5); + this.readMessages = getBit(10); + this.sendMessages = getBit(11); + this.sendTTSMessages = getBit(12); + this.manageMessages = getBit(13); + this.embedLinks = getBit(14); + this.attachFiles = getBit(15); + this.readMessageHistory = getBit(16); + this.mentionEveryone = getBit(17); + + this.voiceConnect = getBit(20); + this.voiceSpeak = getBit(21); + this.voiceMuteMembers = getBit(22); + this.voiceDeafenMembers = getBit(23); + this.voiceMoveMembers = getBit(24); + this.voiceUseVoiceActivation = getBit(26); + } + + _createClass(Permission, [{ + key: "getBit", + value: function getBit(x) { + return (this.packed >>> x & 1) === 1; + } + }]); + + return Permission; +})(); \ No newline at end of file diff --git a/src/Client.js b/src/Client.js index d0a9e3a79..336d704f9 100644 --- a/src/Client.js +++ b/src/Client.js @@ -168,7 +168,7 @@ class Client { self.token = res.body.token; //set our token self.getGateway().then(function (url) { - self.createws(url.replace("discord.gg", "discordapp.net")); + self.createws(url); callback(null, self.token); resolve(self.token); }).catch(function (err) { From 1eb2be50c178be2a0f285b0f28476771f614549b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 16:06:23 +0100 Subject: [PATCH 179/191] 3.6.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8d968f849..186f4b624 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.6.2", + "version": "3.6.3", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 1ff31ac12ba3a85fbcec0805bb27cc2877eba454 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 20:04:58 +0100 Subject: [PATCH 180/191] Added member class --- src/Member.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/Member.js diff --git a/src/Member.js b/src/Member.js new file mode 100644 index 000000000..3fa49ebd6 --- /dev/null +++ b/src/Member.js @@ -0,0 +1,12 @@ +var User = require("./user.js"); + +class Member extends User{ + + constructor(data){ + super(data); + + + + } + +} \ No newline at end of file From 6b8dadced8bf2d3692a3dd3b618365e8983c91c7 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:27:08 +0100 Subject: [PATCH 181/191] added PMChannel --- lib/Client.js | 1 + src/Client.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/lib/Client.js b/lib/Client.js index 67c27c047..916039ffa 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -12,6 +12,7 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); +var Member = require("./Member.js"); var gameMap = require("../ref/gameMap.json"); diff --git a/src/Client.js b/src/Client.js index 336d704f9..459faab75 100644 --- a/src/Client.js +++ b/src/Client.js @@ -6,6 +6,7 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); +var Member = require("./Member.js"); var gameMap = require("../ref/gameMap.json"); @@ -1220,6 +1221,8 @@ class Client { channId = destination.id; } else if (destination instanceof Message) { channId = destination.channel.id; + } else if (destination instanceof PMChannel) { + channId = destination.id; } else if (destination instanceof User) { //check if we have a PM From c7ab2d37dbe0213990b5e0150d529f997c4316fa Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:30:14 +0100 Subject: [PATCH 182/191] Updated reference removed invalid reference so no error --- src/Client.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Client.js b/src/Client.js index 459faab75..aa396fb4e 100644 --- a/src/Client.js +++ b/src/Client.js @@ -6,7 +6,6 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); -var Member = require("./Member.js"); var gameMap = require("../ref/gameMap.json"); From 37d9d23679d88522177695e7e916fc9f1f54e0f3 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:32:40 +0100 Subject: [PATCH 183/191] actually build changes reference now works when building --- lib/Client.js | 3 ++- lib/Member.js | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 lib/Member.js diff --git a/lib/Client.js b/lib/Client.js index 916039ffa..091424b16 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -12,7 +12,6 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); -var Member = require("./Member.js"); var gameMap = require("../ref/gameMap.json"); @@ -1457,6 +1456,8 @@ var Client = (function () { channId = destination.id; } else if (destination instanceof Message) { channId = destination.channel.id; + } else if (destination instanceof PMChannel) { + channId = destination.id; } else if (destination instanceof User) { //check if we have a PM diff --git a/lib/Member.js b/lib/Member.js new file mode 100644 index 000000000..7d7b03f1a --- /dev/null +++ b/lib/Member.js @@ -0,0 +1,21 @@ +"use strict"; + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +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 User = require("./user.js"); + +var Member = (function (_User) { + _inherits(Member, _User); + + function Member(data) { + _classCallCheck(this, Member); + + _get(Object.getPrototypeOf(Member.prototype), "constructor", this).call(this, data); + } + + return Member; +})(User); \ No newline at end of file From 9824a702b76e3b9827085501e3698fe7ad65bd7d Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:38:07 +0100 Subject: [PATCH 184/191] rebuild and prepublish --- gruntfile.js | 1 + lib/Client.js | 2 +- lib/Endpoints.js | 2 +- lib/Member.js | 2 +- lib/PMChannel.js | 2 +- lib/Permissions.js | 2 +- lib/channel.js | 2 +- lib/index.js | 2 +- lib/internal.js | 2 +- lib/invite.js | 2 +- lib/message.js | 2 +- lib/server.js | 2 +- lib/user.js | 2 +- package.json | 1 + web-dist/discord.3.6.3.js | 3879 +++++++++++++++++++++++++++++++++ web-dist/discord.min.3.6.3.js | 2 + 16 files changed, 3895 insertions(+), 12 deletions(-) create mode 100644 web-dist/discord.3.6.3.js create mode 100644 web-dist/discord.min.3.6.3.js diff --git a/gruntfile.js b/gruntfile.js index a8972256f..d3cd05f6d 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -44,5 +44,6 @@ module.exports = function (grunt) { // register at least this one task grunt.registerTask('default', ['babel']); grunt.registerTask('web', ['browserify', "uglify"]); + grunt.registerTask('dist', ["babel", "browserify", "uglify"]) }; \ No newline at end of file diff --git a/lib/Client.js b/lib/Client.js index 091424b16..4d097628b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1925,4 +1925,4 @@ var Client = (function () { return Client; })(); -module.exports = Client; \ No newline at end of file +module.exports = Client; diff --git a/lib/Endpoints.js b/lib/Endpoints.js index 271b465eb..e55f0f580 100644 --- a/lib/Endpoints.js +++ b/lib/Endpoints.js @@ -10,4 +10,4 @@ exports.LOGIN = exports.AUTH + "/login"; exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; -exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file +exports.CHANNELS = exports.API + "/channels"; diff --git a/lib/Member.js b/lib/Member.js index 7d7b03f1a..471460e77 100644 --- a/lib/Member.js +++ b/lib/Member.js @@ -18,4 +18,4 @@ var Member = (function (_User) { } return Member; -})(User); \ No newline at end of file +})(User); diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 0dbc0405e..6eb8134de 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -68,4 +68,4 @@ var PMChannel = (function () { return PMChannel; })(); -module.exports = PMChannel; \ No newline at end of file +module.exports = PMChannel; diff --git a/lib/Permissions.js b/lib/Permissions.js index a1f4f3083..3b7c8f256 100644 --- a/lib/Permissions.js +++ b/lib/Permissions.js @@ -45,4 +45,4 @@ var Permission = (function () { }]); return Permission; -})(); \ No newline at end of file +})(); diff --git a/lib/channel.js b/lib/channel.js index bb67fcf4f..90a2d7428 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -98,4 +98,4 @@ var Channel = (function () { return Channel; })(); -module.exports = Channel; \ No newline at end of file +module.exports = Channel; diff --git a/lib/index.js b/lib/index.js index 6a2f82f05..f0c3c0ab7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -9,4 +9,4 @@ var Discord = { Client: Client }; -module.exports = Discord; \ No newline at end of file +module.exports = Discord; diff --git a/lib/internal.js b/lib/internal.js index 3acf5940b..e8b3385da 100644 --- a/lib/internal.js +++ b/lib/internal.js @@ -200,4 +200,4 @@ Internal.XHR.setUsername = function (token, avatar, email, newPassword, password }); }; -exports.Internal = Internal; \ No newline at end of file +exports.Internal = Internal; diff --git a/lib/invite.js b/lib/invite.js index 5f51dc1a9..7bc8204bd 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -32,4 +32,4 @@ var Invite = (function () { return Invite; })(); -module.exports = Invite; \ No newline at end of file +module.exports = Invite; diff --git a/lib/message.js b/lib/message.js index 3dd4ddcae..f3f3c574a 100644 --- a/lib/message.js +++ b/lib/message.js @@ -76,4 +76,4 @@ var Message = (function () { return Message; })(); -module.exports = Message; \ No newline at end of file +module.exports = Message; diff --git a/lib/server.js b/lib/server.js index c8758d5da..8bd9332a2 100644 --- a/lib/server.js +++ b/lib/server.js @@ -180,4 +180,4 @@ var Server = (function () { return Server; })(); -module.exports = Server; \ No newline at end of file +module.exports = Server; diff --git a/lib/user.js b/lib/user.js index 5e38e132e..e2b2ca256 100644 --- a/lib/user.js +++ b/lib/user.js @@ -54,4 +54,4 @@ var User = (function () { return User; })(); -module.exports = User; \ No newline at end of file +module.exports = User; diff --git a/package.json b/package.json index 186f4b624..cb928dae9 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { + "prepublish" : "grunt dist", "test": "node ./test/bot.js" }, "repository": { diff --git a/web-dist/discord.3.6.3.js b/web-dist/discord.3.6.3.js new file mode 100644 index 000000000..0d9f9341a --- /dev/null +++ b/web-dist/discord.3.6.3.js @@ -0,0 +1,3879 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + + return prom; + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + self.trigger("raw", dat); + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener[data.id]) { + var cbs = self.serverCreateListener[data.id]; + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener[data.id] = null; + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user, server); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user, server); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + userInCache.status = data.status; + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + case "CHANNEL_UPDATE": + + var channelInCache = self.getChannel("id", data.id), + serverInCache = self.getServer("id", data.guild_id); + + if (channelInCache && serverInCache) { + + var newChann = new Channel(data, serverInCache); + newChann.messages = channelInCache.messages; + + self.trigger("channelUpdate", channelInCache, newChann); + + self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann; + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + }, { + key: "setTopic", + value: function setTopic(channel, topic) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + self.resolveDestination(channel).then(next)["catch"](error); + + function error(e) { + callback(e); + reject(e); + } + + function next(destination) { + + var asChan = self.getChannel("id", destination); + + request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({ + name: asChan.name, + position: 0, + topic: topic + }).end(function (err, res) { + if (err) { + error(err); + } else { + asChan.topic = res.body.topic; + resolve(); + callback(); + } + }); + } + }); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var self = this; + var server = this.getServer("id", data.id); + + if (data.unavailable) { + self.trigger("unavailable", data); + self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached."); + return; + } + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + } + } + + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var presence = _step9.value; + + self.getUser("id", presence.user.id).status = presence.status; + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 3, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof PMChannel) { + channId = destination.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; + + if (pmc.user.equals(destination)) { + resolve(pmc.id); + return; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId);else reject(); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var mention = _step15.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } + }, { + key: "getGateway", + value: function getGateway() { + var self = this; + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + } + }, { + key: "setStatusIdle", + value: function setStatusIdle() { + this.setStatus("idle"); + } + }, { + key: "setStatusOnline", + value: function setStatusOnline() { + this.setStatus("online"); + } + }, { + key: "setStatusActive", + value: function setStatusActive() { + this.setStatusOnline(); + } + }, { + key: "setStatusHere", + value: function setStatusHere() { + this.setStatusOnline(); + } + }, { + key: "setStatusAway", + value: function setStatusAway() { + this.setStatusIdle(); + } + }, { + key: "startTyping", + value: function startTyping(chann, stopTypeTime) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (self.typingIntervals[channel]) { + return; + } + + var fn = function fn() { + request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end(); + }; + + fn(); + + var interval = setInterval(fn, 3000); + + self.typingIntervals[channel] = interval; + + if (stopTypeTime) { + setTimeout(function () { + self.stopTyping(channel); + }, stopTypeTime); + } + } + } + }, { + key: "stopTyping", + value: function stopTyping(chann) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (!self.typingIntervals[channel]) { + return; + } + + clearInterval(self.typingIntervals[channel]); + + delete self.typingIntervals[channel]; + } + } + }, { + key: "setStatus", + value: function setStatus(stat) { + + var idleTime = stat === "online" ? null : Date.now(); + + this.__idleTime = idleTime; + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: this.__idleTime, + game_id: this.__gameId + } + })); + } + }, { + key: "setPlayingGame", + value: function setPlayingGame(id) { + + if (id instanceof String || typeof id === "string") { + + // working on names + var gid = id.trim().toUpperCase(); + + id = null; + + var _iteratorNormalCompletion16 = true; + var _didIteratorError16 = false; + var _iteratorError16 = undefined; + + try { + for (var _iterator16 = gameMap[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { + var game = _step16.value; + + if (game.name.trim().toUpperCase() === gid) { + + id = game.id; + break; + } + } + } catch (err) { + _didIteratorError16 = true; + _iteratorError16 = err; + } finally { + try { + if (!_iteratorNormalCompletion16 && _iterator16["return"]) { + _iterator16["return"](); + } + } finally { + if (_didIteratorError16) { + throw _iteratorError16; + } + } + } + } + + this.__gameId = id; + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: this.__idleTime, + game_id: this.__gameId + } + })); + } + }, { + key: "playGame", + value: function playGame(id) { + this.setPlayingGame(id); + } + }, { + key: "playingGame", + value: function playingGame(id) { + + this.setPlayingGame(id); + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion17 = true; + var _didIteratorError17 = false; + var _iteratorError17 = undefined; + + try { + for (var _iterator17 = this.channelCache[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { + var channel = _step17.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError17 = true; + _iteratorError17 = err; + } finally { + try { + if (!_iteratorNormalCompletion17 && _iterator17["return"]) { + _iterator17["return"](); + } + } finally { + if (_didIteratorError17) { + throw _iteratorError17; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +module.exports = Client; + +},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; + +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "isPrivate", + get: function get() { + return true; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; + +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.topic = data.topic; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object && object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "<#" + this.id + ">"; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }, { + key: "isPrivate", + get: function get() { + return false; + } + }, { + key: "users", + get: function get() { + return this.server.members; + } + }, { + key: "members", + get: function get() { + return this.server.members; + } + }]); + + return Channel; +})(); + +module.exports = Channel; + +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; + +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; + +},{}],7:[function(require,module,exports){ +"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 PMChannel = require("./PMChannel.js"); + +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } + }]); + + return Message; +})(); + +module.exports = Message; + +},{"./PMChannel.js":3}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }, { + key: "users", + get: function get() { + return this.members; + } + }]); + + return Server; +})(); + +module.exports = Server; + +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + this.status = "offline"; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; + +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}],15:[function(require,module,exports){ +module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}] +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.3.6.3.js b/web-dist/discord.min.3.6.3.js new file mode 100644 index 000000000..84ac649e8 --- /dev/null +++ b/web-dist/discord.min.3.6.3.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,k=void 0;try{for(var l,m=d.guilds[Symbol.iterator]();!(f=(l=m.next()).done);f=!0)var n=l.value,o=b.addServer(n)}catch(e){h=!0,k=e}finally{try{!f&&m["return"]&&m["return"]()}finally{if(h)throw k}}var p=!0,q=!1,r=void 0;try{for(var s,t=d.private_channels[Symbol.iterator]();!(p=(s=t.next()).done);p=!0){var u=s.value;b.addPMChannel(u)}}catch(e){q=!0,r=e}finally{try{!p&&t["return"]&&t["return"]()}finally{if(q)throw r}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var v=[];d.mentions=d.mentions||[];var w=!0,x=!1,y=void 0;try{for(var z,A=d.mentions[Symbol.iterator]();!(w=(z=A.next()).done);w=!0){var B=z.value;v.push(b.addUser(B))}}catch(e){x=!0,y=e}finally{try{!w&&A["return"]&&A["return"]()}finally{if(x)throw y}}var C=b.getChannel("id",d.channel_id);if(C){var D=C.addMessage(new j(d,C,v,b.addUser(d.author)));b.trigger("message",D)}break;case"MESSAGE_DELETE":b.debug("message deleted");var C=b.getChannel("id",d.channel_id),E=C.getMessage("id",d.id);E?(b.trigger("messageDelete",C,E),C.messages.splice(C.messages.indexOf(E),1)):b.trigger("messageDelete",C);break;case"MESSAGE_UPDATE":b.debug("message updated");var C=b.getChannel("id",d.channel_id),F=C.getMessage("id",d.id);if(F){var G={};for(var H in F)G[H]=F[H];for(var H in d)G[H]=d[H];var v=[],I=!0,J=!1,K=void 0;try{for(var L,M=G.mentions[Symbol.iterator]();!(I=(L=M.next()).done);I=!0){var B=L.value;v.push(b.addUser(B))}}catch(e){J=!0,K=e}finally{try{!I&&M["return"]&&M["return"]()}finally{if(J)throw K}}var N=new j(G,C,v,F.author);b.trigger("messageUpdate",N,F),C.messages[C.messages.indexOf(F)]=N}break;case"GUILD_DELETE":var o=b.getServer("id",d.id);o&&(b.serverCache.splice(b.serverCache.indexOf(o),1),b.trigger("serverDelete",o));break;case"CHANNEL_DELETE":var C=b.getChannel("id",d.id);if(C){var o=C.server;o&&o.channels.splice(o.channels.indexOf(C),1),b.trigger("channelDelete",C),b.serverCache.splice(b.serverCache.indexOf(C),1)}break;case"GUILD_CREATE":var o=b.getServer("id",d.id);if(o||(o=b.addServer(d)),b.serverCreateListener[d.id]){var O=b.serverCreateListener[d.id];O[0](o),O[1](null,o),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",o);break;case"CHANNEL_CREATE":var C=b.getChannel("id",d.id);if(!C){var P=b.addChannel(d,d.guild_id),Q=b.getServer("id",d.guild_id);Q&&Q.addChannel(P),b.trigger("channelCreate",P)}break;case"GUILD_MEMBER_ADD":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)||o.members.push(R),b.trigger("serverNewMember",R,o)}break;case"GUILD_MEMBER_REMOVE":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)&&o.members.splice(o.members.indexOf(R),1),b.trigger("serverRemoveMember",R,o)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var S=new g(d);b.trigger("userUpdate",S,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=S),b.user=S}break;case"PRESENCE_UPDATE":var T=b.getUser("id",d.user.id);if(T){var U=new g(d.user);U.equalsStrict(T)?(T.status=d.status,b.trigger("presence",{user:T,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",T,U),b.userCache[b.userCache.indexOf(T)]=U)}break;case"CHANNEL_UPDATE":var V=b.getChannel("id",d.id),W=b.getServer("id",d.guild_id);if(V&&W){var X=new i(d,W);X.messages=V.messages,b.trigger("channelUpdate",V,X),b.channelCache[b.channelCache.indexOf(V)]=X}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"setTopic",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){var f=!0,k=!1,m=void 0;try{for(var n,o=c.pmChannelCache[Symbol.iterator]();!(f=(n=o.next()).done);f=!0){var p=n.value;if(p.user.equals(a))return void d(p.id)}}catch(q){k=!0,m=q}finally{try{!f&&o["return"]&&o["return"]()}finally{if(k)throw m}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"setStatusIdle",value:function(){this.setStatus("idle")}},{key:"setStatusOnline",value:function(){this.setStatus("online")}},{key:"setStatusActive",value:function(){this.setStatusOnline()}},{key:"setStatusHere",value:function(){this.setStatusOnline()}},{key:"setStatusAway",value:function(){this.setStatusIdle()}},{key:"startTyping",value:function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)}},{key:"stopTyping",value:function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)}},{key:"setStatus",value:function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"setPlayingGame",value:function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;var c=!0,d=!1,e=void 0;try{for(var f,g=m[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h.name.trim().toUpperCase()===b){a=h.id;break}}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"playGame",value:function(a){this.setPlayingGame(a)}},{key:"playingGame",value:function(a){this.setPlayingGame(a)}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null, +this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],15:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[5])(5)}); \ No newline at end of file From 239cb38e4db076b70737851ce9ec22598239e445 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:38:46 +0100 Subject: [PATCH 185/191] 3.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 186f4b624..8da8d52dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.6.3", + "version": "3.7.0", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From eab6837f87d0c8c5b3abd695ca4690e1f55b2151 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:40:45 +0100 Subject: [PATCH 186/191] Updated package.json --- gruntfile.js | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/gruntfile.js b/gruntfile.js index a8972256f..298e8c7c9 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -44,5 +44,6 @@ module.exports = function (grunt) { // register at least this one task grunt.registerTask('default', ['babel']); grunt.registerTask('web', ['browserify', "uglify"]); + grunt.registerTask("dist", ["babel", "browserify", "uglify"]) }; \ No newline at end of file diff --git a/package.json b/package.json index 8da8d52dd..e8621e6d2 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { + "prepublish": "grunt dist" "test": "node ./test/bot.js" }, "repository": { From 70f2dfef3e4ca2010c837ab0d903738802e1e505 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:41:32 +0100 Subject: [PATCH 187/191] Fixed package.json.... --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8621e6d2..3e6e30b09 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { - "prepublish": "grunt dist" + "prepublish": "grunt dist", "test": "node ./test/bot.js" }, "repository": { From 4e15ba1edd3e3c2761862fa11d5f1706e3ff0707 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:41:35 +0100 Subject: [PATCH 188/191] 3.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3e6e30b09..af4e59f4b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.7.0", + "version": "3.7.1", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { From 7361cf3dc36cafae2fd99714e8f8c617e2badb14 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:42:03 +0100 Subject: [PATCH 189/191] 3.7.1 rebuild --- lib/Client.js | 2 +- lib/Endpoints.js | 2 +- lib/Member.js | 2 +- lib/PMChannel.js | 2 +- lib/Permissions.js | 2 +- lib/channel.js | 2 +- lib/index.js | 2 +- lib/internal.js | 2 +- lib/invite.js | 2 +- lib/message.js | 2 +- lib/server.js | 2 +- lib/user.js | 2 +- web-dist/discord.3.7.1.js | 3879 +++++++++++++++++++++++++++++++++ web-dist/discord.min.3.7.1.js | 2 + 14 files changed, 3893 insertions(+), 12 deletions(-) create mode 100644 web-dist/discord.3.7.1.js create mode 100644 web-dist/discord.min.3.7.1.js diff --git a/lib/Client.js b/lib/Client.js index 091424b16..4d097628b 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1925,4 +1925,4 @@ var Client = (function () { return Client; })(); -module.exports = Client; \ No newline at end of file +module.exports = Client; diff --git a/lib/Endpoints.js b/lib/Endpoints.js index 271b465eb..e55f0f580 100644 --- a/lib/Endpoints.js +++ b/lib/Endpoints.js @@ -10,4 +10,4 @@ exports.LOGIN = exports.AUTH + "/login"; exports.LOGOUT = exports.AUTH + "/logout"; exports.USERS = exports.API + "/users"; exports.SERVERS = exports.API + "/guilds"; -exports.CHANNELS = exports.API + "/channels"; \ No newline at end of file +exports.CHANNELS = exports.API + "/channels"; diff --git a/lib/Member.js b/lib/Member.js index 7d7b03f1a..471460e77 100644 --- a/lib/Member.js +++ b/lib/Member.js @@ -18,4 +18,4 @@ var Member = (function (_User) { } return Member; -})(User); \ No newline at end of file +})(User); diff --git a/lib/PMChannel.js b/lib/PMChannel.js index 0dbc0405e..6eb8134de 100644 --- a/lib/PMChannel.js +++ b/lib/PMChannel.js @@ -68,4 +68,4 @@ var PMChannel = (function () { return PMChannel; })(); -module.exports = PMChannel; \ No newline at end of file +module.exports = PMChannel; diff --git a/lib/Permissions.js b/lib/Permissions.js index a1f4f3083..3b7c8f256 100644 --- a/lib/Permissions.js +++ b/lib/Permissions.js @@ -45,4 +45,4 @@ var Permission = (function () { }]); return Permission; -})(); \ No newline at end of file +})(); diff --git a/lib/channel.js b/lib/channel.js index bb67fcf4f..90a2d7428 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -98,4 +98,4 @@ var Channel = (function () { return Channel; })(); -module.exports = Channel; \ No newline at end of file +module.exports = Channel; diff --git a/lib/index.js b/lib/index.js index 6a2f82f05..f0c3c0ab7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -9,4 +9,4 @@ var Discord = { Client: Client }; -module.exports = Discord; \ No newline at end of file +module.exports = Discord; diff --git a/lib/internal.js b/lib/internal.js index 3acf5940b..e8b3385da 100644 --- a/lib/internal.js +++ b/lib/internal.js @@ -200,4 +200,4 @@ Internal.XHR.setUsername = function (token, avatar, email, newPassword, password }); }; -exports.Internal = Internal; \ No newline at end of file +exports.Internal = Internal; diff --git a/lib/invite.js b/lib/invite.js index 5f51dc1a9..7bc8204bd 100644 --- a/lib/invite.js +++ b/lib/invite.js @@ -32,4 +32,4 @@ var Invite = (function () { return Invite; })(); -module.exports = Invite; \ No newline at end of file +module.exports = Invite; diff --git a/lib/message.js b/lib/message.js index 3dd4ddcae..f3f3c574a 100644 --- a/lib/message.js +++ b/lib/message.js @@ -76,4 +76,4 @@ var Message = (function () { return Message; })(); -module.exports = Message; \ No newline at end of file +module.exports = Message; diff --git a/lib/server.js b/lib/server.js index c8758d5da..8bd9332a2 100644 --- a/lib/server.js +++ b/lib/server.js @@ -180,4 +180,4 @@ var Server = (function () { return Server; })(); -module.exports = Server; \ No newline at end of file +module.exports = Server; diff --git a/lib/user.js b/lib/user.js index 5e38e132e..e2b2ca256 100644 --- a/lib/user.js +++ b/lib/user.js @@ -54,4 +54,4 @@ var User = (function () { return User; })(); -module.exports = User; \ No newline at end of file +module.exports = User; diff --git a/web-dist/discord.3.7.1.js b/web-dist/discord.3.7.1.js new file mode 100644 index 000000000..0d9f9341a --- /dev/null +++ b/web-dist/discord.3.7.1.js @@ -0,0 +1,3879 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var mention = _step3.value; + + _mentions.push(mention.substring(2, mention.length - 1)); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return _mentions; + } + }); + + return prom; + } + + //def createws + }, { + key: "createws", + value: function createws(url) { + if (this.websocket) return false; + + var self = this; + + //good to go + this.websocket = new WebSocket(url); + + //open + this.websocket.onopen = function () { + self.trySendConnData(); //try connecting + }; + + //close + this.websocket.onclose = function () { + self.trigger("disconnected"); + }; + + //message + this.websocket.onmessage = function (e) { + + var dat = false, + data = {}; + + try { + dat = JSON.parse(e.data); + data = dat.d; + } catch (err) { + self.trigger("error", err, e); + return; + } + + self.trigger("raw", dat); + + //valid message + switch (dat.t) { + + case "READY": + self.debug("received ready packet"); + + self.user = self.addUser(data.user); + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _server = _step4.value; + + var server = self.addServer(_server); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4["return"]) { + _iterator4["return"](); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var _pmc = _step5.value; + + var pmc = self.addPMChannel(_pmc); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5["return"]) { + _iterator5["return"](); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + self.trigger("ready"); + self.readyTime = Date.now(); + self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users."); + self.state = 3; + setInterval(function () { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + break; + case "MESSAGE_CREATE": + self.debug("received message"); + + var mentions = []; + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var mention = _step6.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6["return"]) { + _iterator6["return"](); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + self.trigger("message", msg); + } + + break; + case "MESSAGE_DELETE": + self.debug("message deleted"); + + var channel = self.getChannel("id", data.channel_id); + var message = channel.getMessage("id", data.id); + if (message) { + self.trigger("messageDelete", channel, message); + channel.messages.splice(channel.messages.indexOf(message), 1); + } else { + //don't have the cache of that message ;( + self.trigger("messageDelete", channel); + } + break; + case "MESSAGE_UPDATE": + self.debug("message updated"); + + var channel = self.getChannel("id", data.channel_id); + var formerMessage = channel.getMessage("id", data.id); + + if (formerMessage) { + + //new message might be partial, so we need to fill it with whatever the old message was. + var info = {}; + + for (var key in formerMessage) { + info[key] = formerMessage[key]; + } + + for (var key in data) { + info[key] = data[key]; + } + + var mentions = []; + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var mention = _step7.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7["return"]) { + _iterator7["return"](); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + var newMessage = new Message(info, channel, mentions, formerMessage.author); + + self.trigger("messageUpdate", newMessage, formerMessage); + + channel.messages[channel.messages.indexOf(formerMessage)] = newMessage; + } + + // message isn't in cache, and if it's a partial it could cause + // all hell to break loose... best to just act as if nothing happened + + break; + + case "GUILD_DELETE": + + var server = self.getServer("id", data.id); + + if (server) { + self.serverCache.splice(self.serverCache.indexOf(server), 1); + self.trigger("serverDelete", server); + } + + break; + + case "CHANNEL_DELETE": + + var channel = self.getChannel("id", data.id); + + if (channel) { + + var server = channel.server; + + if (server) { + + server.channels.splice(server.channels.indexOf(channel), 1); + } + + self.trigger("channelDelete", channel); + + self.serverCache.splice(self.serverCache.indexOf(channel), 1); + } + + break; + + case "GUILD_CREATE": + + var server = self.getServer("id", data.id); + + if (!server) { + //if server doesn't already exist because duh + server = self.addServer(data); + } /*else if(server.channels.length === 0){ + + var srv = new Server(data, self); + for(channel of data.channels){ + srv.channels.push(new Channel(channel, data.id)); + } + self.serverCache[self.serverCache.indexOf(server)] = srv; + + }*/ + + if (self.serverCreateListener[data.id]) { + var cbs = self.serverCreateListener[data.id]; + cbs[0](server); //promise then callback + cbs[1](null, server); //legacy callback + self.serverCreateListener[data.id] = null; + } + + self.trigger("serverCreate", server); + + break; + + case "CHANNEL_CREATE": + + var channel = self.getChannel("id", data.id); + + if (!channel) { + + var chann = self.addChannel(data, data.guild_id); + var srv = self.getServer("id", data.guild_id); + if (srv) { + srv.addChannel(chann); + } + self.trigger("channelCreate", chann); + } + + break; + + case "GUILD_MEMBER_ADD": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (! ~server.members.indexOf(user)) { + server.members.push(user); + } + + self.trigger("serverNewMember", user, server); + } + + break; + + case "GUILD_MEMBER_REMOVE": + + var server = self.getServer("id", data.guild_id); + + if (server) { + + var user = self.addUser(data.user); //if for whatever reason it doesn't exist.. + + if (~server.members.indexOf(user)) { + server.members.splice(server.members.indexOf(user), 1); + } + + self.trigger("serverRemoveMember", user, server); + } + + break; + + case "USER_UPDATE": + + if (self.user && data.id === self.user.id) { + + var newUser = new User(data); //not actually adding to the cache + + self.trigger("userUpdate", newUser, self.user); + + if (~self.userCache.indexOf(self.user)) { + self.userCache[self.userCache.indexOf(self.user)] = newUser; + } + + self.user = newUser; + } + + break; + + case "PRESENCE_UPDATE": + + var userInCache = self.getUser("id", data.user.id); + + if (userInCache) { + //user exists + var presenceUser = new User(data.user); + if (presenceUser.equalsStrict(userInCache)) { + //they're exactly the same, an actual presence update + userInCache.status = data.status; + self.trigger("presence", { + user: userInCache, + status: data.status, + server: self.getServer("id", data.guild_id), + gameId: data.game_id + }); + } else { + //one of their details changed. + self.trigger("userUpdate", userInCache, presenceUser); + self.userCache[self.userCache.indexOf(userInCache)] = presenceUser; + } + } + + break; + + case "CHANNEL_UPDATE": + + var channelInCache = self.getChannel("id", data.id), + serverInCache = self.getServer("id", data.guild_id); + + if (channelInCache && serverInCache) { + + var newChann = new Channel(data, serverInCache); + newChann.messages = channelInCache.messages; + + self.trigger("channelUpdate", channelInCache, newChann); + + self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann; + } + + break; + + default: + self.debug("received unknown packet"); + self.trigger("unknown", dat); + break; + + } + }; + } + + //def addUser + }, { + key: "addUser", + value: function addUser(data) { + if (!this.getUser("id", data.id)) { + this.userCache.push(new User(data)); + } + return this.getUser("id", data.id); + } + + //def addChannel + }, { + key: "addChannel", + value: function addChannel(data, serverId) { + if (!this.getChannel("id", data.id)) { + this.channelCache.push(new Channel(data, this.getServer("id", serverId))); + } + return this.getChannel("id", data.id); + } + }, { + key: "addPMChannel", + value: function addPMChannel(data) { + if (!this.getPMChannel("id", data.id)) { + this.pmChannelCache.push(new PMChannel(data, this)); + } + return this.getPMChannel("id", data.id); + } + }, { + key: "setTopic", + value: function setTopic(channel, topic) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + self.resolveDestination(channel).then(next)["catch"](error); + + function error(e) { + callback(e); + reject(e); + } + + function next(destination) { + + var asChan = self.getChannel("id", destination); + + request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({ + name: asChan.name, + position: 0, + topic: topic + }).end(function (err, res) { + if (err) { + error(err); + } else { + asChan.topic = res.body.topic; + resolve(); + callback(); + } + }); + } + }); + } + + //def addServer + }, { + key: "addServer", + value: function addServer(data) { + + var self = this; + var server = this.getServer("id", data.id); + + if (data.unavailable) { + self.trigger("unavailable", data); + self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached."); + return; + } + + if (!server) { + server = new Server(data, this); + this.serverCache.push(server); + if (data.channels) { + var _iteratorNormalCompletion8 = true; + var _didIteratorError8 = false; + var _iteratorError8 = undefined; + + try { + for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { + var channel = _step8.value; + + server.channels.push(this.addChannel(channel, server.id)); + } + } catch (err) { + _didIteratorError8 = true; + _iteratorError8 = err; + } finally { + try { + if (!_iteratorNormalCompletion8 && _iterator8["return"]) { + _iterator8["return"](); + } + } finally { + if (_didIteratorError8) { + throw _iteratorError8; + } + } + } + } + } + + var _iteratorNormalCompletion9 = true; + var _didIteratorError9 = false; + var _iteratorError9 = undefined; + + try { + for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { + var presence = _step9.value; + + self.getUser("id", presence.user.id).status = presence.status; + } + } catch (err) { + _didIteratorError9 = true; + _iteratorError9 = err; + } finally { + try { + if (!_iteratorNormalCompletion9 && _iterator9["return"]) { + _iterator9["return"](); + } + } finally { + if (_didIteratorError9) { + throw _iteratorError9; + } + } + } + + return server; + } + + //def getUser + }, { + key: "getUser", + value: function getUser(key, value) { + var _iteratorNormalCompletion10 = true; + var _didIteratorError10 = false; + var _iteratorError10 = undefined; + + try { + for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { + var user = _step10.value; + + if (user[key] === value) { + return user; + } + } + } catch (err) { + _didIteratorError10 = true; + _iteratorError10 = err; + } finally { + try { + if (!_iteratorNormalCompletion10 && _iterator10["return"]) { + _iterator10["return"](); + } + } finally { + if (_didIteratorError10) { + throw _iteratorError10; + } + } + } + + return null; + } + + //def getChannel + }, { + key: "getChannel", + value: function getChannel(key, value) { + var _iteratorNormalCompletion11 = true; + var _didIteratorError11 = false; + var _iteratorError11 = undefined; + + try { + for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { + var channel = _step11.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError11 = true; + _iteratorError11 = err; + } finally { + try { + if (!_iteratorNormalCompletion11 && _iterator11["return"]) { + _iterator11["return"](); + } + } finally { + if (_didIteratorError11) { + throw _iteratorError11; + } + } + } + + return this.getPMChannel(key, value); //might be a PM + } + }, { + key: "getPMChannel", + value: function getPMChannel(key, value) { + var _iteratorNormalCompletion12 = true; + var _didIteratorError12 = false; + var _iteratorError12 = undefined; + + try { + for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { + var channel = _step12.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError12 = true; + _iteratorError12 = err; + } finally { + try { + if (!_iteratorNormalCompletion12 && _iterator12["return"]) { + _iterator12["return"](); + } + } finally { + if (_didIteratorError12) { + throw _iteratorError12; + } + } + } + + return null; + } + + //def getServer + }, { + key: "getServer", + value: function getServer(key, value) { + var _iteratorNormalCompletion13 = true; + var _didIteratorError13 = false; + var _iteratorError13 = undefined; + + try { + for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { + var server = _step13.value; + + if (server[key] === value) { + return server; + } + } + } catch (err) { + _didIteratorError13 = true; + _iteratorError13 = err; + } finally { + try { + if (!_iteratorNormalCompletion13 && _iterator13["return"]) { + _iterator13["return"](); + } + } finally { + if (_didIteratorError13) { + throw _iteratorError13; + } + } + } + + return null; + } + + //def trySendConnData + }, { + key: "trySendConnData", + value: function trySendConnData() { + + if (this.token && !this.alreadySentData) { + + this.alreadySentData = true; + + var data = { + op: 2, + d: { + token: this.token, + v: 3, + properties: { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + } + } + }; + this.websocket.send(JSON.stringify(data)); + } + } + }, { + key: "resolveServerID", + value: function resolveServerID(resource) { + + if (resource instanceof Server) { + return resource.id; + } else if (!isNaN(resource) && resource.length && resource.length === 17) { + return resource; + } + } + }, { + key: "resolveDestination", + value: function resolveDestination(destination) { + var channId = false; + var self = this; + + return new Promise(function (resolve, reject) { + if (destination instanceof Server) { + channId = destination.id; //general is the same as server id + } else if (destination instanceof Channel) { + channId = destination.id; + } else if (destination instanceof Message) { + channId = destination.channel.id; + } else if (destination instanceof PMChannel) { + channId = destination.id; + } else if (destination instanceof User) { + + //check if we have a PM + var _iteratorNormalCompletion14 = true; + var _didIteratorError14 = false; + var _iteratorError14 = undefined; + + try { + for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { + var pmc = _step14.value; + + if (pmc.user.equals(destination)) { + resolve(pmc.id); + return; + } + } + + //we don't, at this point we're late + } catch (err) { + _didIteratorError14 = true; + _iteratorError14 = err; + } finally { + try { + if (!_iteratorNormalCompletion14 && _iterator14["return"]) { + _iterator14["return"](); + } + } finally { + if (_didIteratorError14) { + throw _iteratorError14; + } + } + } + + self.startPM(destination).then(function (pmc) { + resolve(pmc.id); + })["catch"](reject); + } else { + channId = destination; + } + if (channId) resolve(channId);else reject(); + }); + } + }, { + key: "_sendMessage", + value: function _sendMessage(destination, content, tts, mentions) { + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({ + content: content, + mentions: mentions, + tts: tts + }).end(function (err, res) { + + if (err) { + reject(err); + } else { + var data = res.body; + + var mentions = []; + + data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var _iteratorNormalCompletion15 = true; + var _didIteratorError15 = false; + var _iteratorError15 = undefined; + + try { + for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { + var mention = _step15.value; + + mentions.push(self.addUser(mention)); + } + } catch (err) { + _didIteratorError15 = true; + _iteratorError15 = err; + } finally { + try { + if (!_iteratorNormalCompletion15 && _iterator15["return"]) { + _iterator15["return"](); + } + } finally { + if (_didIteratorError15) { + throw _iteratorError15; + } + } + } + + var channel = self.getChannel("id", data.channel_id); + if (channel) { + var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_sendFile", + value: function _sendFile(destination, attachment) { + var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) { + + if (err) { + reject(err); + } else { + + var chann = self.getChannel("id", destination); + if (chann) { + var msg = chann.addMessage(new Message(res.body, chann, [], self.user)); + resolve(msg); + } + } + }); + }); + } + }, { + key: "_updateMessage", + value: function _updateMessage(message, content) { + var self = this; + return new Promise(function (resolve, reject) { + request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({ + content: content, + mentions: [] + }).end(function (err, res) { + if (err) { + reject(err); + } else { + var msg = new Message(res.body, message.channel, message.mentions, message.sender); + resolve(msg); + message.channel.messages[message.channel.messages.indexOf(message)] = msg; + } + }); + }); + } + }, { + key: "_deleteMessage", + value: function _deleteMessage(message) { + var self = this; + return new Promise(function (resolve, reject) { + + request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + }, { + key: "checkQueue", + value: function checkQueue(channelID) { + var _this = this; + + var self = this; + + if (!this.checkingQueue[channelID]) { + (function () { + var doNext = function doNext() { + if (self.queue[channelID].length === 0) { + done(); + return; + } + var queuedEvent = self.queue[channelID][0]; + switch (queuedEvent.action) { + case "sendMessage": + var msgToSend = queuedEvent; + self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) { + msgToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "sendFile": + var fileToSend = queuedEvent; + self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) { + fileToSend.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + fileToSend.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "updateMessage": + var msgToUpd = queuedEvent; + self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) { + msgToUpd.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToUpd.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + case "deleteMessage": + var msgToDel = queuedEvent; + self._deleteMessage(msgToDel.message).then(function (msg) { + msgToDel.then(msg); + self.queue[channelID].shift(); + doNext(); + })["catch"](function (err) { + msgToDel.error(err); + self.queue[channelID].shift(); + doNext(); + }); + break; + default: + done(); + break; + } + }; + + var done = function done() { + self.checkingQueue[channelID] = false; + return; + }; + + //if we aren't already checking this queue. + _this.checkingQueue[channelID] = true; + doNext(); + })(); + } + } + }, { + key: "getGateway", + value: function getGateway() { + var self = this; + return new Promise(function (resolve, reject) { + request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) { + if (err) { + reject(err); + } else { + resolve(res.body.url); + } + }); + }); + } + }, { + key: "setStatusIdle", + value: function setStatusIdle() { + this.setStatus("idle"); + } + }, { + key: "setStatusOnline", + value: function setStatusOnline() { + this.setStatus("online"); + } + }, { + key: "setStatusActive", + value: function setStatusActive() { + this.setStatusOnline(); + } + }, { + key: "setStatusHere", + value: function setStatusHere() { + this.setStatusOnline(); + } + }, { + key: "setStatusAway", + value: function setStatusAway() { + this.setStatusIdle(); + } + }, { + key: "startTyping", + value: function startTyping(chann, stopTypeTime) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (self.typingIntervals[channel]) { + return; + } + + var fn = function fn() { + request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end(); + }; + + fn(); + + var interval = setInterval(fn, 3000); + + self.typingIntervals[channel] = interval; + + if (stopTypeTime) { + setTimeout(function () { + self.stopTyping(channel); + }, stopTypeTime); + } + } + } + }, { + key: "stopTyping", + value: function stopTyping(chann) { + var self = this; + + this.resolveDestination(chann).then(next); + + function next(channel) { + if (!self.typingIntervals[channel]) { + return; + } + + clearInterval(self.typingIntervals[channel]); + + delete self.typingIntervals[channel]; + } + } + }, { + key: "setStatus", + value: function setStatus(stat) { + + var idleTime = stat === "online" ? null : Date.now(); + + this.__idleTime = idleTime; + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: this.__idleTime, + game_id: this.__gameId + } + })); + } + }, { + key: "setPlayingGame", + value: function setPlayingGame(id) { + + if (id instanceof String || typeof id === "string") { + + // working on names + var gid = id.trim().toUpperCase(); + + id = null; + + var _iteratorNormalCompletion16 = true; + var _didIteratorError16 = false; + var _iteratorError16 = undefined; + + try { + for (var _iterator16 = gameMap[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { + var game = _step16.value; + + if (game.name.trim().toUpperCase() === gid) { + + id = game.id; + break; + } + } + } catch (err) { + _didIteratorError16 = true; + _iteratorError16 = err; + } finally { + try { + if (!_iteratorNormalCompletion16 && _iterator16["return"]) { + _iterator16["return"](); + } + } finally { + if (_didIteratorError16) { + throw _iteratorError16; + } + } + } + } + + this.__gameId = id; + + this.websocket.send(JSON.stringify({ + op: 3, + d: { + idle_since: this.__idleTime, + game_id: this.__gameId + } + })); + } + }, { + key: "playGame", + value: function playGame(id) { + this.setPlayingGame(id); + } + }, { + key: "playingGame", + value: function playingGame(id) { + + this.setPlayingGame(id); + } + }, { + key: "uptime", + get: function get() { + + return this.readyTime ? Date.now() - this.readyTime : null; + } + }, { + key: "ready", + get: function get() { + return this.state === 3; + } + }, { + key: "servers", + get: function get() { + return this.serverCache; + } + }, { + key: "channels", + get: function get() { + return this.channelCache; + } + }, { + key: "users", + get: function get() { + return this.userCache; + } + }, { + key: "PMChannels", + get: function get() { + return this.pmChannelCache; + } + }, { + key: "messages", + get: function get() { + + var msgs = []; + var _iteratorNormalCompletion17 = true; + var _didIteratorError17 = false; + var _iteratorError17 = undefined; + + try { + for (var _iterator17 = this.channelCache[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { + var channel = _step17.value; + + msgs = msgs.concat(channel.messages); + } + } catch (err) { + _didIteratorError17 = true; + _iteratorError17 = err; + } finally { + try { + if (!_iteratorNormalCompletion17 && _iterator17["return"]) { + _iterator17["return"](); + } + } finally { + if (_didIteratorError17) { + throw _iteratorError17; + } + } + } + + return msgs; + } + }]); + + return Client; +})(); + +module.exports = Client; + +},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){ +"use strict"; + +exports.BASE_DOMAIN = "discordapp.com"; +exports.BASE = "https://" + exports.BASE_DOMAIN; +exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub"; + +exports.API = exports.BASE + "/api"; +exports.AUTH = exports.API + "/auth"; +exports.LOGIN = exports.AUTH + "/login"; +exports.LOGOUT = exports.AUTH + "/logout"; +exports.USERS = exports.API + "/users"; +exports.SERVERS = exports.API + "/guilds"; +exports.CHANNELS = exports.API + "/channels"; + +},{}],3:[function(require,module,exports){ +"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 PMChannel = (function () { + function PMChannel(data, client) { + _classCallCheck(this, PMChannel); + + this.user = client.getUser("id", data.recipient.id); + this.id = data.id; + this.messages = []; + } + + _createClass(PMChannel, [{ + key: "addMessage", + value: function addMessage(data) { + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "isPrivate", + get: function get() { + return true; + } + }]); + + return PMChannel; +})(); + +module.exports = PMChannel; + +},{}],4:[function(require,module,exports){ +"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 Channel = (function () { + function Channel(data, server) { + _classCallCheck(this, Channel); + + this.server = server; + this.name = data.name; + this.type = data.type; + this.topic = data.topic; + this.id = data.id; + this.messages = []; + //this.isPrivate = isPrivate; //not sure about the implementation of this... + } + + _createClass(Channel, [{ + key: "equals", + value: function equals(object) { + return object && object.id === this.id; + } + }, { + key: "addMessage", + value: function addMessage(data) { + + if (this.messages.length > 1000) { + this.messages.splice(0, 1); + } + + if (!this.getMessage("id", data.id)) { + this.messages.push(data); + } + + return this.getMessage("id", data.id); + } + }, { + key: "getMessage", + value: function getMessage(key, value) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var message = _step.value; + + if (message[key] === value) { + return message; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return null; + } + }, { + key: "toString", + value: function toString() { + return "<#" + this.id + ">"; + } + }, { + key: "client", + get: function get() { + return this.server.client; + } + }, { + key: "isPrivate", + get: function get() { + return false; + } + }, { + key: "users", + get: function get() { + return this.server.members; + } + }, { + key: "members", + get: function get() { + return this.server.members; + } + }]); + + return Channel; +})(); + +module.exports = Channel; + +},{}],5:[function(require,module,exports){ +"use strict"; + +var request = require("superagent"); +var Endpoints = require("./Endpoints.js"); +var Client = require("./Client.js"); + +var Discord = { + Endpoints: Endpoints, + Client: Client +}; + +module.exports = Discord; + +},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){ +"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 Invite = (function () { + function Invite(data, client) { + _classCallCheck(this, Invite); + + this.max_age = data.max_age; + this.code = data.code; + this.server = client.getServer("id", data.guild.id); + this.revoked = data.revoked; + this.created_at = Date.parse(data.created_at); + this.temporary = data.temporary; + this.uses = data.uses; + this.max_uses = data.uses; + this.inviter = client.addUser(data.inviter); + this.xkcd = data.xkcdpass; + this.channel = client.getChannel("id", data.channel.id); + } + + _createClass(Invite, [{ + key: "URL", + get: function get() { + var code = this.xkcd ? this.xkcdpass : this.code; + return "https://discord.gg/" + code; + } + }]); + + return Invite; +})(); + +module.exports = Invite; + +},{}],7:[function(require,module,exports){ +"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 PMChannel = require("./PMChannel.js"); + +var Message = (function () { + function Message(data, channel, mentions, author) { + _classCallCheck(this, Message); + + this.tts = data.tts; + this.timestamp = Date.parse(data.timestamp); + this.nonce = data.nonce; + this.mentions = mentions; + this.everyoneMentioned = data.mention_everyone; + this.id = data.id; + this.embeds = data.embeds; + this.editedTimestamp = data.edited_timestamp; + this.content = data.content.trim(); + this.channel = channel; + this.author = author; + this.attachments = data.attachments; + } + + /*exports.Message.prototype.isPM = function() { + return ( this.channel instanceof PMChannel ); + }*/ + + _createClass(Message, [{ + key: "isMentioned", + value: function isMentioned(user) { + var id = user.id ? user.id : user; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var mention = _step.value; + + if (mention.id === id) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } + }, { + key: "sender", + get: function get() { + return this.author; + } + }, { + key: "isPrivate", + get: function get() { + return this.channel.isPrivate; + } + }]); + + return Message; +})(); + +module.exports = Message; + +},{"./PMChannel.js":3}],8:[function(require,module,exports){ +"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 Server = (function () { + function Server(data, client) { + _classCallCheck(this, Server); + + this.client = client; + this.region = data.region; + this.ownerID = data.owner_id; + this.name = data.name; + this.id = data.id; + this.members = []; + this.channels = []; + this.icon = data.icon; + this.afkTimeout = data.afk_timeout; + this.afkChannelId = data.afk_channel_id; + + if (!data.members) { + data.members = [client.user]; + return; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var member = _step.value; + + // first we cache the user in our Discord Client, + // then we add it to our list. This way when we + // get a user from this server's member list, + // it will be identical (unless an async change occurred) + // to the client's cache. + if (member.user) this.members.push(client.addUser(member.user)); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator["return"]) { + _iterator["return"](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + _createClass(Server, [{ + key: "getChannel", + + // get/set + value: function getChannel(key, value) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var channel = _step2.value; + + if (channel[key] === value) { + return channel; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2["return"]) { + _iterator2["return"](); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return null; + } + }, { + key: "getMember", + value: function getMember(key, value) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var member = _step3.value; + + if (member[key] === value) { + return member; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3["return"]) { + _iterator3["return"](); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return null; + } + }, { + key: "addChannel", + value: function addChannel(chann) { + if (!this.getChannel("id", chann.id)) { + this.channels.push(chann); + } + return chann; + } + }, { + key: "addMember", + value: function addMember(member) { + if (!this.getMember("id", member.id)) { + this.members.push(member); + } + return member; + } + }, { + key: "toString", + value: function toString() { + return this.name; + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "iconURL", + get: function get() { + if (!this.icon) return null; + return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg"; + } + }, { + key: "afkChannel", + get: function get() { + if (!this.afkChannelId) return false; + + return this.getChannel("id", this.afkChannelId); + } + }, { + key: "defaultChannel", + get: function get() { + return this.getChannel("name", "general"); + } + }, { + key: "owner", + get: function get() { + return this.client.getUser("id", this.ownerID); + } + }, { + key: "users", + get: function get() { + return this.members; + } + }]); + + return Server; +})(); + +module.exports = Server; + +},{}],9:[function(require,module,exports){ +"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 User = (function () { + function User(data) { + _classCallCheck(this, User); + + this.username = data.username; + this.discriminator = data.discriminator; + this.id = data.id; + this.avatar = data.avatar; + this.status = "offline"; + } + + // access using user.avatarURL; + + _createClass(User, [{ + key: "mention", + value: function mention() { + return "<@" + this.id + ">"; + } + }, { + key: "toString", + value: function toString() { + /* + if we embed a user in a String - like so: + "Yo " + user + " what's up?" + It would generate something along the lines of: + "Yo @hydrabolt what's up?" + */ + return this.mention(); + } + }, { + key: "equals", + value: function equals(object) { + return object.id === this.id; + } + }, { + key: "equalsStrict", + value: function equalsStrict(object) { + return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator; + } + }, { + key: "avatarURL", + get: function get() { + if (!this.avatar) return null; + return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg"; + } + }]); + + return User; +})(); + +module.exports = User; + +},{}],10:[function(require,module,exports){ + +},{}],11:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); + +/** + * Root reference for iframes. + */ + +var root = 'undefined' == typeof window + ? (this || self) + : window; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj === Object(obj); +} + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(obj[key])); + } + } + return pairs.join('&'); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var parts; + var pair; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + parts = pair.split('='); + obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this.setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this.setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this.parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype.setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype.parseBody = function(str){ + var parse = request.parse[this.type]; + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype.setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + Emitter.call(this); + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; + this._header = {}; + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}) + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + xhr.send(data); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.del = function(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":12,"reduce":13}],12:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],13:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var global = (function() { return this; })(); + +/** + * WebSocket constructor. + */ + +var WebSocket = global.WebSocket || global.MozWebSocket; + +/** + * Module exports. + */ + +module.exports = WebSocket ? ws : null; + +/** + * WebSocket constructor. + * + * The third `opts` options object gets ignored in web browsers, since it's + * non-standard, and throws a TypeError if passed to the constructor. + * See: https://github.com/einaros/ws/issues/227 + * + * @param {String} uri + * @param {Array} protocols (optional) + * @param {Object) opts (optional) + * @api public + */ + +function ws(uri, protocols, opts) { + var instance; + if (protocols) { + instance = new WebSocket(uri, protocols); + } else { + instance = new WebSocket(uri); + } + return instance; +} + +if (WebSocket) ws.prototype = WebSocket.prototype; + +},{}],15:[function(require,module,exports){ +module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}] +},{}]},{},[5])(5) +}); \ No newline at end of file diff --git a/web-dist/discord.min.3.7.1.js b/web-dist/discord.min.3.7.1.js new file mode 100644 index 000000000..84ac649e8 --- /dev/null +++ b/web-dist/discord.min.3.7.1.js @@ -0,0 +1,2 @@ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,k=void 0;try{for(var l,m=d.guilds[Symbol.iterator]();!(f=(l=m.next()).done);f=!0)var n=l.value,o=b.addServer(n)}catch(e){h=!0,k=e}finally{try{!f&&m["return"]&&m["return"]()}finally{if(h)throw k}}var p=!0,q=!1,r=void 0;try{for(var s,t=d.private_channels[Symbol.iterator]();!(p=(s=t.next()).done);p=!0){var u=s.value;b.addPMChannel(u)}}catch(e){q=!0,r=e}finally{try{!p&&t["return"]&&t["return"]()}finally{if(q)throw r}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var v=[];d.mentions=d.mentions||[];var w=!0,x=!1,y=void 0;try{for(var z,A=d.mentions[Symbol.iterator]();!(w=(z=A.next()).done);w=!0){var B=z.value;v.push(b.addUser(B))}}catch(e){x=!0,y=e}finally{try{!w&&A["return"]&&A["return"]()}finally{if(x)throw y}}var C=b.getChannel("id",d.channel_id);if(C){var D=C.addMessage(new j(d,C,v,b.addUser(d.author)));b.trigger("message",D)}break;case"MESSAGE_DELETE":b.debug("message deleted");var C=b.getChannel("id",d.channel_id),E=C.getMessage("id",d.id);E?(b.trigger("messageDelete",C,E),C.messages.splice(C.messages.indexOf(E),1)):b.trigger("messageDelete",C);break;case"MESSAGE_UPDATE":b.debug("message updated");var C=b.getChannel("id",d.channel_id),F=C.getMessage("id",d.id);if(F){var G={};for(var H in F)G[H]=F[H];for(var H in d)G[H]=d[H];var v=[],I=!0,J=!1,K=void 0;try{for(var L,M=G.mentions[Symbol.iterator]();!(I=(L=M.next()).done);I=!0){var B=L.value;v.push(b.addUser(B))}}catch(e){J=!0,K=e}finally{try{!I&&M["return"]&&M["return"]()}finally{if(J)throw K}}var N=new j(G,C,v,F.author);b.trigger("messageUpdate",N,F),C.messages[C.messages.indexOf(F)]=N}break;case"GUILD_DELETE":var o=b.getServer("id",d.id);o&&(b.serverCache.splice(b.serverCache.indexOf(o),1),b.trigger("serverDelete",o));break;case"CHANNEL_DELETE":var C=b.getChannel("id",d.id);if(C){var o=C.server;o&&o.channels.splice(o.channels.indexOf(C),1),b.trigger("channelDelete",C),b.serverCache.splice(b.serverCache.indexOf(C),1)}break;case"GUILD_CREATE":var o=b.getServer("id",d.id);if(o||(o=b.addServer(d)),b.serverCreateListener[d.id]){var O=b.serverCreateListener[d.id];O[0](o),O[1](null,o),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",o);break;case"CHANNEL_CREATE":var C=b.getChannel("id",d.id);if(!C){var P=b.addChannel(d,d.guild_id),Q=b.getServer("id",d.guild_id);Q&&Q.addChannel(P),b.trigger("channelCreate",P)}break;case"GUILD_MEMBER_ADD":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)||o.members.push(R),b.trigger("serverNewMember",R,o)}break;case"GUILD_MEMBER_REMOVE":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)&&o.members.splice(o.members.indexOf(R),1),b.trigger("serverRemoveMember",R,o)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var S=new g(d);b.trigger("userUpdate",S,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=S),b.user=S}break;case"PRESENCE_UPDATE":var T=b.getUser("id",d.user.id);if(T){var U=new g(d.user);U.equalsStrict(T)?(T.status=d.status,b.trigger("presence",{user:T,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",T,U),b.userCache[b.userCache.indexOf(T)]=U)}break;case"CHANNEL_UPDATE":var V=b.getChannel("id",d.id),W=b.getServer("id",d.guild_id);if(V&&W){var X=new i(d,W);X.messages=V.messages,b.trigger("channelUpdate",V,X),b.channelCache[b.channelCache.indexOf(V)]=X}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"setTopic",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){var f=!0,k=!1,m=void 0;try{for(var n,o=c.pmChannelCache[Symbol.iterator]();!(f=(n=o.next()).done);f=!0){var p=n.value;if(p.user.equals(a))return void d(p.id)}}catch(q){k=!0,m=q}finally{try{!f&&o["return"]&&o["return"]()}finally{if(k)throw m}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"setStatusIdle",value:function(){this.setStatus("idle")}},{key:"setStatusOnline",value:function(){this.setStatus("online")}},{key:"setStatusActive",value:function(){this.setStatusOnline()}},{key:"setStatusHere",value:function(){this.setStatusOnline()}},{key:"setStatusAway",value:function(){this.setStatusIdle()}},{key:"startTyping",value:function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)}},{key:"stopTyping",value:function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)}},{key:"setStatus",value:function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"setPlayingGame",value:function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;var c=!0,d=!1,e=void 0;try{for(var f,g=m[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h.name.trim().toUpperCase()===b){a=h.id;break}}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"playGame",value:function(a){this.setPlayingGame(a)}},{key:"playingGame",value:function(a){this.setPlayingGame(a)}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null, +this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],15:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[5])(5)}); \ No newline at end of file From 87901b7643fffc5b8c97defa145e1bf8006b81ee Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:46:16 +0100 Subject: [PATCH 190/191] Are you happy yet travis build >_> --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index af4e59f4b..35c83aa5d 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": { - "prepublish": "grunt dist", "test": "node ./test/bot.js" }, "repository": { From 4c913902173d1732cf2fa4b168163fc2c813143e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Fri, 2 Oct 2015 21:48:02 +0100 Subject: [PATCH 191/191] 3.7.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35c83aa5d..74c1b4766 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord.js", - "version": "3.7.1", + "version": "3.7.2", "description": "A way to interface with the Discord API", "main": "./lib/index.js", "scripts": {