require 'discordrb' # A server implementation for Discord using discordrb. class Sv_Discord < Vrobot4::Server::AudioServer # The server type name. def self.type "Discord" end Vrobot4::Server.add_server_type self attr_reader :bot # The Discordrb::Bot instance. # (see Vrobot4::Server::Server#initialize) def initialize info super if info.key? "admins"; @ops = info["admins"] else; @ops = []; end if info.key? "halfop"; @hop = info["halfop"] else; @hop = []; end @bot = Discordrb::Bot.new \ token: info["apikey"], client_id: info["client"] @bot.message do |evt| m = Vrobot4::Server::Message.new \ msg: evt.message.content, user: User.new(evt.user, @ops, @hop), chan: Channel.new(evt.channel), serv: self, reply: -> (text) {evt.respond text}, reply_b: -> (text) {evt.respond "```\n" + text + "```"} if m.msg.start_with? '.' argv = m.msg.split cnam = argv.shift[1..-1] on_command m, cnam, argv else on_message m end end end # (see Vrobot4::Server::AudioServer#voice_join) def voice_join m chan = m.user.real.voice_channel raise RuntimeError, "You're not in a voice channel" unless chan @bot.voice_connect chan end # (see Vrobot4::Server::AudioServer#voice_join) def voice_quit m @bot.voice_destroy m.chan.real.server.id end # (see Vrobot4::Server::AudioServer#play) def play m, io v = @bot.voice(m.chan.real) raise ArgumentError, "Invalid i/o stream" unless io raise RuntimeError, "I'm not in a voice channel" unless v v.play_stream io end # (see Vrobot4::Server::AudioServer#is_playing?) def is_playing? m v = @bot.voice(m.chan.real) v != nil and v.playing? end # (see Vrobot4::Server::Server#connect) def connect @bot.run end # (see Vrobot4::Server::Server#flags) def flags "AD" end protected # (see Vrobot4::Server::Server#load_permissions) def load_permissions pinf @mprm = {chan: {}, role: {}, glob: {}} pinf.each do |perm| mod = Vrobot4::Module.get_module_type(perm["module"])[:type] if perm.key? "channel" @mprm[:chan][mod] = ChannelPerms.new unless @mprm[:chan].key? mod @mprm[:chan][mod][perm["channel"]] = true elsif perm.key? "roles" @mprm[:role][mod] = perm["roles"] else @mprm[:glob][mod] = perm["enable"] end end end class ChannelPerms def initialize @cprm = {} end # Returns true if the channel is enabled, false otherwise. def [] chan (@cprm.key? chan.name and @cprm[chan.name]) or (@cprm.key? chan.real.id and @cprm[chan.real.id]) end # Sets a channel's permission on/off. def []= chan, set @cprm[chan] = set end end private_constant :ChannelPerms # A Discord user. class User < Vrobot4::Server::User attr_reader :real # The Discordrb::User instance. # @param user [Discordrb::User] the discord user # @param ops [Array] list of operator role IDs # @param hop [Array] list of half-operator role IDs def initialize user, ops, hop @real = user @name = user.name @roles = "v" if user.is_a? Discordrb::Member if user.owner? @roles += "Ooh" elsif ops and ops.select {|role| user.role? role}.any? @roles += "oh" elsif hop and hop.select {|role| user.role? role}.any? @roles += "h" end end end end # A Discord channel. class Channel < Vrobot4::Server::Channel attr_reader :real # The Discordrb::Channel instance. # @param chan [Discordrb::Channel] the discord channel def initialize chan @real = chan @name = "#" + chan.name end end end ## EOF