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