Course:CPSC312-2019-Discord-Permissions
Discord Permissions
Authors: Rebecca Li, JeongSoo Doo
What is the problem?
Discord is an instant messaging client with complex permissions. Permissions can be applied at a guild-wide level for @everyone
, individual members, and roles (which members may belong to). These permissions may be overwritten on a per-channel basis. The following hierarchy is observed:
(Taken from Discord documentation, found here.)
- Base permissions given to @everyone are applied at a guild level
- Permissions allowed to a user by their roles are applied at a guild level
- Overwrites that deny permissions for @everyone are applied at a channel level
- Overwrites that allow permissions for @everyone are applied at a channel level
- Overwrites that deny permissions for specific roles are applied at a channel level
- Overwrites that allow permissions for specific roles are applied at a channel level
- Member-specific overwrites that deny permissions are applied at a channel level
- Member-specific overwrites that allow permissions are applied at a channel level
Permissions are represented by a permissions integer whose bits correspond to various flags. Individual permissions may be extracted through bitwise operations/masking (e.g. CREATE_INSTANT_INVITE
is 0x00000001
).
Our project implements per-channel permissions overwriting in Prolog, allowing the permissions integer for a particular user to be computed given a guild or a channel (and their IDs).
What is the something extra?
Using the Discord API to fetch real data including guild permissions, users, roles, and channels. This is done through HTTP requests by a bot user that has access to the guild whose data is requested using http/http_open.
Data is received in JSON format and parsed into Prolog dicts via http/json.
What did we learn from doing this?
Logic programming is suitable for the task, though it has some downsides.
- Understanding the Prolog documentation was difficult, but the code itself for retrieving the data is relatively simple. The docs indicate argument modes, which we did not discuss (directly) in class.
- Prolog supports use of hexadecimal values (lead with
0x
) and bitwise operations (/\
,\/
), which was convenient. - When writing multiple definitions of a predicate, it can be easy to make mistakes that cause multiple answers to be returned when only one answer is desired (e.g.
guild_permissions
andchannel_permissions
should only produce one permissions integer for the given user). Care must be taken to separate distinct cases.- This was especially messy with the many helpers in
permissions.pl
.
- This was especially messy with the many helpers in
- Constant values are saved using predicates (see
flags.pl
andtoken.pl
). This can be useful if the relations are complex, but in our case we only used permission names to get the one corresponding integer.