Alright so this really needs a page of its own because it's special. There's no actual api endpoint to get the guild members, so instead you have 2 options:
1) fetch the member list sidebar (guild.members.fetchMemberList, which uses opcode 14)
- when to use: if you can see any categories/channels in the guild
- pro: fast
- con: for large servers (```guild.memberCount > 1000```), only not-offline members are fetched
2) search for members by query (guild.members.fetchBruteforce, which uses opcode 8)
- when to use: if you cannot see any categories/channels in the guild
- pro: can potentially get the entire member list, can scrape members from multiple guilds at the same time
- con: slow af (speed is dependent on brute forcer optimizations)
____________________________________
# Links/Table of Contents
- [fetch the member list sidebar (faster, but less members)](#fetch-the-member-list-sidebar)
- [Algorithm](#Algorithm)
- [How many members can I fetch?](#how-many-members-can-i-fetch)
console.log(guild.members.cache.size); // will print the number of members in the guild
```
It's possible that fetchMembers doesn't fetch all not-offline members due to rate limiting. Don't worry if this happens, you can start fetching members from any index.
As you can see, the "no overlap" method fetches 200 members/second while the "overlap" method fetches 100 members/second. However, "no overlap" is also a lot less effective. After doing a few more tests with both methods ("overlap" and "no overlap"), "no overlap" shows a lot less consistency/reliability than "overlap".
#### Fetching the member list backwards
(and in pretty much any "style" you want)
So, this is more proof-of-concept, but here's a short explanation.
Suppose you're in a guild with 1000 members and want to fetch the member list backwards (I dunno...more undetectable since noone fetches it backwards? lol).
Since discum requests members in 200-member chunks, you'll either have to request for the following range groups (safer):
```
[[0,99],[800,899],[900,999]] #target start: 800
[[0,99],[700,799],[800,899]] #target start: 700
[[0,99],[600,699],[700,799]] #target start: 600
[[0,99],[500,599],[600,699]] #target start: 500
[[0,99],[400,499],[500,599]] #target start: 400
[[0,99],[300,399],[400,499]] #target start: 300
[[0,99],[200,299],[300,399]] #target start: 200
[[0,99],[100,199],[200,299]] #target start: 100
[[0,99],[100,199]] #target start: 0
```
or the following range groups (faster):
```
[[0,99],[800,899],[900,999]] #target start: 800
[[0,99],[600,699],[700,799]] #target start: 600
[[0,99],[400,499],[500,599]] #target start: 400
[[0,99],[200,299],[300,399]] #target start: 200
[[0,99],[100,199]] #target start: 0
```
The first one looks like an overlap method while the second looks like a no-overlap method. However, since we're fetching the memberlist backwards, we cannot
use 100 and 200 for the methods. Instead, we need a list of multipliers (method) and a startIndex.
A wait time of at least 0.5 is needed to prevent the brute forcer from rate limiting too often. In the event that the brute forcer does get rate limited, some time will be lost reconnecting.
#### Algorithm
for simplicity, assume that the list of characters to search for is ['a', 'b', 'c', 'd']
1) query for up to 100 members in guild who have a nickname/username starting with 'a'
2) on a GUILD_MEMBERS_CHUNK event:
- if there are 100 results:
- add on the 2nd character of the last result. For example, if the results are
```
aaaaaaaaaaaa
aaadfd3fgdftjh
...
Acaddd
```
,
the next query will be 'ac'. Note: searches are case-insensitive and consecutive spaces are treated like single spaces.
- if there are less than 100 results:
- replace the last index of the query with the next option in the list
This algorithm can definitely be made a lot better so have at it. The brute forcer example is just there to help you get started.
#### How many members can I fetch?
- a limit is posed if many users have the same nickname & username (but different discriminators). Only the 1st 100 members will be able to be fetched. There's no known way to include the discriminator # in the search.
- also, in order to query users with fancy characters in their username/nickname, the op8 brute forcer needs to be slowed down (cause, more characters to search)