From 35b61312b9b173b98da29b66becb0fd0f5dca8fd Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 16:55:23 +0100 Subject: [PATCH 01/34] 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/34] 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/34] 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/34] 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/34] 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/34] 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/34] 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 31a0cba0d1ae00de2ed3ef54e97a8a951fcf7d7e Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 23 Aug 2015 22:12:07 +0100 Subject: [PATCH 08/34] 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 09/34] 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 10/34] 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 11/34] 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 12/34] 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 13/34] 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 14/34] 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 15/34] 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 16/34] 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 17/34] 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 18/34] 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 19/34] 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 20/34] 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 21/34] 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 22/34] 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 23/34] 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 24/34] 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 25/34] 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 26/34] 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 27/34] 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 28/34] 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 29/34] 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 30/34] 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 31/34] 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 32/34] 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 33/34] 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 34/34] 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)