T;T++)switch(v){case 143>=T:pa.push([T+48,8]);break;case 255>=T:pa.push([T-144+400,9]);break;case 279>=T:pa.push([T-256+0,7]);break;case 287>=T:pa.push([T-280+192,8]);break;default:q("invalid literal: "+T)}
ma.prototype.h=function(){var b,a,c,d,e=this.input;switch(this.k){case 0:c=0;for(d=e.length;c>>8&255;m[n++]=l&255;m[n++]=l>>>8&255;if(A)m.set(f,n),n+=f.length,m=m.subarray(0,n);else{s=0;for(p=f.length;sz)for(;0<
z--;)H[F++]=0,L[0]++;else for(;0z?z:138,C>z-3&&C=C?(H[F++]=17,H[F++]=C-3,L[17]++):(H[F++]=18,H[F++]=C-11,L[18]++),z-=C;else if(H[F++]=I[w],L[I[w]]++,z--,3>z)for(;0z?z:6,C>z-3&&CB;B++)sa[B]=ka[qb[B]];for(W=19;4=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,
a-31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:q("invalid length: "+a)}}var a=[],c,d;for(c=3;258>=c;c++)d=b(c),a[c]=d[2]<<24|d[1]<<
16|d[0];return a}(),xa=A?new Uint32Array(wa):wa;
function qa(b,a){function c(a,c){var b=a.O,d=[],f=0,e;e=xa[a.length];d[f++]=e&65535;d[f++]=e>>16&255;d[f++]=e>>24;var g;switch(v){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-
65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=
b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:q("invalid distance")}e=g;d[f++]=e[0];d[f++]=e[1];d[f++]=e[2];var h,k;h=0;for(k=d.length;h=f;)u[f++]=0;for(f=0;29>=f;)x[f++]=0}u[256]=1;d=0;for(e=a.length;d=e){p&&c(p,-1);f=0;for(g=e-d;fg&&a+gf&&(e=d,f=g);if(258===g)break}return new ua(f,a-e)}
function ra(b,a){var c=b.length,d=new ia(572),e=new (A?Uint8Array:Array)(c),f,g,k,h,l;if(!A)for(h=0;h2*e[n-1]+f[n]&&(e[n]=2*e[n-1]+f[n]),k[n]=Array(e[n]),h[n]=Array(e[n]);for(m=0;mb[m]?(k[n][r]=u,h[n][r]=a,x+=2):(k[n][r]=b[m],h[n][r]=m,++m);l[n]=0;1===f[n]&&d(n)}return g}
function ta(b){var a=new (A?Uint16Array:Array)(b.length),c=[],d=[],e=0,f,g,k,h;f=0;for(g=b.length;f>>=1}return a};function Aa(b,a){this.input=b;this.b=this.c=0;this.g={};a&&(a.flags&&(this.g=a.flags),"string"===typeof a.filename&&(this.filename=a.filename),"string"===typeof a.comment&&(this.w=a.comment),a.deflateOptions&&(this.l=a.deflateOptions));this.l||(this.l={})}
Aa.prototype.h=function(){var b,a,c,d,e,f,g,k,h=new (A?Uint8Array:Array)(32768),l=0,s=this.input,p=this.c,m=this.filename,n=this.w;h[l++]=31;h[l++]=139;h[l++]=8;b=0;this.g.fname&&(b|=Ba);this.g.fcomment&&(b|=Ca);this.g.fhcrc&&(b|=Da);h[l++]=b;a=(Date.now?Date.now():+new Date)/1E3|0;h[l++]=a&255;h[l++]=a>>>8&255;h[l++]=a>>>16&255;h[l++]=a>>>24&255;h[l++]=0;h[l++]=Sa;if(this.g.fname!==t){g=0;for(k=m.length;g>>8&255),h[l++]=f&255;h[l++]=0}if(this.g.comment){g=
0;for(k=n.length;g>>8&255),h[l++]=f&255;h[l++]=0}this.g.fhcrc&&(c=R(h,0,l)&65535,h[l++]=c&255,h[l++]=c>>>8&255);this.l.outputBuffer=h;this.l.outputIndex=l;e=new ma(s,this.l);h=e.h();l=e.b;A&&(l+8>h.buffer.byteLength?(this.a=new Uint8Array(l+8),this.a.set(new Uint8Array(h.buffer)),h=this.a):h=new Uint8Array(h.buffer));d=R(s,t,t);h[l++]=d&255;h[l++]=d>>>8&255;h[l++]=d>>>16&255;h[l++]=d>>>24&255;k=s.length;h[l++]=k&255;h[l++]=k>>>8&255;h[l++]=k>>>16&255;h[l++]=
k>>>24&255;this.c=p;A&&l>>=1;switch(b){case 0:var a=this.input,c=this.c,d=this.a,e=this.b,f=a.length,g=t,k=t,h=d.length,l=t;this.e=this.j=0;c+1>=f&&q(Error("invalid uncompressed block header: LEN"));g=a[c++]|a[c++]<<8;c+1>=f&&q(Error("invalid uncompressed block header: NLEN"));k=a[c++]|a[c++]<<8;g===~k&&q(Error("invalid uncompressed block header: length verify"));c+g>a.length&&q(Error("input buffer is broken"));switch(this.q){case Ua:for(;e+g>d.length;){l=
h-e;g-=l;if(A)d.set(a.subarray(c,c+l),e),e+=l,c+=l;else for(;l--;)d[e++]=a[c++];this.b=e;d=this.f();e=this.b}break;case Ta:for(;e+g>d.length;)d=this.f({B:2});break;default:q(Error("invalid inflate mode"))}if(A)d.set(a.subarray(c,c+g),e),e+=g,c+=g;else for(;g--;)d[e++]=a[c++];this.c=c;this.b=e;this.a=d;break;case 1:this.r(Va,Wa);break;case 2:Xa(this);break;default:q(Error("unknown BTYPE: "+b))}}return this.z()};
var Ya=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Za=A?new Uint16Array(Ya):Ya,$a=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],ab=A?new Uint16Array($a):$a,bb=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],cb=A?new Uint8Array(bb):bb,db=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],eb=A?new Uint16Array(db):db,fb=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
10,11,11,12,12,13,13],gb=A?new Uint8Array(fb):fb,hb=new (A?Uint8Array:Array)(288),$,ib;$=0;for(ib=hb.length;$=$?8:255>=$?9:279>=$?7:8;var Va=ja(hb),jb=new (A?Uint8Array:Array)(30),kb,lb;kb=0;for(lb=jb.length;kb=g&&q(Error("input buffer is broken")),c|=e[f++]<>>a;b.e=d-a;b.c=f;return k}
function mb(b,a){for(var c=b.j,d=b.e,e=b.input,f=b.c,g=e.length,k=a[0],h=a[1],l,s;d=g);)c|=e[f++]<>>16;b.j=c>>s;b.e=d-s;b.c=f;return l&65535}
function Xa(b){function a(a,b,c){var d,e=this.I,f,g;for(g=0;gf)d>=e&&(this.b=d,c=this.f(),d=this.b),c[d++]=f;else{g=f-257;h=ab[g];0=e&&(this.b=d,c=this.f(),d=this.b);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
Y.prototype.R=function(b,a){var c=this.a,d=this.b;this.A=b;for(var e=c.length,f,g,k,h;256!==(f=mb(this,b));)if(256>f)d>=e&&(c=this.f(),e=c.length),c[d++]=f;else{g=f-257;h=ab[g];0e&&(c=this.f(),e=c.length);for(;h--;)c[d]=c[d++-k]}for(;8<=this.e;)this.e-=8,this.c--;this.b=d};
Y.prototype.f=function(){var b=new (A?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,d,e=this.a;if(A)b.set(e.subarray(32768,b.length));else{c=0;for(d=b.length;cc;++c)e[c]=e[a+c];this.b=32768;return e};
Y.prototype.T=function(b){var a,c=this.input.length/this.c+1|0,d,e,f,g=this.input,k=this.a;b&&("number"===typeof b.B&&(c=b.B),"number"===typeof b.N&&(c+=b.N));2>c?(d=(g.length-this.c)/this.A[2],f=258*(d/2)|0,e=fa&&(this.a.length=a),b=this.a);return this.buffer=b};function nb(b){this.input=b;this.c=0;this.G=[];this.S=!1}
nb.prototype.i=function(){for(var b=this.input.length;this.c>>0;R(e,t,t)!==s&&q(Error("invalid CRC-32 checksum: 0x"+R(e,t,t).toString(16)+" / 0x"+
s.toString(16)));a.$=c=(p[m++]|p[m++]<<8|p[m++]<<16|p[m++]<<24)>>>0;(e.length&4294967295)!==c&&q(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.G.push(a);this.c=m}this.S=v;var n=this.G,r,u,x=0,O=0,y;r=0;for(u=n.length;r>>0;b=a}for(var e=1,f=0,g=b.length,k,h=0;0>>0};function pb(b,a){var c,d;this.input=b;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.W=a.verify);c=b[this.c++];d=b[this.c++];switch(c&15){case rb:this.method=rb;break;default:q(Error("unsupported compression method"))}0!==((c<<8)+d)%31&&q(Error("invalid fcheck flag:"+((c<<8)+d)%31));d&32&&q(Error("fdict flag is not supported"));this.K=new Y(b,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})}
pb.prototype.i=function(){var b=this.input,a,c;a=this.K.i();this.c=this.K.c;this.W&&(c=(b[this.c++]<<24|b[this.c++]<<16|b[this.c++]<<8|b[this.c++])>>>0,c!==ob(a)&&q(Error("invalid adler-32 checksum")));return a};var rb=8;function sb(b,a){this.input=b;this.a=new (A?Uint8Array:Array)(32768);this.k=tb.t;var c={},d;if((a||!(a={}))&&"number"===typeof a.compressionType)this.k=a.compressionType;for(d in a)c[d]=a[d];c.outputBuffer=this.a;this.J=new ma(this.input,c)}var tb=oa;
sb.prototype.h=function(){var b,a,c,d,e,f,g,k=0;g=this.a;b=rb;switch(b){case rb:a=Math.LOG2E*Math.log(32768)-8;break;default:q(Error("invalid compression method"))}c=a<<4|b;g[k++]=c;switch(b){case rb:switch(this.k){case tb.NONE:e=0;break;case tb.M:e=1;break;case tb.t:e=2;break;default:q(Error("unsupported compression type"))}break;default:q(Error("invalid compression method"))}d=e<<6|0;g[k++]=d|31-(256*c+d)%31;f=ob(this.input);this.J.b=k;g=this.J.h();k=g.length;A&&(g=new Uint8Array(g.buffer),g.length<=
k+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,k+4));g[k++]=f>>24&255;g[k++]=f>>16&255;g[k++]=f>>8&255;g[k++]=f&255;return g};exports.deflate=ub;exports.deflateSync=vb;exports.inflate=wb;exports.inflateSync=xb;exports.gzip=yb;exports.gzipSync=zb;exports.gunzip=Ab;exports.gunzipSync=Bb;function ub(b,a,c){process.nextTick(function(){var d,e;try{e=vb(b,c)}catch(f){d=f}a(d,e)})}function vb(b,a){var c;c=(new sb(b)).h();a||(a={});return a.H?c:Cb(c)}function wb(b,a,c){process.nextTick(function(){var d,e;try{e=xb(b,c)}catch(f){d=f}a(d,e)})}
function xb(b,a){var c;b.subarray=b.slice;c=(new pb(b)).i();a||(a={});return a.noBuffer?c:Cb(c)}function yb(b,a,c){process.nextTick(function(){var d,e;try{e=zb(b,c)}catch(f){d=f}a(d,e)})}function zb(b,a){var c;b.subarray=b.slice;c=(new Aa(b)).h();a||(a={});return a.H?c:Cb(c)}function Ab(b,a,c){process.nextTick(function(){var d,e;try{e=Bb(b,c)}catch(f){d=f}a(d,e)})}function Bb(b,a){var c;b.subarray=b.slice;c=(new nb(b)).i();a||(a={});return a.H?c:Cb(c)}
function Cb(b){var a=new Buffer(b.length),c,d;c=0;for(d=b.length;c { this.client.emit(Constants.Events.GUILD_CREATE, guild); });
} else {
this.client.emit(Constants.Events.GUILD_CREATE, guild);
}
}
return guild;
}
newUser(data) {
if (this.client.users.has(data.id)) return this.client.users.get(data.id);
const user = new User(this.client, data);
this.client.users.set(user.id, user);
return user;
}
newChannel(data, guild) {
const already = this.client.channels.has(data.id);
let channel;
if (data.type === Constants.ChannelTypes.DM) {
channel = new DMChannel(this.client, data);
} else if (data.type === Constants.ChannelTypes.groupDM) {
channel = new GroupDMChannel(this.client, data);
} else {
guild = guild || this.client.guilds.get(data.guild_id);
if (guild) {
if (data.type === Constants.ChannelTypes.text) {
channel = new TextChannel(guild, data);
guild.channels.set(channel.id, channel);
} else if (data.type === Constants.ChannelTypes.voice) {
channel = new VoiceChannel(guild, data);
guild.channels.set(channel.id, channel);
}
}
}
if (channel) {
if (this.pastReady && !already) this.client.emit(Constants.Events.CHANNEL_CREATE, channel);
this.client.channels.set(channel.id, channel);
return channel;
}
return null;
}
newEmoji(data, guild) {
const already = guild.emojis.has(data.id);
if (data && !already) {
let emoji = new Emoji(guild, data);
this.client.emit(Constants.Events.EMOJI_CREATE, emoji);
guild.emojis.set(emoji.id, emoji);
return emoji;
} else if (already) {
return guild.emojis.get(data.id);
}
return null;
}
killEmoji(emoji) {
if (!(emoji instanceof Emoji && emoji.guild)) return;
this.client.emit(Constants.Events.EMOJI_DELETE, emoji);
emoji.guild.emojis.delete(emoji.id);
}
killGuild(guild) {
const already = this.client.guilds.has(guild.id);
this.client.guilds.delete(guild.id);
if (already && this.pastReady) this.client.emit(Constants.Events.GUILD_DELETE, guild);
}
killUser(user) {
this.client.users.delete(user.id);
}
killChannel(channel) {
this.client.channels.delete(channel.id);
if (channel instanceof GuildChannel) channel.guild.channels.delete(channel.id);
}
updateGuild(currentGuild, newData) {
const oldGuild = cloneObject(currentGuild);
currentGuild.setup(newData);
if (this.pastReady) this.client.emit(Constants.Events.GUILD_UPDATE, oldGuild, currentGuild);
}
updateChannel(currentChannel, newData) {
currentChannel.setup(newData);
}
updateEmoji(currentEmoji, newData) {
const oldEmoji = cloneObject(currentEmoji);
currentEmoji.setup(newData);
this.client.emit(Constants.Events.GUILD_EMOJI_UPDATE, oldEmoji, currentEmoji);
}
}
module.exports = ClientDataManager;
/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {
const Constants = __webpack_require__(0);
/**
* Manages the State and Background Tasks of the Client
* @private
*/
class ClientManager {
constructor(client) {
/**
* The Client that instantiated this Manager
* @type {Client}
*/
this.client = client;
/**
* The heartbeat interval, null if not yet set
* @type {?number}
*/
this.heartbeatInterval = null;
}
/**
* Connects the Client to the WebSocket
* @param {string} token The authorization token
* @param {Function} resolve Function to run when connection is successful
* @param {Function} reject Function to run when connection fails
*/
connectToWebSocket(token, resolve, reject) {
this.client.emit(Constants.Events.DEBUG, `Authenticated using token ${token}`);
this.client.token = token;
const timeout = this.client.setTimeout(() => reject(new Error(Constants.Errors.TOOK_TOO_LONG)), 1000 * 300);
this.client.rest.methods.getGateway().then(gateway => {
this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`);
this.client.ws.connect(gateway);
this.client.ws.once('close', event => {
if (event.code === 4004) reject(new Error(Constants.Errors.BAD_LOGIN));
if (event.code === 4010) reject(new Error(Constants.Errors.INVALID_SHARD));
});
this.client.once(Constants.Events.READY, () => {
resolve(token);
this.client.clearTimeout(timeout);
});
}, reject);
}
/**
* Sets up a keep-alive interval to keep the Client's connection valid
* @param {number} time The interval in milliseconds at which heartbeat packets should be sent
*/
setupKeepAlive(time) {
this.heartbeatInterval = this.client.setInterval(() => {
this.client.emit('debug', 'Sending heartbeat');
this.client.ws.send({
op: Constants.OPCodes.HEARTBEAT,
d: this.client.ws.sequence,
}, true);
}, time);
}
destroy() {
return new Promise(resolve => {
this.client.ws.destroy();
if (!this.client.user.bot) {
resolve(this.client.rest.methods.logout());
} else {
resolve();
}
});
}
}
module.exports = ClientManager;
/***/ },
/* 65 */
/***/ function(module, exports, __webpack_require__) {
class ActionsManager {
constructor(client) {
this.client = client;
this.register(__webpack_require__(82));
this.register(__webpack_require__(83));
this.register(__webpack_require__(84));
this.register(__webpack_require__(88));
this.register(__webpack_require__(85));
this.register(__webpack_require__(86));
this.register(__webpack_require__(87));
this.register(__webpack_require__(66));
this.register(__webpack_require__(67));
this.register(__webpack_require__(68));
this.register(__webpack_require__(70));
this.register(__webpack_require__(81));
this.register(__webpack_require__(74));
this.register(__webpack_require__(75));
this.register(__webpack_require__(69));
this.register(__webpack_require__(76));
this.register(__webpack_require__(77));
this.register(__webpack_require__(78));
this.register(__webpack_require__(89));
this.register(__webpack_require__(91));
this.register(__webpack_require__(90));
this.register(__webpack_require__(80));
this.register(__webpack_require__(71));
this.register(__webpack_require__(72));
this.register(__webpack_require__(73));
this.register(__webpack_require__(79));
}
register(Action) {
this[Action.name.replace(/Action$/, '')] = new Action(this.client);
}
}
module.exports = ActionsManager;
/***/ },
/* 66 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class ChannelCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.dataManager.newChannel(data);
return {
channel,
};
}
}
module.exports = ChannelCreateAction;
/***/ },
/* 67 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class ChannelDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
let channel = client.channels.get(data.id);
if (channel) {
client.dataManager.killChannel(channel);
this.deleted.set(channel.id, channel);
this.scheduleForDeletion(channel.id);
} else {
channel = this.deleted.get(data.id) || null;
}
return {
channel,
};
}
scheduleForDeletion(id) {
this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout);
}
}
module.exports = ChannelDeleteAction;
/***/ },
/* 68 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class ChannelUpdateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get(data.id);
if (channel) {
const oldChannel = cloneObject(channel);
channel.setup(data);
client.emit(Constants.Events.CHANNEL_UPDATE, oldChannel, channel);
return {
old: oldChannel,
updated: channel,
};
}
return {
old: null,
updated: null,
};
}
}
/**
* Emitted whenever a channel is updated - e.g. name change, topic change.
* @event Client#channelUpdate
* @param {Channel} oldChannel The channel before the update
* @param {Channel} newChannel The channel after the update
*/
module.exports = ChannelUpdateAction;
/***/ },
/* 69 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class GuildBanRemove extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const user = client.dataManager.newUser(data.user);
if (guild && user) client.emit(Constants.Events.GUILD_BAN_REMOVE, guild, user);
}
}
module.exports = GuildBanRemove;
/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class GuildDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
let guild = client.guilds.get(data.id);
if (guild) {
if (guild.available && data.unavailable) {
// guild is unavailable
guild.available = false;
client.emit(Constants.Events.GUILD_UNAVAILABLE, guild);
// stops the GuildDelete packet thinking a guild was actually deleted,
// handles emitting of event itself
return {
guild: null,
};
}
// delete guild
client.guilds.delete(guild.id);
this.deleted.set(guild.id, guild);
this.scheduleForDeletion(guild.id);
} else {
guild = this.deleted.get(data.id) || null;
}
return {
guild,
};
}
scheduleForDeletion(id) {
this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout);
}
}
/**
* Emitted whenever a guild becomes unavailable, likely due to a server outage.
* @event Client#guildUnavailable
* @param {Guild} guild The guild that has become unavailable.
*/
module.exports = GuildDeleteAction;
/***/ },
/* 71 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class EmojiCreateAction extends Action {
handle(data, guild) {
const client = this.client;
const emoji = client.dataManager.newEmoji(data, guild);
return {
emoji,
};
}
}
/**
* Emitted whenever an emoji is created
* @event Client#guildEmojiCreate
* @param {Emoji} emoji The emoji that was created.
*/
module.exports = EmojiCreateAction;
/***/ },
/* 72 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class EmojiDeleteAction extends Action {
handle(data) {
const client = this.client;
client.dataManager.killEmoji(data);
return {
data,
};
}
}
/**
* Emitted whenever an emoji is deleted
* @event Client#guildEmojiDelete
* @param {Emoji} emoji The emoji that was deleted.
*/
module.exports = EmojiDeleteAction;
/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class GuildEmojiUpdateAction extends Action {
handle(data, guild) {
const client = this.client;
for (let emoji of data.emojis) {
const already = guild.emojis.has(emoji.id);
if (already) {
client.dataManager.updateEmoji(guild.emojis.get(emoji.id), emoji);
} else {
emoji = client.dataManager.newEmoji(emoji, guild);
}
}
for (let emoji of guild.emojis) {
if (!data.emoijs.has(emoji.id)) client.dataManager.killEmoji(emoji);
}
return {
emojis: data.emojis,
};
}
}
/**
* Emitted whenever an emoji is updated
* @event Client#guildEmojiUpdate
* @param {Emoji} oldEmoji The old emoji
* @param {Emoji} newEmoji The new emoji
*/
module.exports = GuildEmojiUpdateAction;
/***/ },
/* 74 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class GuildMemberGetAction extends Action {
handle(guild, data) {
const member = guild._addMember(data, false);
return {
member,
};
}
}
module.exports = GuildMemberGetAction;
/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class GuildMemberRemoveAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
if (guild) {
let member = guild.members.get(data.user.id);
if (member) {
guild.memberCount--;
guild._removeMember(member);
this.deleted.set(guild.id + data.user.id, member);
if (client.status === Constants.Status.READY) client.emit(Constants.Events.GUILD_MEMBER_REMOVE, member);
this.scheduleForDeletion(guild.id, data.user.id);
} else {
member = this.deleted.get(guild.id + data.user.id) || null;
}
return {
guild,
member,
};
}
return {
guild,
member: null,
};
}
scheduleForDeletion(guildID, userID) {
this.client.setTimeout(() => this.deleted.delete(guildID + userID), this.client.options.restWsBridgeTimeout);
}
}
/**
* Emitted whenever a member leaves a guild, or is kicked.
* @event Client#guildMemberRemove
* @param {GuildMember} member The member that has left/been kicked from the guild.
*/
module.exports = GuildMemberRemoveAction;
/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const Role = __webpack_require__(7);
class GuildRoleCreate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
if (guild) {
const already = guild.roles.has(data.role.id);
const role = new Role(guild, data.role);
guild.roles.set(role.id, role);
if (!already) client.emit(Constants.Events.GUILD_ROLE_CREATE, role);
return {
role,
};
}
return {
role: null,
};
}
}
/**
* Emitted whenever a role is created.
* @event Client#roleCreate
* @param {Role} role The role that was created.
*/
module.exports = GuildRoleCreate;
/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class GuildRoleDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
if (guild) {
let role = guild.roles.get(data.role_id);
if (role) {
guild.roles.delete(data.role_id);
this.deleted.set(guild.id + data.role_id, role);
this.scheduleForDeletion(guild.id, data.role_id);
client.emit(Constants.Events.GUILD_ROLE_DELETE, role);
} else {
role = this.deleted.get(guild.id + data.role_id) || null;
}
return {
role,
};
}
return {
role: null,
};
}
scheduleForDeletion(guildID, roleID) {
this.client.setTimeout(() => this.deleted.delete(guildID + roleID), this.client.options.restWsBridgeTimeout);
}
}
/**
* Emitted whenever a guild role is deleted.
* @event Client#roleDelete
* @param {Role} role The role that was deleted.
*/
module.exports = GuildRoleDeleteAction;
/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class GuildRoleUpdateAction extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
if (guild) {
const roleData = data.role;
let oldRole = null;
const role = guild.roles.get(roleData.id);
if (role) {
oldRole = cloneObject(role);
role.setup(data.role);
client.emit(Constants.Events.GUILD_ROLE_UPDATE, oldRole, role);
}
return {
old: oldRole,
updated: role,
};
}
return {
old: null,
updated: null,
};
}
}
/**
* Emitted whenever a guild role is updated.
* @event Client#roleUpdate
* @param {Role} oldRole The role before the update.
* @param {Role} newRole The role after the update.
*/
module.exports = GuildRoleUpdateAction;
/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class GuildRolesPositionUpdate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
if (guild) {
for (const partialRole of data.roles) {
const role = guild.roles.get(partialRole.id);
if (role) {
role.position = partialRole.position;
}
}
}
return {
guild,
};
}
}
module.exports = GuildRolesPositionUpdate;
/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class GuildSync extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.id);
if (guild) {
data.presences = data.presences || [];
for (const presence of data.presences) {
guild._setPresence(presence.user.id, presence);
}
data.members = data.members || [];
for (const syncMember of data.members) {
const member = guild.members.get(syncMember.user.id);
if (member) {
guild._updateMember(member, syncMember);
} else {
guild._addMember(syncMember);
}
}
}
}
}
module.exports = GuildSync;
/***/ },
/* 81 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class GuildUpdateAction extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.id);
if (guild) {
const oldGuild = cloneObject(guild);
guild.setup(data);
client.emit(Constants.Events.GUILD_UPDATE, oldGuild, guild);
return {
old: oldGuild,
updated: guild,
};
}
return {
old: null,
updated: null,
};
}
}
/**
* Emitted whenever a guild is updated - e.g. name change.
* @event Client#guildUpdate
* @param {Guild} oldGuild The guild before the update.
* @param {Guild} newGuild The guild after the update.
*/
module.exports = GuildUpdateAction;
/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Message = __webpack_require__(13);
class MessageCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get((data instanceof Array ? data[0] : data).channel_id);
if (channel) {
if (data instanceof Array) {
const messages = new Array(data.length);
for (let i = 0; i < data.length; i++) {
messages[i] = channel._cacheMessage(new Message(channel, data[i], client));
}
channel.lastMessageID = messages[messages.length - 1].id;
return {
messages,
};
} else {
const message = channel._cacheMessage(new Message(channel, data, client));
channel.lastMessageID = data.id;
return {
message,
};
}
}
return {
message: null,
};
}
}
module.exports = MessageCreateAction;
/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class MessageDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
const channel = client.channels.get(data.channel_id);
if (channel) {
let message = channel.messages.get(data.id);
if (message) {
channel.messages.delete(message.id);
this.deleted.set(channel.id + message.id, message);
this.scheduleForDeletion(channel.id, message.id);
} else {
message = this.deleted.get(channel.id + data.id) || null;
}
return {
message,
};
}
return {
message: null,
};
}
scheduleForDeletion(channelID, messageID) {
this.client.setTimeout(() => this.deleted.delete(channelID + messageID),
this.client.options.restWsBridgeTimeout);
}
}
module.exports = MessageDeleteAction;
/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Collection = __webpack_require__(3);
const Constants = __webpack_require__(0);
class MessageDeleteBulkAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get(data.channel_id);
const ids = data.ids;
const messages = new Collection();
for (const id of ids) {
const message = channel.messages.get(id);
if (message) messages.set(message.id, message);
}
if (messages.size > 0) client.emit(Constants.Events.MESSAGE_BULK_DELETE, messages);
return {
messages,
};
}
}
module.exports = MessageDeleteBulkAction;
/***/ },
/* 85 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
/*
{ user_id: 'id',
message_id: 'id',
emoji: { name: '�', id: null },
channel_id: 'id' } }
*/
class MessageReactionAdd extends Action {
handle(data) {
const user = this.client.users.get(data.user_id);
if (!user) return false;
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
const message = channel.messages.get(data.message_id);
if (!message) return false;
if (!data.emoji) return false;
const reaction = message._addReaction(data.emoji, user);
if (reaction) {
this.client.emit(Constants.Events.MESSAGE_REACTION_ADD, reaction, user);
}
return {
message,
reaction,
user,
};
}
}
/**
* Emitted whenever a reaction is added to a message.
* @event Client#messageReactionAdd
* @param {MessageReaction} messageReaction The reaction object.
* @param {User} user The user that applied the emoji or reaction emoji.
*/
module.exports = MessageReactionAdd;
/***/ },
/* 86 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
/*
{ user_id: 'id',
message_id: 'id',
emoji: { name: '�', id: null },
channel_id: 'id' } }
*/
class MessageReactionRemove extends Action {
handle(data) {
const user = this.client.users.get(data.user_id);
if (!user) return false;
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
const message = channel.messages.get(data.message_id);
if (!message) return false;
if (!data.emoji) return false;
const reaction = message._removeReaction(data.emoji, user);
if (reaction) {
this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE, reaction, user);
}
return {
message,
reaction,
user,
};
}
}
/**
* Emitted whenever a reaction is removed from a message.
* @event Client#messageReactionRemove
* @param {MessageReaction} messageReaction The reaction object.
* @param {User} user The user that removed the emoji or reaction emoji.
*/
module.exports = MessageReactionRemove;
/***/ },
/* 87 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class MessageReactionRemoveAll extends Action {
handle(data) {
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
const message = channel.messages.get(data.message_id);
if (!message) return false;
message._clearReactions();
this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE_ALL, message);
return {
message,
};
}
}
/**
* Emitted whenever all reactions are removed from a message.
* @event Client#messageReactionRemoveAll
* @param {MessageReaction} messageReaction The reaction object.
*/
module.exports = MessageReactionRemoveAll;
/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class MessageUpdateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get(data.channel_id);
if (channel) {
const message = channel.messages.get(data.id);
if (message) {
const oldMessage = cloneObject(message);
message.patch(data);
message._edits.unshift(oldMessage);
client.emit(Constants.Events.MESSAGE_UPDATE, oldMessage, message);
return {
old: oldMessage,
updated: message,
};
}
return {
old: message,
updated: message,
};
}
return {
old: null,
updated: null,
};
}
}
/**
* Emitted whenever a message is updated - e.g. embed or content change.
* @event Client#messageUpdate
* @param {Message} oldMessage The message before the update.
* @param {Message} newMessage The message after the update.
*/
module.exports = MessageUpdateAction;
/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
class UserGetAction extends Action {
handle(data) {
const client = this.client;
const user = client.dataManager.newUser(data);
return {
user,
};
}
}
module.exports = UserGetAction;
/***/ },
/* 90 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
class UserNoteUpdateAction extends Action {
handle(data) {
const client = this.client;
const oldNote = client.user.notes.get(data.id);
const note = data.note.length ? data.note : null;
client.user.notes.set(data.id, note);
client.emit(Constants.Events.USER_NOTE_UPDATE, data.id, oldNote, note);
return {
old: oldNote,
updated: note,
};
}
}
/**
* Emitted whenever a note is updated.
* @event Client#userNoteUpdate
* @param {User} user The user the note belongs to
* @param {string} oldNote The note content before the update
* @param {string} newNote The note content after the update
*/
module.exports = UserNoteUpdateAction;
/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {
const Action = __webpack_require__(2);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class UserUpdateAction extends Action {
handle(data) {
const client = this.client;
if (client.user) {
if (client.user.equals(data)) {
return {
old: client.user,
updated: client.user,
};
}
const oldUser = cloneObject(client.user);
client.user.patch(data);
client.emit(Constants.Events.USER_UPDATE, oldUser, client.user);
return {
old: oldUser,
updated: client.user,
};
}
return {
old: null,
updated: null,
};
}
}
module.exports = UserUpdateAction;
/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {
const request = __webpack_require__(23);
const Constants = __webpack_require__(0);
function getRoute(url) {
let route = url.split('?')[0];
if (route.includes('/channels/') || route.includes('/guilds/')) {
const startInd = ~route.indexOf('/channels/') ? route.indexOf('/channels/') : route.indexOf('/guilds/');
const majorID = route.substring(startInd).split('/')[2];
route = route.replace(/(\d{8,})/g, ':id').replace(':id', majorID);
}
return route;
}
class APIRequest {
constructor(rest, method, url, auth, data, file) {
this.rest = rest;
this.method = method;
this.url = url;
this.auth = auth;
this.data = data;
this.file = file;
this.route = getRoute(this.url);
}
getAuth() {
if (this.rest.client.token && this.rest.client.user && this.rest.client.user.bot) {
return `Bot ${this.rest.client.token}`;
} else if (this.rest.client.token) {
return this.rest.client.token;
}
throw new Error(Constants.Errors.NO_TOKEN);
}
gen() {
const apiRequest = request[this.method](this.url);
if (this.auth) apiRequest.set('authorization', this.getAuth());
if (this.file && this.file.file) {
apiRequest.attach('file', this.file.file, this.file.name);
this.data = this.data || {};
for (const key in this.data) {
if (this.data[key]) {
apiRequest.field(key, this.data[key]);
}
}
} else if (this.data) {
apiRequest.send(this.data);
}
apiRequest.set('User-Agent', this.rest.userAgentManager.userAgent);
return apiRequest;
}
}
module.exports = APIRequest;
/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {
const Constants = __webpack_require__(0);
const Collection = __webpack_require__(3);
const splitMessage = __webpack_require__(41);
const parseEmoji = __webpack_require__(134);
const User = __webpack_require__(5);
const GuildMember = __webpack_require__(12);
const Role = __webpack_require__(7);
const Invite = __webpack_require__(30);
const Webhook = __webpack_require__(20);
const UserProfile = __webpack_require__(133);
const ClientOAuth2Application = __webpack_require__(26);
class RESTMethods {
constructor(restManager) {
this.rest = restManager;
}
loginToken(token = this.rest.client.token) {
return new Promise((resolve, reject) => {
token = token.replace(/^Bot\s*/i, '');
this.rest.client.manager.connectToWebSocket(token, resolve, reject);
});
}
loginEmailPassword(email, password) {
this.rest.client.emit('warn', 'Client launched using email and password - should use token instead');
this.rest.client.email = email;
this.rest.client.password = password;
return this.rest.makeRequest('post', Constants.Endpoints.login, false, { email, password }).then(data =>
this.loginToken(data.token)
);
}
logout() {
return this.rest.makeRequest('post', Constants.Endpoints.logout, true, {});
}
getGateway() {
return this.rest.makeRequest('get', Constants.Endpoints.gateway, true).then(res => {
this.rest.client.ws.gateway = `${res.url}/?encoding=json&v=${Constants.PROTOCOL_VERSION}`;
return this.rest.client.ws.gateway;
});
}
getBotGateway() {
return this.rest.makeRequest('get', Constants.Endpoints.botGateway, true);
}
sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split } = {}, file = null) {
return new Promise((resolve, reject) => {
if (typeof content !== 'undefined') content = this.rest.client.resolver.resolveString(content);
if (content) {
if (disableEveryone || (typeof disableEveryone === 'undefined' && this.rest.client.options.disableEveryone)) {
content = content.replace(/@(everyone|here)/g, '@\u200b$1');
}
if (split) content = splitMessage(content, typeof split === 'object' ? split : {});
}
if (channel instanceof User || channel instanceof GuildMember) {
this.createDM(channel).then(chan => {
this._sendMessageRequest(chan, content, file, tts, nonce, embed, resolve, reject);
}, reject);
} else {
this._sendMessageRequest(channel, content, file, tts, nonce, embed, resolve, reject);
}
});
}
_sendMessageRequest(channel, content, file, tts, nonce, embed, resolve, reject) {
if (content instanceof Array) {
const datas = [];
let promise = this.rest.makeRequest('post', Constants.Endpoints.channelMessages(channel.id), true, {
content: content[0], tts, nonce,
}, file).catch(reject);
for (let i = 1; i <= content.length; i++) {
if (i < content.length) {
const i2 = i;
promise = promise.then(data => {
datas.push(data);
return this.rest.makeRequest('post', Constants.Endpoints.channelMessages(channel.id), true, {
content: content[i2], tts, nonce, embed,
}, file);
}, reject);
} else {
promise.then(data => {
datas.push(data);
resolve(this.rest.client.actions.MessageCreate.handle(datas).messages);
}, reject);
}
}
} else {
this.rest.makeRequest('post', Constants.Endpoints.channelMessages(channel.id), true, {
content, tts, nonce, embed,
}, file)
.then(data => resolve(this.rest.client.actions.MessageCreate.handle(data).message), reject);
}
}
deleteMessage(message) {
return this.rest.makeRequest('del', Constants.Endpoints.channelMessage(message.channel.id, message.id), true)
.then(() =>
this.rest.client.actions.MessageDelete.handle({
id: message.id,
channel_id: message.channel.id,
}).message
);
}
bulkDeleteMessages(channel, messages) {
return this.rest.makeRequest('post', `${Constants.Endpoints.channelMessages(channel.id)}/bulk_delete`, true, {
messages,
}).then(() =>
this.rest.client.actions.MessageDeleteBulk.handle({
channel_id: channel.id,
ids: messages,
}).messages
);
}
updateMessage(message, content, { embed } = {}) {
content = this.rest.client.resolver.resolveString(content);
return this.rest.makeRequest('patch', Constants.Endpoints.channelMessage(message.channel.id, message.id), true, {
content, embed,
}).then(data => this.rest.client.actions.MessageUpdate.handle(data).updated);
}
createChannel(guild, channelName, channelType) {
return this.rest.makeRequest('post', Constants.Endpoints.guildChannels(guild.id), true, {
name: channelName,
type: channelType,
}).then(data => this.rest.client.actions.ChannelCreate.handle(data).channel);
}
createDM(recipient) {
const dmChannel = this.getExistingDM(recipient);
if (dmChannel) return Promise.resolve(dmChannel);
return this.rest.makeRequest('post', Constants.Endpoints.userChannels(this.rest.client.user.id), true, {
recipient_id: recipient.id,
}).then(data => this.rest.client.actions.ChannelCreate.handle(data).channel);
}
getExistingDM(recipient) {
return this.rest.client.channels.find(channel =>
channel.recipient && channel.recipient.id === recipient.id
);
}
deleteChannel(channel) {
if (channel instanceof User || channel instanceof GuildMember) channel = this.getExistingDM(channel);
if (!channel) return Promise.reject(new Error('No channel to delete.'));
return this.rest.makeRequest('del', Constants.Endpoints.channel(channel.id), true).then(data => {
data.id = channel.id;
return this.rest.client.actions.ChannelDelete.handle(data).channel;
});
}
updateChannel(channel, _data) {
const data = {};
data.name = (_data.name || channel.name).trim();
data.topic = _data.topic || channel.topic;
data.position = _data.position || channel.position;
data.bitrate = _data.bitrate || channel.bitrate;
data.user_limit = _data.userLimit || channel.userLimit;
return this.rest.makeRequest('patch', Constants.Endpoints.channel(channel.id), true, data).then(newData =>
this.rest.client.actions.ChannelUpdate.handle(newData).updated
);
}
leaveGuild(guild) {
if (guild.ownerID === this.rest.client.user.id) return Promise.reject(new Error('Guild is owned by the client.'));
return this.rest.makeRequest('del', Constants.Endpoints.meGuild(guild.id), true).then(() =>
this.rest.client.actions.GuildDelete.handle({ id: guild.id }).guild
);
}
createGuild(options) {
options.icon = this.rest.client.resolver.resolveBase64(options.icon) || null;
options.region = options.region || 'us-central';
return new Promise((resolve, reject) => {
this.rest.makeRequest('post', Constants.Endpoints.guilds, true, options).then(data => {
if (this.rest.client.guilds.has(data.id)) {
resolve(this.rest.client.guilds.get(data.id));
return;
}
const handleGuild = guild => {
if (guild.id === data.id) {
this.rest.client.removeListener('guildCreate', handleGuild);
this.rest.client.clearTimeout(timeout);
resolve(guild);
}
};
this.rest.client.on('guildCreate', handleGuild);
const timeout = this.rest.client.setTimeout(() => {
this.rest.client.removeListener('guildCreate', handleGuild);
reject(new Error('Took too long to receive guild data.'));
}, 10000);
}, reject);
});
}
// untested but probably will work
deleteGuild(guild) {
return this.rest.makeRequest('del', Constants.Endpoints.guild(guild.id), true).then(() =>
this.rest.client.actions.GuildDelete.handle({ id: guild.id }).guild
);
}
getUser(userID) {
return this.rest.makeRequest('get', Constants.Endpoints.user(userID), true).then(data =>
this.rest.client.actions.UserGet.handle(data).user
);
}
updateCurrentUser(_data) {
const user = this.rest.client.user;
const data = {};
data.username = _data.username || user.username;
data.avatar = this.rest.client.resolver.resolveBase64(_data.avatar) || user.avatar;
if (!user.bot) {
data.email = _data.email || user.email;
data.password = this.rest.client.password;
if (_data.new_password) data.new_password = _data.newPassword;
}
return this.rest.makeRequest('patch', Constants.Endpoints.me, true, data).then(newData =>
this.rest.client.actions.UserUpdate.handle(newData).updated
);
}
updateGuild(guild, _data) {
const data = {};
if (_data.name) data.name = _data.name;
if (_data.region) data.region = _data.region;
if (_data.verificationLevel) data.verification_level = Number(_data.verificationLevel);
if (_data.afkChannel) data.afk_channel_id = this.rest.client.resolver.resolveChannel(_data.afkChannel).id;
if (_data.afkTimeout) data.afk_timeout = Number(_data.afkTimeout);
if (_data.icon) data.icon = this.rest.client.resolver.resolveBase64(_data.icon);
if (_data.owner) data.owner_id = this.rest.client.resolver.resolveUser(_data.owner).id;
if (_data.splash) data.splash = this.rest.client.resolver.resolveBase64(_data.splash);
return this.rest.makeRequest('patch', Constants.Endpoints.guild(guild.id), true, data).then(newData =>
this.rest.client.actions.GuildUpdate.handle(newData).updated
);
}
kickGuildMember(guild, member) {
return this.rest.makeRequest('del', Constants.Endpoints.guildMember(guild.id, member.id), true).then(() =>
this.rest.client.actions.GuildMemberRemove.handle({
guild_id: guild.id,
user: member.user,
}).member
);
}
createGuildRole(guild) {
return this.rest.makeRequest('post', Constants.Endpoints.guildRoles(guild.id), true).then(role =>
this.rest.client.actions.GuildRoleCreate.handle({
guild_id: guild.id,
role,
}).role
);
}
deleteGuildRole(role) {
return this.rest.makeRequest('del', Constants.Endpoints.guildRole(role.guild.id, role.id), true).then(() =>
this.rest.client.actions.GuildRoleDelete.handle({
guild_id: role.guild.id,
role_id: role.id,
}).role
);
}
setChannelOverwrite(channel, payload) {
return this.rest.makeRequest(
'put', `${Constants.Endpoints.channelPermissions(channel.id)}/${payload.id}`, true, payload
);
}
deletePermissionOverwrites(overwrite) {
return this.rest.makeRequest(
'del', `${Constants.Endpoints.channelPermissions(overwrite.channel.id)}/${overwrite.id}`, true
).then(() => overwrite);
}
getChannelMessages(channel, payload = {}) {
const params = [];
if (payload.limit) params.push(`limit=${payload.limit}`);
if (payload.around) params.push(`around=${payload.around}`);
else if (payload.before) params.push(`before=${payload.before}`);
else if (payload.after) params.push(`after=${payload.after}`);
let endpoint = Constants.Endpoints.channelMessages(channel.id);
if (params.length > 0) endpoint += `?${params.join('&')}`;
return this.rest.makeRequest('get', endpoint, true);
}
getChannelMessage(channel, messageID) {
const msg = channel.messages.get(messageID);
if (msg) return Promise.resolve(msg);
return this.rest.makeRequest('get', Constants.Endpoints.channelMessage(channel.id, messageID), true);
}
getGuildMember(guild, user) {
return this.rest.makeRequest('get', Constants.Endpoints.guildMember(guild.id, user.id), true).then(data =>
this.rest.client.actions.GuildMemberGet.handle(guild, data).member
);
}
updateGuildMember(member, data) {
if (data.channel) data.channel_id = this.rest.client.resolver.resolveChannel(data.channel).id;
if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role);
let endpoint = Constants.Endpoints.guildMember(member.guild.id, member.id);
// fix your endpoints, discord ;-;
if (member.id === this.rest.client.user.id) {
const keys = Object.keys(data);
if (keys.length === 1 && keys[0] === 'nick') {
endpoint = Constants.Endpoints.stupidInconsistentGuildEndpoint(member.guild.id);
}
}
return this.rest.makeRequest('patch', endpoint, true, data).then(newData =>
member.guild._updateMember(member, newData).mem
);
}
sendTyping(channelID) {
return this.rest.makeRequest('post', `${Constants.Endpoints.channel(channelID)}/typing`, true);
}
banGuildMember(guild, member, deleteDays = 0) {
const id = this.rest.client.resolver.resolveUserID(member);
if (!id) return Promise.reject(new Error('Couldn\'t resolve the user ID to ban.'));
return this.rest.makeRequest(
'put', `${Constants.Endpoints.guildBans(guild.id)}/${id}?delete-message-days=${deleteDays}`, true, {
'delete-message-days': deleteDays,
}
).then(() => {
if (member instanceof GuildMember) return member;
const user = this.rest.client.resolver.resolveUser(id);
if (user) {
member = this.rest.client.resolver.resolveGuildMember(guild, user);
return member || user;
}
return id;
});
}
unbanGuildMember(guild, member) {
return new Promise((resolve, reject) => {
const id = this.rest.client.resolver.resolveUserID(member);
if (!id) throw new Error('Couldn\'t resolve the user ID to unban.');
const listener = (eGuild, eUser) => {
if (eGuild.id === guild.id && eUser.id === id) {
this.rest.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.rest.client.clearTimeout(timeout);
resolve(eUser);
}
};
this.rest.client.on(Constants.Events.GUILD_BAN_REMOVE, listener);
const timeout = this.rest.client.setTimeout(() => {
this.rest.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
reject(new Error('Took too long to receive the ban remove event.'));
}, 10000);
this.rest.makeRequest('del', `${Constants.Endpoints.guildBans(guild.id)}/${id}`, true).catch(err => {
this.rest.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.rest.client.clearTimeout(timeout);
reject(err);
});
});
}
getGuildBans(guild) {
return this.rest.makeRequest('get', Constants.Endpoints.guildBans(guild.id), true).then(banItems => {
const bannedUsers = new Collection();
for (const banItem of banItems) {
const user = this.rest.client.dataManager.newUser(banItem.user);
bannedUsers.set(user.id, user);
}
return bannedUsers;
});
}
updateGuildRole(role, _data) {
const data = {};
data.name = _data.name || role.name;
data.position = typeof _data.position !== 'undefined' ? _data.position : role.position;
data.color = _data.color || role.color;
if (typeof data.color === 'string' && data.color.startsWith('#')) {
data.color = parseInt(data.color.replace('#', ''), 16);
}
data.hoist = typeof _data.hoist !== 'undefined' ? _data.hoist : role.hoist;
data.mentionable = typeof _data.mentionable !== 'undefined' ? _data.mentionable : role.mentionable;
if (_data.permissions) {
let perms = 0;
for (let perm of _data.permissions) {
if (typeof perm === 'string') perm = Constants.PermissionFlags[perm];
perms |= perm;
}
data.permissions = perms;
} else {
data.permissions = role.permissions;
}
return this.rest.makeRequest(
'patch', Constants.Endpoints.guildRole(role.guild.id, role.id), true, data
).then(_role =>
this.rest.client.actions.GuildRoleUpdate.handle({
role: _role,
guild_id: role.guild.id,
}).updated
);
}
pinMessage(message) {
return this.rest.makeRequest('put', `${Constants.Endpoints.channel(message.channel.id)}/pins/${message.id}`, true)
.then(() => message);
}
unpinMessage(message) {
return this.rest.makeRequest('del', `${Constants.Endpoints.channel(message.channel.id)}/pins/${message.id}`, true)
.then(() => message);
}
getChannelPinnedMessages(channel) {
return this.rest.makeRequest('get', `${Constants.Endpoints.channel(channel.id)}/pins`, true);
}
createChannelInvite(channel, options) {
const payload = {};
payload.temporary = options.temporary;
payload.max_age = options.maxAge;
payload.max_uses = options.maxUses;
return this.rest.makeRequest('post', `${Constants.Endpoints.channelInvites(channel.id)}`, true, payload)
.then(invite => new Invite(this.rest.client, invite));
}
deleteInvite(invite) {
return this.rest.makeRequest('del', Constants.Endpoints.invite(invite.code), true).then(() => invite);
}
getInvite(code) {
return this.rest.makeRequest('get', Constants.Endpoints.invite(code), true).then(invite =>
new Invite(this.rest.client, invite)
);
}
getGuildInvites(guild) {
return this.rest.makeRequest('get', Constants.Endpoints.guildInvites(guild.id), true).then(inviteItems => {
const invites = new Collection();
for (const inviteItem of inviteItems) {
const invite = new Invite(this.rest.client, inviteItem);
invites.set(invite.code, invite);
}
return invites;
});
}
pruneGuildMembers(guild, days, dry) {
return this.rest.makeRequest(dry ? 'get' : 'post', `${Constants.Endpoints.guildPrune(guild.id)}?days=${days}`, true)
.then(data => data.pruned);
}
createEmoji(guild, image, name) {
return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, { name, image })
.then(data => this.rest.client.actions.EmojiCreate.handle(data, guild).emoji);
}
deleteEmoji(emoji) {
return this.rest.makeRequest('delete', `${Constants.Endpoints.guildEmojis(emoji.guild.id)}/${emoji.id}`, true)
.then(() => this.rest.client.actions.EmojiDelete.handle(emoji).data);
}
getWebhook(id, token) {
return this.rest.makeRequest('get', Constants.Endpoints.webhook(id, token), !token).then(data =>
new Webhook(this.rest.client, data)
);
}
getGuildWebhooks(guild) {
return this.rest.makeRequest('get', Constants.Endpoints.guildWebhooks(guild.id), true).then(data => {
const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.rest.client, hook));
return hooks;
});
}
getChannelWebhooks(channel) {
return this.rest.makeRequest('get', Constants.Endpoints.channelWebhooks(channel.id), true).then(data => {
const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.rest.client, hook));
return hooks;
});
}
createWebhook(channel, name, avatar) {
return this.rest.makeRequest('post', Constants.Endpoints.channelWebhooks(channel.id), true, { name, avatar })
.then(data => new Webhook(this.rest.client, data));
}
editWebhook(webhook, name, avatar) {
return this.rest.makeRequest('patch', Constants.Endpoints.webhook(webhook.id, webhook.token), false, {
name,
avatar,
}).then(data => {
webhook.name = data.name;
webhook.avatar = data.avatar;
return webhook;
});
}
deleteWebhook(webhook) {
return this.rest.makeRequest('delete', Constants.Endpoints.webhook(webhook.id, webhook.token), false);
}
sendWebhookMessage(webhook, content, { avatarURL, tts, disableEveryone, embeds } = {}, file = null) {
if (typeof content !== 'undefined') content = this.rest.client.resolver.resolveString(content);
if (content) {
if (disableEveryone || (typeof disableEveryone === 'undefined' && this.rest.client.options.disableEveryone)) {
content = content.replace(/@(everyone|here)/g, '@\u200b$1');
}
}
return this.rest.makeRequest('post', `${Constants.Endpoints.webhook(webhook.id, webhook.token)}?wait=true`, false, {
username: webhook.name,
avatar_url: avatarURL,
content,
tts,
file,
embeds,
});
}
sendSlackWebhookMessage(webhook, body) {
return this.rest.makeRequest(
'post', `${Constants.Endpoints.webhook(webhook.id, webhook.token)}/slack?wait=true`, false, body
);
}
fetchUserProfile(user) {
return this.rest.makeRequest('get', Constants.Endpoints.userProfile(user.id), true).then(data =>
new UserProfile(user, data)
);
}
addFriend(user) {
return this.rest.makeRequest('post', Constants.Endpoints.relationships('@me'), true, {
username: user.username,
discriminator: user.discriminator,
}).then(() => user);
}
removeFriend(user) {
return this.rest.makeRequest('delete', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true)
.then(() => user);
}
blockUser(user) {
return this.rest.makeRequest('put', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true, { type: 2 })
.then(() => user);
}
unblockUser(user) {
return this.rest.makeRequest('delete', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true)
.then(() => user);
}
setRolePositions(guildID, roles) {
return this.rest.makeRequest('patch', Constants.Endpoints.guildRoles(guildID), true, roles).then(() =>
this.rest.client.actions.GuildRolesPositionUpdate.handle({
guild_id: guildID,
roles,
}).guild
);
}
addMessageReaction(message, emoji) {
return this.rest.makeRequest(
'put', Constants.Endpoints.selfMessageReaction(message.channel.id, message.id, emoji), true
).then(() =>
this.rest.client.actions.MessageReactionAdd.handle({
user_id: this.rest.client.user.id,
message_id: message.id,
emoji: parseEmoji(emoji),
channel_id: message.channel.id,
}).reaction
);
}
removeMessageReaction(message, emoji, user) {
let endpoint = Constants.Endpoints.selfMessageReaction(message.channel.id, message.id, emoji);
if (user.id !== this.rest.client.user.id) {
endpoint = Constants.Endpoints.userMessageReaction(message.channel.id, message.id, emoji, null, user.id);
}
return this.rest.makeRequest('delete', endpoint, true).then(() =>
this.rest.client.actions.MessageReactionRemove.handle({
user_id: user.id,
message_id: message.id,
emoji: parseEmoji(emoji),
channel_id: message.channel.id,
}).reaction
);
}
removeMessageReactions(message) {
this.rest.makeRequest('delete', Constants.Endpoints.messageReactions(message.channel.id, message.id), true)
.then(() => message);
}
getMessageReactionUsers(message, emoji, limit = 100) {
return this.rest.makeRequest(
'get', Constants.Endpoints.messageReaction(message.channel.id, message.id, emoji, limit), true
);
}
getMyApplication() {
return this.rest.makeRequest('get', Constants.Endpoints.myApplication, true).then(app =>
new ClientOAuth2Application(this.rest.client, app)
);
}
setNote(user, note) {
return this.rest.makeRequest('put', Constants.Endpoints.note(user.id), true, { note }).then(() => user);
}
}
module.exports = RESTMethods;
/***/ },
/* 94 */
/***/ function(module, exports, __webpack_require__) {
const RequestHandler = __webpack_require__(46);
class BurstRequestHandler extends RequestHandler {
constructor(restManager, endpoint) {
super(restManager, endpoint);
this.requestRemaining = 1;
this.first = true;
}
push(request) {
super.push(request);
this.handle();
}
handleNext(time) {
if (this.waiting) return;
this.waiting = true;
this.restManager.client.setTimeout(() => {
this.requestRemaining = this.requestLimit;
this.waiting = false;
this.handle();
}, time);
}
execute(item) {
item.request.gen().end((err, res) => {
if (res && res.headers) {
this.requestLimit = res.headers['x-ratelimit-limit'];
this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.requestRemaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
this.handleNext((this.requestResetTime - Date.now()) + this.timeDifference + 1000);
}
if (err) {
if (err.status === 429) {
this.requestRemaining = 0;
this.queue.unshift(item);
this.restManager.client.setTimeout(() => {
this.globalLimit = false;
this.handle();
}, Number(res.headers['retry-after']) + 500);
if (res.headers['x-ratelimit-global']) {
this.globalLimit = true;
}
} else {
item.reject(err);
}
} else {
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
if (this.first) {
this.first = false;
this.handle();
}
}
});
}
handle() {
super.handle();
if (this.requestRemaining < 1 || this.queue.length === 0 || this.globalLimit) return;
while (this.queue.length > 0 && this.requestRemaining > 0) {
this.execute(this.queue.shift());
this.requestRemaining--;
}
}
}
module.exports = BurstRequestHandler;
/***/ },
/* 95 */
/***/ function(module, exports, __webpack_require__) {
const RequestHandler = __webpack_require__(46);
/**
* Handles API Requests sequentially, i.e. we wait until the current request is finished before moving onto
* the next. This plays a _lot_ nicer in terms of avoiding 429's when there is more than one session of the account,
* but it can be slower.
* @extends {RequestHandler}
* @private
*/
class SequentialRequestHandler extends RequestHandler {
/**
* @param {RESTManager} restManager The REST manager to use
* @param {string} endpoint The endpoint to handle
*/
constructor(restManager, endpoint) {
super(restManager, endpoint);
/**
* Whether this rate limiter is waiting for a response from a request
* @type {boolean}
*/
this.waiting = false;
/**
* The endpoint that this handler is handling
* @type {string}
*/
this.endpoint = endpoint;
/**
* The time difference between Discord's Dates and the local computer's Dates. A positive number means the local
* computer's time is ahead of Discord's.
* @type {number}
*/
this.timeDifference = 0;
}
push(request) {
super.push(request);
this.handle();
}
/**
* Performs a request then resolves a promise to indicate its readiness for a new request
* @param {APIRequest} item The item to execute
* @returns {Promise}
*/
execute(item) {
return new Promise(resolve => {
item.request.gen().end((err, res) => {
if (res && res.headers) {
this.requestLimit = res.headers['x-ratelimit-limit'];
this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.requestRemaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
}
if (err) {
if (err.status === 429) {
this.restManager.client.setTimeout(() => {
this.waiting = false;
this.globalLimit = false;
resolve();
}, Number(res.headers['retry-after']) + 500);
if (res.headers['x-ratelimit-global']) {
this.globalLimit = true;
}
} else {
this.queue.shift();
this.waiting = false;
item.reject(err);
resolve(err);
}
} else {
this.queue.shift();
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
if (this.requestRemaining === 0) {
this.restManager.client.setTimeout(() => {
this.waiting = false;
resolve(data);
}, (this.requestResetTime - Date.now()) + this.timeDifference + 1000);
} else {
this.waiting = false;
resolve(data);
}
}
});
});
}
handle() {
super.handle();
if (this.waiting || this.queue.length === 0 || this.globalLimit) return;
this.waiting = true;
const item = this.queue[0];
this.execute(item).then(() => this.handle());
}
}
module.exports = SequentialRequestHandler;
/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {
const Constants = __webpack_require__(0);
class UserAgentManager {
constructor(restManager) {
this.restManager = restManager;
this._userAgent = {
url: 'https://github.com/hydrabolt/discord.js',
version: Constants.Package.version,
};
}
set(info) {
this._userAgent.url = info.url || 'https://github.com/hydrabolt/discord.js';
this._userAgent.version = info.version || Constants.Package.version;
}
get userAgent() {
return `DiscordBot (${this._userAgent.url}, ${this._userAgent.version})`;
}
}
module.exports = UserAgentManager;
/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {
const browser = typeof window !== 'undefined';
const WebSocket = browser ? window.WebSocket : __webpack_require__(137); // eslint-disable-line no-undef
const EventEmitter = __webpack_require__(21).EventEmitter;
const Constants = __webpack_require__(0);
const inflate = browser ? __webpack_require__(62).inflateSync : __webpack_require__(43).inflateSync;
const PacketManager = __webpack_require__(98);
const convertArrayBuffer = __webpack_require__(47);
/**
* The WebSocket Manager of the Client
* @private
*/
class WebSocketManager extends EventEmitter {
constructor(client) {
super();
/**
* The Client that instantiated this WebSocketManager
* @type {Client}
*/
this.client = client;
/**
* A WebSocket Packet manager, it handles all the messages
* @type {PacketManager}
*/
this.packetManager = new PacketManager(this);
/**
* The status of the WebSocketManager, a type of Constants.Status. It defaults to IDLE.
* @type {number}
*/
this.status = Constants.Status.IDLE;
/**
* The session ID of the connection, null if not yet available.
* @type {?string}
*/
this.sessionID = null;
/**
* The packet count of the client, null if not yet available.
* @type {?number}
*/
this.sequence = -1;
/**
* The gateway address for this WebSocket connection, null if not yet available.
* @type {?string}
*/
this.gateway = null;
/**
* Whether READY was emitted normally (all packets received) or not
* @type {boolean}
*/
this.normalReady = false;
/**
* The WebSocket connection to the gateway
* @type {?WebSocket}
*/
this.ws = null;
/**
* An object with keys that are websocket event names that should be ignored
* @type {Object}
*/
this.disabledEvents = {};
for (const event in client.options.disabledEvents) this.disabledEvents[event] = true;
this.first = true;
}
/**
* Connects the client to a given gateway
* @param {string} gateway The gateway to connect to
*/
_connect(gateway) {
this.client.emit('debug', `Connecting to gateway ${gateway}`);
this.normalReady = false;
if (this.status !== Constants.Status.RECONNECTING) this.status = Constants.Status.CONNECTING;
this.ws = new WebSocket(gateway);
if (browser) this.ws.binaryType = 'arraybuffer';
this.ws.onopen = () => this.eventOpen();
this.ws.onclose = (d) => this.eventClose(d);
this.ws.onmessage = (e) => this.eventMessage(e);
this.ws.onerror = (e) => this.eventError(e);
this._queue = [];
this._remaining = 3;
}
connect(gateway) {
if (this.first) {
this._connect(gateway);
this.first = false;
} else {
this.client.setTimeout(() => this._connect(gateway), 5500);
}
}
/**
* Sends a packet to the gateway
* @param {Object} data An object that can be JSON stringified
* @param {boolean} force Whether or not to send the packet immediately
*/
send(data, force = false) {
if (force) {
this._send(JSON.stringify(data));
return;
}
this._queue.push(JSON.stringify(data));
this.doQueue();
}
destroy() {
this.ws.close(1000);
this._queue = [];
this.status = Constants.Status.IDLE;
}
_send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.emit('send', data);
this.ws.send(data);
}
}
doQueue() {
const item = this._queue[0];
if (this.ws.readyState === WebSocket.OPEN && item) {
if (this._remaining === 0) {
this.client.setTimeout(this.doQueue.bind(this), 1000);
return;
}
this._remaining--;
this._send(item);
this._queue.shift();
this.doQueue();
this.client.setTimeout(() => this._remaining++, 1000);
}
}
/**
* Run whenever the gateway connections opens up
*/
eventOpen() {
this.client.emit('debug', 'Connection to gateway opened');
if (this.status === Constants.Status.RECONNECTING) this._sendResume();
else this._sendNewIdentify();
}
/**
* Sends a gateway resume packet, in cases of unexpected disconnections.
*/
_sendResume() {
if (!this.sessionID) {
this._sendNewIdentify();
return;
}
this.client.emit('debug', 'Identifying as resumed session');
const payload = {
token: this.client.token,
session_id: this.sessionID,
seq: this.sequence,
};
this.send({
op: Constants.OPCodes.RESUME,
d: payload,
});
}
/**
* Sends a new identification packet, in cases of new connections or failed reconnections.
*/
_sendNewIdentify() {
this.reconnecting = false;
const payload = this.client.options.ws;
payload.token = this.client.token;
if (this.client.options.shardCount > 0) {
payload.shard = [Number(this.client.options.shardId), Number(this.client.options.shardCount)];
}
this.client.emit('debug', 'Identifying as new session');
this.send({
op: Constants.OPCodes.IDENTIFY,
d: payload,
});
this.sequence = -1;
}
/**
* Run whenever the connection to the gateway is closed, it will try to reconnect the client.
* @param {Object} event The received websocket data
*/
eventClose(event) {
this.emit('close', event);
this.client.clearInterval(this.client.manager.heartbeatInterval);
/**
* Emitted whenever the client websocket is disconnected
* @event Client#disconnect
*/
if (!this.reconnecting) this.client.emit(Constants.Events.DISCONNECT);
if (event.code === 4004) return;
if (event.code === 4010) return;
if (!this.reconnecting && event.code !== 1000) this.tryReconnect();
}
/**
* Run whenever a message is received from the WebSocket. Returns `true` if the message
* was handled properly.
* @param {Object} event The received websocket data
* @returns {boolean}
*/
eventMessage(event) {
const data = this.tryParseEventData(event.data);
if (data === null) {
this.eventError(new Error(Constants.Errors.BAD_WS_MESSAGE));
return false;
}
this.client.emit('raw', data);
if (data.op === Constants.OPCodes.HELLO) this.client.manager.setupKeepAlive(data.d.heartbeat_interval);
return this.packetManager.handle(data);
}
/**
* Parses the raw data from a websocket event, inflating it if necessary
* @param {*} data Event data
* @returns {Object}
*/
parseEventData(data) {
if (typeof data !== 'string') {
if (data instanceof ArrayBuffer) data = convertArrayBuffer(data);
data = inflate(data).toString();
}
return JSON.parse(data);
}
/**
* Tries to call `parseEventData()` and return its result, or returns `null` upon thrown errors.
* @param {*} data Event data
* @returns {?Object}
*/
tryParseEventData(data) {
try {
return this.parseEventData(data);
} catch (err) {
return null;
}
}
/**
* Run whenever an error occurs with the WebSocket connection. Tries to reconnect
* @param {Error} err The encountered error
*/
eventError(err) {
/**
* Emitted whenever the Client encounters a serious connection error
* @event Client#error
* @param {Error} error The encountered error
*/
if (this.client.listenerCount('error') > 0) this.client.emit('error', err);
this.ws.close();
}
_emitReady(normal = true) {
/**
* Emitted when the Client becomes ready to start working
* @event Client#ready
*/
this.status = Constants.Status.READY;
this.client.emit(Constants.Events.READY);
this.packetManager.handleQueue();
this.normalReady = normal;
}
/**
* Runs on new packets before `READY` to see if the Client is ready yet, if it is prepares
* the `READY` event.
*/
checkIfReady() {
if (this.status !== Constants.Status.READY && this.status !== Constants.Status.NEARLY) {
let unavailableCount = 0;
for (const guildID of this.client.guilds.keys()) {
unavailableCount += this.client.guilds.get(guildID).available ? 0 : 1;
}
if (unavailableCount === 0) {
this.status = Constants.Status.NEARLY;
if (this.client.options.fetchAllMembers) {
const promises = this.client.guilds.map(g => g.fetchMembers());
Promise.all(promises).then(() => this._emitReady(), e => {
this.client.emit(Constants.Events.WARN, 'Error in pre-ready guild member fetching');
this.client.emit(Constants.Events.ERROR, e);
this._emitReady();
});
return;
}
this._emitReady();
}
}
}
/**
* Tries to reconnect the client, changing the status to Constants.Status.RECONNECTING.
*/
tryReconnect() {
this.status = Constants.Status.RECONNECTING;
this.ws.close();
this.packetManager.handleQueue();
/**
* Emitted when the Client tries to reconnect after being disconnected
* @event Client#reconnecting
*/
this.client.emit(Constants.Events.RECONNECTING);
this.connect(this.client.ws.gateway);
}
}
module.exports = WebSocketManager;
/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {
const Constants = __webpack_require__(0);
const BeforeReadyWhitelist = [
Constants.WSEvents.READY,
Constants.WSEvents.GUILD_CREATE,
Constants.WSEvents.GUILD_DELETE,
Constants.WSEvents.GUILD_MEMBERS_CHUNK,
Constants.WSEvents.GUILD_MEMBER_ADD,
Constants.WSEvents.GUILD_MEMBER_REMOVE,
];
class WebSocketPacketManager {
constructor(websocketManager) {
this.ws = websocketManager;
this.handlers = {};
this.queue = [];
this.register(Constants.WSEvents.READY, __webpack_require__(124));
this.register(Constants.WSEvents.GUILD_CREATE, __webpack_require__(105));
this.register(Constants.WSEvents.GUILD_DELETE, __webpack_require__(106));
this.register(Constants.WSEvents.GUILD_UPDATE, __webpack_require__(115));
this.register(Constants.WSEvents.GUILD_BAN_ADD, __webpack_require__(103));
this.register(Constants.WSEvents.GUILD_BAN_REMOVE, __webpack_require__(104));
this.register(Constants.WSEvents.GUILD_MEMBER_ADD, __webpack_require__(107));
this.register(Constants.WSEvents.GUILD_MEMBER_REMOVE, __webpack_require__(108));
this.register(Constants.WSEvents.GUILD_MEMBER_UPDATE, __webpack_require__(109));
this.register(Constants.WSEvents.GUILD_ROLE_CREATE, __webpack_require__(111));
this.register(Constants.WSEvents.GUILD_ROLE_DELETE, __webpack_require__(112));
this.register(Constants.WSEvents.GUILD_ROLE_UPDATE, __webpack_require__(113));
this.register(Constants.WSEvents.GUILD_MEMBERS_CHUNK, __webpack_require__(110));
this.register(Constants.WSEvents.CHANNEL_CREATE, __webpack_require__(99));
this.register(Constants.WSEvents.CHANNEL_DELETE, __webpack_require__(100));
this.register(Constants.WSEvents.CHANNEL_UPDATE, __webpack_require__(102));
this.register(Constants.WSEvents.CHANNEL_PINS_UPDATE, __webpack_require__(101));
this.register(Constants.WSEvents.PRESENCE_UPDATE, __webpack_require__(123));
this.register(Constants.WSEvents.USER_UPDATE, __webpack_require__(129));
this.register(Constants.WSEvents.USER_NOTE_UPDATE, __webpack_require__(128));
this.register(Constants.WSEvents.VOICE_STATE_UPDATE, __webpack_require__(131));
this.register(Constants.WSEvents.TYPING_START, __webpack_require__(127));
this.register(Constants.WSEvents.MESSAGE_CREATE, __webpack_require__(116));
this.register(Constants.WSEvents.MESSAGE_DELETE, __webpack_require__(117));
this.register(Constants.WSEvents.MESSAGE_UPDATE, __webpack_require__(122));
this.register(Constants.WSEvents.MESSAGE_DELETE_BULK, __webpack_require__(118));
this.register(Constants.WSEvents.VOICE_SERVER_UPDATE, __webpack_require__(130));
this.register(Constants.WSEvents.GUILD_SYNC, __webpack_require__(114));
this.register(Constants.WSEvents.RELATIONSHIP_ADD, __webpack_require__(125));
this.register(Constants.WSEvents.RELATIONSHIP_REMOVE, __webpack_require__(126));
this.register(Constants.WSEvents.MESSAGE_REACTION_ADD, __webpack_require__(119));
this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE, __webpack_require__(120));
this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE_ALL, __webpack_require__(121));
}
get client() {
return this.ws.client;
}
register(event, Handler) {
this.handlers[event] = new Handler(this);
}
handleQueue() {
this.queue.forEach((element, index) => {
this.handle(this.queue[index]);
this.queue.splice(index, 1);
});
}
setSequence(s) {
if (s && s > this.ws.sequence) this.ws.sequence = s;
}
handle(packet) {
if (packet.op === Constants.OPCodes.RECONNECT) {
this.setSequence(packet.s);
this.ws.tryReconnect();
return false;
}
if (packet.op === Constants.OPCodes.INVALID_SESSION) {
this.ws.sessionID = null;
this.ws._sendNewIdentify();
return false;
}
if (packet.op === Constants.OPCodes.HEARTBEAT_ACK) this.ws.client.emit('debug', 'Heartbeat acknowledged');
if (this.ws.status === Constants.Status.RECONNECTING) {
this.ws.reconnecting = false;
this.ws.checkIfReady();
}
this.setSequence(packet.s);
if (this.ws.disabledEvents[packet.t] !== undefined) return false;
if (this.ws.status !== Constants.Status.READY) {
if (BeforeReadyWhitelist.indexOf(packet.t) === -1) {
this.queue.push(packet);
return false;
}
}
if (this.handlers[packet.t]) return this.handlers[packet.t].handle(packet);
return false;
}
}
module.exports = WebSocketPacketManager;
/***/ },
/* 99 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class ChannelCreateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.ChannelCreate.handle(data);
}
}
/**
* Emitted whenever a channel is created.
* @event Client#channelCreate
* @param {Channel} channel The channel that was created
*/
module.exports = ChannelCreateHandler;
/***/ },
/* 100 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class ChannelDeleteHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const response = client.actions.ChannelDelete.handle(data);
if (response.channel) client.emit(Constants.Events.CHANNEL_DELETE, response.channel);
}
}
/**
* Emitted whenever a channel is deleted.
* @event Client#channelDelete
* @param {Channel} channel The channel that was deleted
*/
module.exports = ChannelDeleteHandler;
/***/ },
/* 101 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
/*
{ t: 'CHANNEL_PINS_UPDATE',
s: 666,
op: 0,
d:
{ last_pin_timestamp: '2016-08-28T17:37:13.171774+00:00',
channel_id: '314866471639044027' } }
*/
class ChannelPinsUpdate extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const channel = client.channels.get(data.channel_id);
const time = new Date(data.last_pin_timestamp);
if (channel && time) client.emit(Constants.Events.CHANNEL_PINS_UPDATE, channel, time);
}
}
/**
* Emitted whenever the pins of a channel are updated. Due to the nature of the WebSocket event, not much information
* can be provided easily here - you need to manually check the pins yourself.
* @event Client#channelPinsUpdate
* @param {Channel} channel The channel that the pins update occured in
* @param {Date} time The time of the pins update
*/
module.exports = ChannelPinsUpdate;
/***/ },
/* 102 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class ChannelUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.ChannelUpdate.handle(data);
}
}
module.exports = ChannelUpdateHandler;
/***/ },
/* 103 */
/***/ function(module, exports, __webpack_require__) {
// ##untested handler##
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class GuildBanAddHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.guild_id);
const user = client.users.get(data.user.id);
if (guild && user) client.emit(Constants.Events.GUILD_BAN_ADD, guild, user);
}
}
/**
* Emitted whenever a member is banned from a guild.
* @event Client#guildBanAdd
* @param {Guild} guild The guild that the ban occurred in
* @param {User} user The user that was banned
*/
module.exports = GuildBanAddHandler;
/***/ },
/* 104 */
/***/ function(module, exports, __webpack_require__) {
// ##untested handler##
const AbstractHandler = __webpack_require__(1);
class GuildBanRemoveHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildBanRemove.handle(data);
}
}
/**
* Emitted whenever a member is unbanned from a guild.
* @event Client#guildBanRemove
* @param {Guild} guild The guild that the unban occurred in
* @param {User} user The user that was unbanned
*/
module.exports = GuildBanRemoveHandler;
/***/ },
/* 105 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildCreateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.id);
if (guild) {
if (!guild.available && !data.unavailable) {
// a newly available guild
guild.setup(data);
this.packetManager.ws.checkIfReady();
}
} else {
// a new guild
client.dataManager.newGuild(data);
}
}
}
module.exports = GuildCreateHandler;
/***/ },
/* 106 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class GuildDeleteHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const response = client.actions.GuildDelete.handle(data);
if (response.guild) client.emit(Constants.Events.GUILD_DELETE, response.guild);
}
}
/**
* Emitted whenever a guild is deleted/left.
* @event Client#guildDelete
* @param {Guild} guild The guild that was deleted
*/
module.exports = GuildDeleteHandler;
/***/ },
/* 107 */
/***/ function(module, exports, __webpack_require__) {
// ##untested handler##
const AbstractHandler = __webpack_require__(1);
class GuildMemberAddHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.guild_id);
if (guild) {
guild.memberCount++;
guild._addMember(data);
}
}
}
module.exports = GuildMemberAddHandler;
/***/ },
/* 108 */
/***/ function(module, exports, __webpack_require__) {
// ##untested handler##
const AbstractHandler = __webpack_require__(1);
class GuildMemberRemoveHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildMemberRemove.handle(data);
}
}
module.exports = GuildMemberRemoveHandler;
/***/ },
/* 109 */
/***/ function(module, exports, __webpack_require__) {
// ##untested handler##
const AbstractHandler = __webpack_require__(1);
class GuildMemberUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.guild_id);
if (guild) {
const member = guild.members.get(data.user.id);
if (member) guild._updateMember(member, data);
}
}
}
module.exports = GuildMemberUpdateHandler;
/***/ },
/* 110 */
/***/ function(module, exports, __webpack_require__) {
// ##untested##
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class GuildMembersChunkHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.guild_id);
const members = [];
if (guild) {
for (const member of data.members) members.push(guild._addMember(member, false));
}
guild._checkChunks();
client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members);
}
}
/**
* Emitted whenever a chunk of guild members is received (all members come from the same guild)
* @event Client#guildMembersChunk
* @param {GuildMember[]} members The members in the chunk
*/
module.exports = GuildMembersChunkHandler;
/***/ },
/* 111 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildRoleCreateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildRoleCreate.handle(data);
}
}
module.exports = GuildRoleCreateHandler;
/***/ },
/* 112 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildRoleDeleteHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildRoleDelete.handle(data);
}
}
module.exports = GuildRoleDeleteHandler;
/***/ },
/* 113 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildRoleUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildRoleUpdate.handle(data);
}
}
module.exports = GuildRoleUpdateHandler;
/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildSyncHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildSync.handle(data);
}
}
module.exports = GuildSyncHandler;
/***/ },
/* 115 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class GuildUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.GuildUpdate.handle(data);
}
}
module.exports = GuildUpdateHandler;
/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class MessageCreateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const response = client.actions.MessageCreate.handle(data);
if (response.message) client.emit(Constants.Events.MESSAGE_CREATE, response.message);
}
}
/**
* Emitted whenever a message is created
* @event Client#message
* @param {Message} message The created message
*/
module.exports = MessageCreateHandler;
/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class MessageDeleteHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const response = client.actions.MessageDelete.handle(data);
if (response.message) client.emit(Constants.Events.MESSAGE_DELETE, response.message);
}
}
/**
* Emitted whenever a message is deleted
* @event Client#messageDelete
* @param {Message} message The deleted message
*/
module.exports = MessageDeleteHandler;
/***/ },
/* 118 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class MessageDeleteBulkHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageDeleteBulk.handle(data);
}
}
/**
* Emitted whenever messages are deleted in bulk
* @event Client#messageDeleteBulk
* @param {Collection} messages The deleted messages, mapped by their ID
*/
module.exports = MessageDeleteBulkHandler;
/***/ },
/* 119 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class MessageReactionAddHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageReactionAdd.handle(data);
}
}
module.exports = MessageReactionAddHandler;
/***/ },
/* 120 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class MessageReactionRemove extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageReactionRemove.handle(data);
}
}
module.exports = MessageReactionRemove;
/***/ },
/* 121 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class MessageReactionRemoveAll extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageReactionRemoveAll.handle(data);
}
}
module.exports = MessageReactionRemoveAll;
/***/ },
/* 122 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class MessageUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageUpdate.handle(data);
}
}
module.exports = MessageUpdateHandler;
/***/ },
/* 123 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class PresenceUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
let user = client.users.get(data.user.id);
const guild = client.guilds.get(data.guild_id);
// step 1
if (!user) {
if (data.user.username) {
user = client.dataManager.newUser(data.user);
} else {
return;
}
}
const oldUser = cloneObject(user);
user.patch(data.user);
if (!user.equals(oldUser)) {
client.emit(Constants.Events.USER_UPDATE, oldUser, user);
}
if (guild) {
let member = guild.members.get(user.id);
if (!member && data.status !== 'offline') {
member = guild._addMember({
user,
roles: data.roles,
deaf: false,
mute: false,
}, false);
client.emit(Constants.Events.GUILD_MEMBER_AVAILABLE, member);
}
if (member) {
const oldMember = cloneObject(member);
if (member.presence) {
oldMember.frozenPresence = cloneObject(member.presence);
}
guild._setPresence(user.id, data);
client.emit(Constants.Events.PRESENCE_UPDATE, oldMember, member);
} else {
guild._setPresence(user.id, data);
}
}
}
}
/**
* Emitted whenever a guild member's presence changes, or they change one of their details.
* @event Client#presenceUpdate
* @param {GuildMember} oldMember The member before the presence update
* @param {GuildMember} newMember The member after the presence update
*/
/**
* Emitted whenever a user's details (e.g. username) are changed.
* @event Client#userUpdate
* @param {User} oldUser The user before the update
* @param {User} newUser The user after the update
*/
/**
* Emitted whenever a member becomes available in a large guild
* @event Client#guildMemberAvailable
* @param {GuildMember} member The member that became available
*/
module.exports = PresenceUpdateHandler;
/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const ClientUser = __webpack_require__(27);
class ReadyHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const clientUser = new ClientUser(client, data.user);
client.user = clientUser;
client.readyAt = new Date();
client.users.set(clientUser.id, clientUser);
for (const guild of data.guilds) client.dataManager.newGuild(guild);
for (const privateDM of data.private_channels) client.dataManager.newChannel(privateDM);
for (const relation of data.relationships) {
const user = client.dataManager.newUser(relation.user);
if (relation.type === 1) {
client.user.friends.set(user.id, user);
} else if (relation.type === 2) {
client.user.blocked.set(user.id, user);
}
}
data.presences = data.presences || [];
for (const presence of data.presences) {
client.dataManager.newUser(presence.user);
client._setPresence(presence.user.id, presence);
}
if (data.notes) {
for (const user in data.notes) {
let note = data.notes[user];
if (!note.length) note = null;
client.user.notes.set(user, note);
}
}
if (!client.user.bot && client.options.sync) client.setInterval(client.syncGuilds.bind(client), 30000);
client.once('ready', client.syncGuilds.bind(client));
if (!client.users.has('1')) {
client.dataManager.newUser({
id: '1',
username: 'Clyde',
discriminator: '0000',
avatar: 'https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png',
bot: true,
status: 'online',
game: null,
verified: true,
});
}
client.setTimeout(() => {
if (!client.ws.normalReady) client.ws._emitReady(false);
}, 1200 * data.guilds.length);
this.packetManager.ws.sessionID = data.session_id;
this.packetManager.ws.checkIfReady();
}
}
module.exports = ReadyHandler;
/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class RelationshipAddHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
if (data.type === 1) {
client.fetchUser(data.id).then(user => {
client.user.friends.set(user.id, user);
});
} else if (data.type === 2) {
client.fetchUser(data.id).then(user => {
client.user.blocked.set(user.id, user);
});
}
}
}
module.exports = RelationshipAddHandler;
/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class RelationshipRemoveHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
if (data.type === 2) {
if (client.user.blocked.has(data.id)) {
client.user.blocked.delete(data.id);
}
} else if (data.type === 1) {
if (client.user.friends.has(data.id)) {
client.user.friends.delete(data.id);
}
}
}
}
module.exports = RelationshipRemoveHandler;
/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
class TypingStartHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const channel = client.channels.get(data.channel_id);
const user = client.users.get(data.user_id);
const timestamp = new Date(data.timestamp * 1000);
if (channel && user) {
if (channel.type === 'voice') {
client.emit(Constants.Events.WARN, `Discord sent a typing packet to voice channel ${channel.id}`);
return;
}
if (channel._typing.has(user.id)) {
const typing = channel._typing.get(user.id);
typing.lastTimestamp = timestamp;
typing.resetTimeout(tooLate(channel, user));
} else {
channel._typing.set(user.id, new TypingData(client, timestamp, timestamp, tooLate(channel, user)));
client.emit(Constants.Events.TYPING_START, channel, user);
}
}
}
}
class TypingData {
constructor(client, since, lastTimestamp, _timeout) {
this.client = client;
this.since = since;
this.lastTimestamp = lastTimestamp;
this._timeout = _timeout;
}
resetTimeout(_timeout) {
this.client.clearTimeout(this._timeout);
this._timeout = _timeout;
}
get elapsedTime() {
return Date.now() - this.since;
}
}
function tooLate(channel, user) {
return channel.client.setTimeout(() => {
channel.client.emit(Constants.Events.TYPING_STOP, channel, user, channel._typing.get(user.id));
channel._typing.delete(user.id);
}, 6000);
}
/**
* Emitted whenever a user starts typing in a channel
* @event Client#typingStart
* @param {Channel} channel The channel the user started typing in
* @param {User} user The user that started typing
*/
/**
* Emitted whenever a user stops typing in a channel
* @event Client#typingStop
* @param {Channel} channel The channel the user stopped typing in
* @param {User} user The user that stopped typing
*/
module.exports = TypingStartHandler;
/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class UserNoteUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.UserNoteUpdate.handle(data);
}
}
module.exports = UserNoteUpdateHandler;
/***/ },
/* 129 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
class UserUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.UserUpdate.handle(data);
}
}
module.exports = UserUpdateHandler;
/***/ },
/* 130 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
/*
{
"token": "my_token",
"guild_id": "41771983423143937",
"endpoint": "smart.loyal.discord.gg"
}
*/
class VoiceServerUpdate extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.emit('self.voiceServer', data);
}
}
module.exports = VoiceServerUpdate;
/***/ },
/* 131 */
/***/ function(module, exports, __webpack_require__) {
const AbstractHandler = __webpack_require__(1);
const Constants = __webpack_require__(0);
const cloneObject = __webpack_require__(4);
class VoiceStateUpdateHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
const guild = client.guilds.get(data.guild_id);
if (guild) {
const member = guild.members.get(data.user_id);
if (member) {
const oldVoiceChannelMember = cloneObject(member);
if (member.voiceChannel && member.voiceChannel.id !== data.channel_id) {
member.voiceChannel.members.delete(oldVoiceChannelMember.id);
}
// if the member left the voice channel, unset their speaking property
if (!data.channel_id) member.speaking = null;
if (member.user.id === client.user.id && data.channel_id) {
client.emit('self.voiceStateUpdate', data);
}
const newChannel = client.channels.get(data.channel_id);
if (newChannel) newChannel.members.set(member.user.id, member);
member.serverMute = data.mute;
member.serverDeaf = data.deaf;
member.selfMute = data.self_mute;
member.selfDeaf = data.self_deaf;
member.voiceSessionID = data.session_id;
member.voiceChannelID = data.channel_id;
client.emit(Constants.Events.VOICE_STATE_UPDATE, oldVoiceChannelMember, member);
}
}
}
}
/**
* Emitted whenever a user changes voice state - e.g. joins/leaves a channel, mutes/unmutes.
* @event Client#voiceStateUpdate
* @param {GuildMember} oldMember The member before the voice state update
* @param {GuildMember} newMember The member after the voice state update
*/
module.exports = VoiceStateUpdateHandler;
/***/ },
/* 132 */
/***/ function(module, exports) {
/**
* Represents a user connection (or "platform identity")
*/
class UserConnection {
constructor(user, data) {
/**
* The user that owns the Connection
* @type {User}
*/
this.user = user;
this.setup(data);
}
setup(data) {
/**
* The type of the Connection
* @type {string}
*/
this.type = data.type;
/**
* The username of the connection account
* @type {string}
*/
this.name = data.name;
/**
* The id of the connection account
* @type {string}
*/
this.id = data.id;
/**
* Whether the connection is revoked
* @type {Boolean}
*/
this.revoked = data.revoked;
/**
* an array of partial server integrations (not yet implemented in this lib)
* @type {Object[]}
*/
this.integrations = data.integrations;
}
}
module.exports = UserConnection;
/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {
const Collection = __webpack_require__(3);
const UserConnection = __webpack_require__(132);
/**
* Represents a user's profile on Discord.
*/
class UserProfile {
constructor(user, data) {
/**
* The owner of the profile
* @type {User}
*/
this.user = user;
/**
* The Client that created the instance of the the UserProfile.
* @type {Client}
*/
this.client = this.user.client;
Object.defineProperty(this, 'client', { enumerable: false, configurable: false });
/**
* Guilds that the client user and the user share
* @type {Collection}
*/
this.mutualGuilds = new Collection();
/**
* The user's connections
* @type {Collection}
*/
this.connections = new Collection();
this.setup(data);
}
setup(data) {
for (const guild of data.mutual_guilds) {
if (this.client.guilds.has(guild.id)) {
this.mutualGuilds.set(guild.id, this.client.guilds.get(guild.id));
}
}
for (const connection of data.connected_accounts) {
this.connections.set(connection.id, new UserConnection(this.user, connection));
}
}
}
module.exports = UserProfile;
/***/ },
/* 134 */
/***/ function(module, exports) {
module.exports = function parseEmoji(text) {
if (text.includes('%')) {
text = decodeURIComponent(text);
}
if (text.includes(':')) {
const [name, id] = text.split(':');
return { name, id };
} else {
return {
name: text,
id: null,
};
}
};
/***/ },
/* 135 */
/***/ function(module, exports) {
/* (ignored) */
/***/ },
/* 136 */
/***/ function(module, exports) {
/* (ignored) */
/***/ },
/* 137 */
/***/ function(module, exports) {
/* (ignored) */
/***/ },
/* 138 */
/***/ function(module, exports, __webpack_require__) {
module.exports = {
Client: __webpack_require__(49),
WebhookClient: __webpack_require__(50),
Shard: __webpack_require__(52),
ShardClientUtil: __webpack_require__(53),
ShardingManager: __webpack_require__(54),
Collection: __webpack_require__(3),
splitMessage: __webpack_require__(41),
escapeMarkdown: __webpack_require__(14),
fetchRecommendedShards: __webpack_require__(51),
Channel: __webpack_require__(8),
ClientOAuth2Application: __webpack_require__(26),
ClientUser: __webpack_require__(27),
DMChannel: __webpack_require__(28),
Emoji: __webpack_require__(9),
EvaluatedPermissions: __webpack_require__(17),
Game: __webpack_require__(6).Game,
GroupDMChannel: __webpack_require__(29),
Guild: __webpack_require__(18),
GuildChannel: __webpack_require__(11),
GuildMember: __webpack_require__(12),
Invite: __webpack_require__(30),
Message: __webpack_require__(13),
MessageAttachment: __webpack_require__(31),
MessageCollector: __webpack_require__(32),
MessageEmbed: __webpack_require__(33),
MessageReaction: __webpack_require__(34),
OAuth2Application: __webpack_require__(35),
PartialGuild: __webpack_require__(36),
PartialGuildChannel: __webpack_require__(37),
PermissionOverwrites: __webpack_require__(38),
Presence: __webpack_require__(6).Presence,
ReactionEmoji: __webpack_require__(19),
Role: __webpack_require__(7),
TextChannel: __webpack_require__(39),
User: __webpack_require__(5),
VoiceChannel: __webpack_require__(40),
Webhook: __webpack_require__(20),
version: __webpack_require__(25).version,
};
if (typeof window !== 'undefined') window.Discord = module.exports; // eslint-disable-line no-undef
/***/ }
/******/ ]);