From 35b61312b9b173b98da29b66becb0fd0f5dca8fd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 16:55:23 +0100 Subject: [PATCH 01/71] 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 02/71] 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 03/71] 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 04/71] 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 05/71] 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 06/71] 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 07/71] 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 08/71] 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 09/71] 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 10/71] 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 11/71] 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 12/71] 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 13/71] 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 14/71] 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 15/71] 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 16/71] 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 17/71] 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 18/71] 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 19/71] 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 20/71] 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 21/71] 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 22/71] 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 23/71] 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 24/71] 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 25/71] 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 26/71] 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 27/71] 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 28/71] 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 29/71] 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 30/71] 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 31/71] 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 32/71] 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 33/71] 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 34/71] 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 35/71] 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 36/71] 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 37/71] 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 38/71] 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 39/71] 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 40/71] 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 41/71] 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 42/71] 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 43/71] 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 44/71] 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 45/71] 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 46/71] 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 47/71] 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 48/71] 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 49/71] 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 50/71] 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 51/71] 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 52/71] 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 53/71] 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 54/71] 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 55/71] 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 56/71] 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 57/71] 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 58/71] 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 59/71] 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 60/71] 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 61/71] 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 62/71] 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 63/71] 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 64/71] 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 65/71] 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 66/71] 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 67/71] 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 68/71] 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 69/71] 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 70/71] 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 71/71] 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