vrobot4/source/servers/discord.rb

148 lines
4.0 KiB
Ruby
Raw Normal View History

2017-08-06 16:30:37 -07:00
require 'discordrb'
2017-08-11 19:40:43 -07:00
# A server implementation for Discord using discordrb.
2017-08-08 21:00:28 -07:00
class Sv_Discord < Vrobot4::Server::AudioServer
2017-08-11 19:40:43 -07:00
# The server type name.
def self.type() "Discord" end
2017-08-11 18:50:43 -07:00
Vrobot4::Server.add_server_type self
2017-08-08 21:00:28 -07:00
2017-08-11 19:40:43 -07:00
attr_reader :bot # The Discordrb::Bot instance.
2017-08-11 19:40:43 -07:00
# (see Vrobot4::Server::Server#initialize)
def initialize info
super
2019-02-23 16:18:39 -08:00
@id = info["client"]
@ops = info["admins"] || []
@hop = info["halfop"] || []
2017-08-06 16:30:37 -07:00
@bot = Discordrb::Bot.new \
token: info["apikey"],
client_id: info["client"]
@bot.message do |evt|
m = Vrobot4::Server::Message.new \
msg: evt.message.content,
2017-08-09 02:57:56 -07:00
user: User.new(evt.user, @ops, @hop),
chan: Channel.new(evt.channel),
serv: self,
2017-08-08 04:33:30 -07:00
reply: -> (text) {evt.respond text},
2019-02-23 20:46:40 -08:00
reply_b: -> (text) {evt.respond "```\n#{text}```"}
2017-08-13 03:48:00 -07:00
handle_text_cmd m
2017-08-06 16:30:37 -07:00
end
end
2019-02-23 20:46:40 -08:00
# (see Vrobot4::Server::AudioServer#voice_quit)
2017-08-08 21:03:18 -07:00
def voice_quit m
@bot.voice_destroy m.chan.real.server.id
end
# (see Vrobot4::Server::AudioServer#voice_play)
def voice_play m, fname
2019-02-23 20:46:40 -08:00
vc = @bot.voice m.chan.real
raise RuntimeError, "I'm not in a voice channel" unless vc
vc.play_file fname
2017-08-08 21:03:18 -07:00
end
# (see Vrobot4::Server::AudioServer#voice_play_io)
def voice_play_io m, io
2019-02-23 20:46:40 -08:00
vc = @bot.voice m.chan.real
raise ArgumentError, "Invalid IO stream" unless io
raise RuntimeError, "I'm not in a voice channel" unless vc
2019-02-23 20:46:40 -08:00
Thread.new do
vc.play_io io
end
# HACK
sleep 1
oldst = nil
while vc.stream_time != oldst
oldst = vc.stream_time
sleep 5
end
2017-08-08 21:03:18 -07:00
end
2017-08-11 19:40:43 -07:00
# (see Vrobot4::Server::Server#connect)
def connect
2017-08-06 16:30:37 -07:00
@bot.run
end
2017-08-11 19:40:43 -07:00
# (see Vrobot4::Server::Server#flags)
2017-08-08 04:32:45 -07:00
def flags
2019-02-23 16:18:39 -08:00
?A
2017-08-08 04:32:45 -07:00
end
protected
2019-02-23 20:46:40 -08:00
2017-08-11 19:40:43 -07:00
# (see Vrobot4::Server::Server#load_permissions)
def load_permissions pinf
@mprm = {chan: {}, role: {}, glob: {}}
2017-08-13 03:48:00 -07:00
pinf.each do |pr|
mod = Vrobot4::Module.get_module_type(pr["module"])[:type]
if pr.key? "channel"
@mprm[:chan][mod] = ChannelPerms.new unless @mprm[:chan].key? mod
2017-08-13 03:48:00 -07:00
@mprm[:chan][mod][pr["channel"]] = true
elsif pr.key? "roles"
@mprm[:role][mod] = pr["roles"]
elsif pr.key? "enable"
@mprm[:glob][mod] = pr["enable"]
end
2017-08-13 03:48:00 -07:00
end if pinf
end
2019-02-23 20:46:40 -08:00
# Helper for channel permissions handling.
class ChannelPerms
2017-08-13 03:48:00 -07:00
def initialize() @cprm = {} end
2019-02-23 20:46:40 -08:00
# @param chan [Sv_Discord::Channel] the channel for this permission
# @return [Boolean] true if the channel is enabled, false otherwise.
2017-08-13 03:48:00 -07:00
def [](chan) @cprm[chan.name] or @cprm[chan.real.id] end
2017-08-11 19:40:43 -07:00
# Sets a channel's permission on/off.
2019-02-23 20:46:40 -08:00
# @param chan [Sv_Discord::Channel] the channel for this permission
# @param set [Boolean] if this permission should be set
# @return [void]
2017-08-13 03:48:00 -07:00
def []=(chan, set) @cprm[chan] = set end
end
2017-08-11 19:40:43 -07:00
private_constant :ChannelPerms
2017-08-11 19:40:43 -07:00
# A Discord user.
class User < Vrobot4::Server::User
2017-08-11 19:40:43 -07:00
attr_reader :real # The Discordrb::User instance.
2017-08-11 19:40:43 -07:00
# @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
2017-08-15 13:48:43 -07:00
@id = user.id
@roles = "v"
if user.is_a? Discordrb::Member
if user.owner?
@roles += "Ooh"
2019-02-23 20:46:40 -08:00
elsif ops and ops.any? do |role| user.role? role end
@roles += "oh"
2019-02-23 20:46:40 -08:00
elsif hop and hop.any? do |role| user.role? role end
@roles += "h"
end
end
end
end
2017-08-11 19:40:43 -07:00
# A Discord channel.
class Channel < Vrobot4::Server::Channel
2017-08-11 19:40:43 -07:00
attr_reader :real # The Discordrb::Channel instance.
2017-08-11 19:40:43 -07:00
# @param chan [Discordrb::Channel] the discord channel
def initialize chan
@real = chan
2019-02-23 16:18:39 -08:00
@name = ?# + chan.name
2017-08-15 13:48:43 -07:00
@id = chan.id
end
end
end
## EOF