1 module dcord.types.channel; 2 3 import std.stdio, 4 std.format, 5 std.variant, 6 std.algorithm, 7 core.vararg; 8 9 import dcord.types, 10 dcord.client; 11 12 alias ChannelMap = ModelMap!(Snowflake, Channel); 13 alias PermissionOverwriteMap = ModelMap!(Snowflake, PermissionOverwrite); 14 15 enum PermissionOverwriteType { 16 ROLE = "role", 17 MEMBER = "member" , 18 } 19 20 enum ChannelType : ushort { 21 GUILD_TEXT = 0, 22 DM = 1, 23 GUILD_VOICE = 2, 24 GROUP_DM = 3, 25 GUILD_CATEGORY = 4, 26 } 27 28 class PermissionOverwrite : IModel { 29 mixin Model; 30 31 Snowflake id; 32 33 // Overwrite type 34 PermissionOverwriteType type; 35 36 // Permissions 37 Permission allow; 38 Permission deny; 39 40 // Parent channel 41 Channel channel; 42 } 43 44 class Channel : IModel, IPermissible { 45 mixin Model; 46 mixin Permissible; 47 48 Snowflake id; 49 Snowflake guildID; 50 string name; 51 string topic; 52 Snowflake lastMessageID; 53 short position; 54 uint bitrate; 55 ChannelType type; 56 Snowflake parentID; 57 58 @JSONListToMap("id") 59 UserMap recipients; 60 61 // Overwrites 62 @JSONListToMap("id") 63 @JSONSource("permission_overwrites") 64 PermissionOverwriteMap overwrites; 65 66 @property Guild guild() { 67 return this.client.state.guilds.get(this.guildID); 68 } 69 70 override void initialize() { 71 this.overwrites = new PermissionOverwriteMap; 72 } 73 74 override string toString() { 75 return format("<Channel %s (%s)>", this.name, this.id); 76 } 77 78 Message sendMessage(inout(string) content, string nonce=null, bool tts=false) { 79 return this.client.api.channelsMessagesCreate(this.id, content, nonce, tts, null); 80 } 81 82 Message sendMessagef(T...)(inout(string) content, T args) { 83 return this.client.api.channelsMessagesCreate(this.id, format(content, args), null, false, null); 84 } 85 86 Message sendMessage(Sendable obj) { 87 return this.client.api.channelsMessagesCreate( 88 this.id, 89 obj.getContents(), 90 obj.getNonce(), 91 obj.getTTS(), 92 obj.getEmbed(), 93 ); 94 } 95 96 /// Whether this is a direct message 97 @property bool DM() { 98 return ( 99 this.type == ChannelType.DM || 100 this.type == ChannelType.GROUP_DM 101 ); 102 } 103 104 /// Whether this is a voice channel 105 @property bool voice() { 106 return ( 107 this.type == ChannelType.GUILD_VOICE || 108 this.type == ChannelType.GROUP_DM || 109 this.type == ChannelType.DM 110 ); 111 } 112 113 /// Whether this is a text channel 114 @property bool text() { 115 return ( 116 this.type == ChannelType.GUILD_TEXT || 117 this.type == ChannelType.DM || 118 this.type == ChannelType.GROUP_DM 119 ); 120 } 121 122 /// Whether this channel is a category 123 @property bool category() { 124 return this.type == ChannelType.GUILD_CATEGORY; 125 } 126 127 @property auto voiceStates() { 128 return this.guild.voiceStates.filter(c => c.channelID == this.id); 129 } 130 131 override Permission getPermissions(Snowflake user) { 132 GuildMember member = this.guild.getMember(user); 133 Permission perm = this.guild.getPermissions(user); 134 135 // Apply any role overwrites 136 foreach (overwrite; this.overwrites.values) { 137 if (overwrite.type != PermissionOverwriteType.ROLE) continue; 138 if (!member.roles.canFind(overwrite.id)) continue; 139 perm ^= overwrite.deny; 140 perm |= overwrite.allow; 141 } 142 143 // Finally grab a user overwrite 144 if (this.overwrites.has(member.id)) { 145 perm ^= this.overwrites.get(member.id).deny; 146 perm |= this.overwrites.get(member.id).allow; 147 } 148 149 return perm; 150 } 151 }