diff --git a/lib/src/events/GuildCreateEvent.dart b/lib/src/events/GuildCreateEvent.dart index 38bb4cd..b4fed4d 100644 --- a/lib/src/events/GuildCreateEvent.dart +++ b/lib/src/events/GuildCreateEvent.dart @@ -5,35 +5,16 @@ class GuildCreateEvent { /// The guild created. Guild guild; - GuildCreateEvent._new(Client client, Map json, _WS ws) { + GuildCreateEvent._new(Client client, Map json, Shard shard) { this.guild = new Guild._new(client, json['d'] as Map, true, true); - if (!client.ready) { - bool match = true; - client.guilds.forEach((String id, Guild o) { - if (o == null) match = false; - }); - - bool match2 = true; - ws.client.shards.forEach((int id, Shard s) { - if (!s.ready) match = false; - }); + if (shard._ws.client._options.forceFetchMembers) + shard._send("REQUEST_GUILD_MEMBERS", + {"guild_id": guild.id, "query": "", "limit": 0}); - if (match && match2) { - client.ready = true; - if (client.user.bot) { - client._http - .get('/oauth2/applications/@me', true) - .then((_HttpResponse r) { - client.app = new ClientOAuth2Application._new( - client, r.json as Map); - new ReadyEvent._new(client); - }); - } else { - new ReadyEvent._new(client); - } - } + if (!client.ready) { + shard._ws.testReady(); } else { client._events.onGuildCreate.add(this); } diff --git a/lib/src/events/GuildMemberAddEvent.dart b/lib/src/events/GuildMemberAddEvent.dart index 35a81e8..8c1669a 100644 --- a/lib/src/events/GuildMemberAddEvent.dart +++ b/lib/src/events/GuildMemberAddEvent.dart @@ -8,6 +8,7 @@ class GuildMemberAddEvent { GuildMemberAddEvent._new(Client client, Map json) { if (client.ready) { final Guild guild = client.guilds[json['d']['guild_id']]; + guild.memberCount++; this.member = new Member._new(client, json['d'] as Map, guild); client._events.onGuildMemberAdd.add(this); diff --git a/lib/src/events/GuildMemberRemoveEvent.dart b/lib/src/events/GuildMemberRemoveEvent.dart index e593a86..11efcd3 100644 --- a/lib/src/events/GuildMemberRemoveEvent.dart +++ b/lib/src/events/GuildMemberRemoveEvent.dart @@ -11,6 +11,7 @@ class GuildMemberRemoveEvent { GuildMemberRemoveEvent._new(Client client, Map json) { if (client.ready && json['d']['user']['id'] != client.user.id) { this.guild = client.guilds[json['d']['guild_id']]; + guild.memberCount--; this.user = new User._new(client, json['d']['user'] as Map); guild.members.remove(user.id); diff --git a/lib/src/internal/_WS.dart b/lib/src/internal/_WS.dart index f4f2db3..95279ee 100644 --- a/lib/src/internal/_WS.dart +++ b/lib/src/internal/_WS.dart @@ -47,30 +47,7 @@ class _WS { shard.onReady.stream.listen((Shard s) { if (!client.ready) { - bool match = true; - client.guilds.forEach((String id, Guild o) { - if (o == null) match = false; - }); - - bool match2 = true; - client.shards.forEach((int id, Shard s) { - if (!s.ready) match = false; - }); - - if (match && match2) { - client.ready = true; - if (client.user.bot) { - client._http - .get('/oauth2/applications/@me', true) - .then((_HttpResponse r) { - client.app = new ClientOAuth2Application._new( - client, r.json as Map); - new ReadyEvent._new(client); - }); - } else { - new ReadyEvent._new(client); - } - } + testReady(); } }); } @@ -87,4 +64,35 @@ class _WS { if (index + 1 != this.client._options.shardIds.length) new Timer(new Duration(seconds: 6), () => connectShard(index + 1)); } + + void testReady() { + bool match = true; + client.guilds.forEach((String id, Guild o) { + if (client._options.forceFetchMembers) { + if (o == null || o.members.length != o.memberCount) match = false; + } else { + if (o == null) match = false; + } + }); + + bool match2 = true; + this.client.shards.forEach((int id, Shard s) { + if (!s.ready) match = false; + }); + + if (match && match2) { + client.ready = true; + if (client.user.bot) { + client._http + .get('/oauth2/applications/@me', true) + .then((_HttpResponse r) { + client.app = new ClientOAuth2Application._new( + client, r.json as Map); + new ReadyEvent._new(client); + }); + } else { + new ReadyEvent._new(client); + } + } + } } diff --git a/lib/src/objects/ClientOptions.dart b/lib/src/objects/ClientOptions.dart index 72b9a41..477d00a 100644 --- a/lib/src/objects/ClientOptions.dart +++ b/lib/src/objects/ClientOptions.dart @@ -22,6 +22,11 @@ class ClientOptions { /// Ex: `onMessageUpdate`. bool ignoreUncachedEvents; + /// Whether or not to force fetch all of the members the client can see. + /// Can slow down ready times but is recommended if you rely on `Message.member` + /// or the member cache. + bool forceFetchMembers; + /// A list of discord formatted events to be disabled. Note: some of these events /// can be dangerous to disable. Ex: `TYPING_START` List disabledEvents; @@ -34,5 +39,6 @@ class ClientOptions { this.shardCount: 1, this.disabledEvents: const [], this.messageCacheSize: 200, - this.ignoreUncachedEvents: true}); + this.ignoreUncachedEvents: true, + this.forceFetchMembers: true}); } diff --git a/lib/src/objects/Shard.dart b/lib/src/objects/Shard.dart index 4837728..bfb63c4 100644 --- a/lib/src/objects/Shard.dart +++ b/lib/src/objects/Shard.dart @@ -131,6 +131,16 @@ class Shard extends _BaseObj { this.onReady.add(this); break; + case 'GUILD_MEMBERS_CHUNK': + json['d']['members'].forEach((Map o) { + new Member._new(this._ws.client, o, + this._ws.client.guilds[json['d']['guild_id']]); + }); + if (!_ws.client.ready) { + _ws.testReady(); + } + break; + case 'MESSAGE_CREATE': MessageEvent msgEvent = new MessageEvent._new(this._ws.client, json); @@ -156,7 +166,7 @@ class Shard extends _BaseObj { break; case 'GUILD_CREATE': - new GuildCreateEvent._new(this._ws.client, json, this._ws); + new GuildCreateEvent._new(this._ws.client, json, this); break; case 'GUILD_UPDATE':