Added User Class

This commit is contained in:
hydrabolt
2015-08-23 19:33:52 +01:00
parent a9bd6cd59c
commit 344f8d73a4
11 changed files with 320 additions and 262 deletions

View File

@@ -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));
}
}
}, {
@@ -61,3 +196,5 @@ var Client = (function () {
return Client;
})();
module.exports = Client;

View File

@@ -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";

View File

@@ -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;
exports.Client = Client;

View File

@@ -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);

View File

@@ -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";
};
exports.User.prototype.mention = function () {
_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.equals = function (otherUser) {
return User;
})();
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;

View File

@@ -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,9 +99,57 @@ 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
@@ -114,3 +178,5 @@ class Client {
}
}
module.exports = Client;

View File

@@ -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`;

View File

@@ -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;
exports.Client = Client;

View File

@@ -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 );

View File

@@ -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;
}
this.username = username;
this.discriminator = discriminator;
this.id = id;
this.avatar = avatar;
}
exports.User.prototype.getAvatarURL = function() {
// access using user.avatarURL;
get avatarURL(){
if( !this.avatar )
return false;
return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
return null;
return `https://discordapp.com/api/users/${this.id}/avatars/${this.avatar}.jpg`;
}
exports.User.prototype.mention = function() {
return "<@" + this.id + ">";
mention(){
return `<@${this.id}>`;
}
exports.User.prototype.equals = function( otherUser ) {
return otherUser.id === 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();
}
exports.User.prototype.equalsStrict = function( otherUser ) {
return ( this.username === otherUser.username && this.discriminator === otherUser.discriminator && this.id === otherUser.id && this.avatar === otherUser.avatar );
equals(object){
return object.id === this.id;
}
}
module.exports = User;

7
test/bot.js Normal file
View File

@@ -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);
});