1 module dscord.types.guild; 2 3 import std.stdio, 4 std.algorithm, 5 std.array, 6 std.conv; 7 8 import dscord.types, 9 dscord.client, 10 dscord.gateway; 11 12 alias GuildMap = ModelMap!(Snowflake, Guild); 13 alias RoleMap = ModelMap!(Snowflake, Role); 14 alias GuildMemberMap = ModelMap!(Snowflake, GuildMember); 15 alias EmojiMap = ModelMap!(Snowflake, Emoji); 16 17 enum VerificationLevel : ushort { 18 NONE = 0, 19 LOW = 1, 20 MEDIUM = 2, 21 HIGH = 3, 22 EXTREME = 4, 23 } 24 25 class Role : IModel { 26 mixin Model; 27 28 Snowflake id; 29 Snowflake guildID; 30 31 string name; 32 bool hoist; 33 bool managed; 34 uint color; 35 Permission permissions; 36 short position; 37 bool mentionable; 38 39 @property Guild guild() { 40 return this.client.state.guilds.get(this.guildID); 41 } 42 } 43 44 class Emoji : IModel { 45 mixin Model; 46 47 Snowflake id; 48 Snowflake guildID; 49 string name; 50 bool requireColons; 51 bool managed; 52 53 Snowflake[] roles; 54 55 @property Guild guild() { 56 return this.client.state.guilds.get(this.guildID); 57 } 58 59 bool matches(string usage) { 60 if (this.name == ":" ~ usage ~ ":") { 61 return true; 62 } else if (this.requireColons) { 63 return false; 64 } else { 65 return this.name == usage; 66 } 67 } 68 } 69 70 class GuildMember : IModel { 71 mixin Model; 72 73 User user; 74 Snowflake guildID; 75 string nick; 76 string joinedAt; 77 bool mute; 78 bool deaf; 79 80 Snowflake[] roles; 81 82 @property Snowflake id() { 83 return this.user.id; 84 } 85 86 @property Guild guild() { 87 return this.client.state.guilds.get(this.guildID); 88 } 89 90 override string toString() { 91 return format("<GuildMember %s#%s (%s / %s)>", 92 this.user.username, 93 this.user.discriminator, 94 this.id, 95 this.guild.id); 96 } 97 98 bool hasRole(Role role) { 99 return this.hasRole(role.id); 100 } 101 102 bool hasRole(Snowflake id) { 103 return this.roles.canFind(id); 104 } 105 } 106 107 class Guild : IModel, IPermissible { 108 mixin Model; 109 mixin Permissible; 110 111 Snowflake id; 112 Snowflake ownerID; 113 Snowflake afkChannelID; 114 Snowflake embedChannelID; 115 string name; 116 string icon; 117 string splash; 118 string region; 119 uint afkTimeout; 120 bool embedEnabled; 121 ushort verificationLevel; 122 ushort mfaLevel; 123 string[] features; 124 125 bool unavailable; 126 127 @JSONListToMap("id") 128 GuildMemberMap members; 129 130 @JSONListToMap("sessionID") 131 VoiceStateMap voiceStates; 132 133 @JSONListToMap("id") 134 ChannelMap channels; 135 136 @JSONListToMap("id") 137 RoleMap roles; 138 139 @JSONListToMap("id") 140 EmojiMap emojis; 141 142 override void init() { 143 // It's possible these are not created 144 if (!this.members) return; 145 146 this.members.each((m) { m.guildID = this.id; }); 147 this.voiceStates.each((vc) { vc.guildID = this.id; }); 148 this.channels.each((c) { c.guildID = this.id; }); 149 this.roles.each((r) { r.guildID = this.id; }); 150 this.emojis.each((e) { e.guildID = this.id; }); 151 } 152 153 override string toString() { 154 return format("<Guild %s (%s)>", this.name, this.id); 155 } 156 157 /// Returns a GuildMember for a given user object 158 GuildMember getMember(User obj) { 159 return this.getMember(obj.id); 160 } 161 162 /// Returns a GuildMember for a given user/member id 163 GuildMember getMember(Snowflake id) { 164 return this.members.get(id); 165 } 166 167 /// Kick a given GuildMember 168 void kick(GuildMember member) { 169 this.kick(member.user); 170 } 171 172 /// Kick a given User 173 void kick(User user) { 174 this.client.api.guildsMembersKick(this.id, user.id); 175 } 176 177 /// Default role for this Guild 178 @property Role defaultRole() { 179 return this.roles.pick((r) { 180 return r.id == this.id; 181 }); 182 } 183 184 /// Default channel for this Guild 185 @property Channel defaultChannel() { 186 return this.channels.pick((c) { 187 return c.id == this.id; 188 }); 189 } 190 191 /// Request offline members for this guild 192 void requestOfflineMembers() { 193 this.client.gw.send(new RequestGuildMembers(this.id)); 194 } 195 196 override Permission getPermissions(Snowflake user) { 197 // If we're the owner, we have alllll the permissions 198 if (this.ownerID == user) { 199 return Permissions.ADMINISTRATOR; 200 } 201 202 // Otherwise grab the member object 203 GuildMember member = this.getMember(user); 204 Permission perm; 205 auto roles = member.roles.map!((rid) => this.roles.get(rid)); 206 207 // Iterate over roles and add permissions 208 foreach (role; roles) { 209 perm |= role.permissions; 210 } 211 212 return perm; 213 } 214 215 /// Set this servers name 216 void setName(string name) { 217 this.client.api.guildsModify(this.id, VibeJSON(["name" : VibeJSON(name)])); 218 } 219 220 /// Set this servers region 221 void setRegion(string region) { 222 this.client.api.guildsModify(this.id, VibeJSON(["region" : VibeJSON(region)])); 223 } 224 }