fix conflation of server and bot
parent
34aeec60dc
commit
8f79a79b4e
|
@ -1 +1 @@
|
||||||
--protected --private --hide-void-return source/*.rb source/servers/*.rb
|
--protected --private --hide-void-return source/*.rb source/backends/*.rb
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
# Discord backend.
|
||||||
|
module Backend_Discord
|
||||||
|
require 'discordrb'
|
||||||
|
|
||||||
|
# Helper for channel permissions handling.
|
||||||
|
class ChannelPerms
|
||||||
|
def initialize() @cprm = {} end
|
||||||
|
|
||||||
|
# @param chan [Bot_Discord::Channel] the channel for this permission
|
||||||
|
# @return [Boolean] true if the channel is enabled, false otherwise.
|
||||||
|
def [](chan) @cprm[chan.name] or @cprm[chan.real.id] end
|
||||||
|
|
||||||
|
# Sets a channel's permission on/off.
|
||||||
|
# @param chan [Bot_Discord::Channel] the channel for this permission
|
||||||
|
# @param set [Boolean] if this permission should be set
|
||||||
|
# @return [void]
|
||||||
|
def []=(chan, set) @cprm[chan] = set end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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
|
||||||
|
@id = user.id
|
||||||
|
@roles = "v"
|
||||||
|
if user.is_a? Discordrb::Member
|
||||||
|
if user.owner?
|
||||||
|
@roles += "Ooh"
|
||||||
|
elsif ops and ops.any? do |role| user.role? role end
|
||||||
|
@roles += "oh"
|
||||||
|
elsif hop and hop.any? do |role| user.role? role end
|
||||||
|
@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
|
||||||
|
@id = chan.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# A Discord server.
|
||||||
|
class Server < Vrobot4::Server::AudioServer
|
||||||
|
# The server type name.
|
||||||
|
def self.type() "Discord" end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#initialize)
|
||||||
|
def initialize info, bot, id
|
||||||
|
super info, bot
|
||||||
|
|
||||||
|
@id = id
|
||||||
|
@ops = info["admins"] || []
|
||||||
|
@hop = info["halfop"] || []
|
||||||
|
|
||||||
|
if mods = info["modules"]
|
||||||
|
for mod in mods
|
||||||
|
load_mod mod
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::AudioServer#voice_quit)
|
||||||
|
def voice_quit m
|
||||||
|
@bot.real.voice_destroy m.chan.real.server.id
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::AudioServer#voice_play)
|
||||||
|
def voice_play m, fname
|
||||||
|
vc = @bot.real.voice m.chan.real
|
||||||
|
raise RuntimeError, "I'm not in a voice channel" unless vc
|
||||||
|
vc.play_file fname
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::AudioServer#voice_play_io)
|
||||||
|
def voice_play_io m, io
|
||||||
|
vc = @bot.real.voice m.chan.real
|
||||||
|
raise ArgumentError, "Invalid IO stream" unless io
|
||||||
|
raise RuntimeError, "I'm not in a voice channel" unless vc
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#flags)
|
||||||
|
def flags
|
||||||
|
?A
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#load_permissions)
|
||||||
|
def load_permissions pinf
|
||||||
|
@mprm = {chan: {}, role: {}, glob: {}}
|
||||||
|
return unless pinf
|
||||||
|
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][mod]
|
||||||
|
@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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# A bot implementation for Discord using discordrb.
|
||||||
|
class Bot < Vrobot4::Robots::Bot
|
||||||
|
# The bot type name.
|
||||||
|
def self.type() "Discord" end
|
||||||
|
Vrobot4::Robots.add_bot_type self
|
||||||
|
|
||||||
|
attr_reader :real
|
||||||
|
|
||||||
|
def initialize info
|
||||||
|
super
|
||||||
|
@servers = {}
|
||||||
|
|
||||||
|
@real = Discordrb::Bot.new \
|
||||||
|
token: info["apikey"],
|
||||||
|
client_id: info["client"]
|
||||||
|
|
||||||
|
@real.message do |evt|
|
||||||
|
if evt.server
|
||||||
|
serv = server_by_id evt.server.id
|
||||||
|
m = Vrobot4::Server::Message.new \
|
||||||
|
msg: evt.message.content,
|
||||||
|
user: User.new(evt.user, @ops, @hop),
|
||||||
|
chan: Channel.new(evt.channel),
|
||||||
|
serv: serv,
|
||||||
|
reply: -> (text) {evt.respond text},
|
||||||
|
reply_b: -> (text) {evt.respond "```\n#{text}```"}
|
||||||
|
|
||||||
|
serv.handle_text_cmd m
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Robots::Bot#connect)
|
||||||
|
def connect
|
||||||
|
@real.run
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# Adds a server to the hash.
|
||||||
|
# @param id [Integer] id of the server
|
||||||
|
# @return [Discordrb::Server]
|
||||||
|
def add_server id
|
||||||
|
Vrobot4.log :DEBUG, "initializing server #{id}"
|
||||||
|
@servers[id] = Server.new @info[id] || {}, self, id
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finds a server in the hash, potentially adding it.
|
||||||
|
# @param id [Integer] id of the server
|
||||||
|
# @return [Discordrb::Server]
|
||||||
|
def server_by_id id
|
||||||
|
@servers[id] || add_server(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
## EOF
|
|
@ -0,0 +1,143 @@
|
||||||
|
# IRC backend.
|
||||||
|
module Backend_IRC
|
||||||
|
require 'cinch'
|
||||||
|
|
||||||
|
# Helper for channel permissions.
|
||||||
|
class ChannelPerms
|
||||||
|
def initialize() @cprm = {} end
|
||||||
|
|
||||||
|
# @param chan [Backend_IRC::Channel] the channel for this permission
|
||||||
|
# @return [Boolean] true if the channel is enabled, false otherwise.
|
||||||
|
def [](chan) @cprm[chan.name] end
|
||||||
|
|
||||||
|
# Sets a channel's permission on/off.
|
||||||
|
# @param name [String] the channel for this permission
|
||||||
|
# @param set [Boolean] if this permission should be set
|
||||||
|
# @return [void]
|
||||||
|
def []=(name, set) @cprm[name] = set end
|
||||||
|
end
|
||||||
|
|
||||||
|
# An IRC user.
|
||||||
|
class User < Vrobot4::Server::User
|
||||||
|
attr_reader :real # The Cinch::User instance.
|
||||||
|
|
||||||
|
# @param user [Cinch::User] the irc user
|
||||||
|
# @param chan [Cinch::Channel] the irc channel this object was made in
|
||||||
|
def initialize user, chan
|
||||||
|
@real = user
|
||||||
|
@name = user.nick
|
||||||
|
@id = Vrobot4.hash_str user.nick.downcase
|
||||||
|
if user.oper? then @roles = "Oohv"
|
||||||
|
elsif chan.opped? user then @roles = "ohv"
|
||||||
|
elsif chan.half_opped? user then @roles = "hv"
|
||||||
|
elsif chan.voiced? user then @roles = "v"
|
||||||
|
else @roles = "" end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# An IRC channel.
|
||||||
|
class Channel < Vrobot4::Server::Channel
|
||||||
|
attr_reader :real # The Cinch::Channel instance.
|
||||||
|
|
||||||
|
# @param chan [Cinch::Channel] the irc channel
|
||||||
|
def initialize chan
|
||||||
|
@real = chan
|
||||||
|
@name = chan.name.downcase
|
||||||
|
@id = Vrobot4.hash_str chan.name.downcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# An IRC server.
|
||||||
|
class Server < Vrobot4::Server::Server
|
||||||
|
# The server type name.
|
||||||
|
def self.type() "IRC" end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#initialize)
|
||||||
|
def initialize info, bot
|
||||||
|
super
|
||||||
|
@id = Vrobot4.hash_str info["server"].downcase
|
||||||
|
|
||||||
|
for mod in info["modules"] do
|
||||||
|
load_mod mod
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#flags)
|
||||||
|
def flags
|
||||||
|
?L
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# (see Vrobot4::Server::Server#load_permissions)
|
||||||
|
def load_permissions pinf
|
||||||
|
@mprm = {chan: {}, role: {}, glob: {}}
|
||||||
|
return unless pinf
|
||||||
|
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][mod]
|
||||||
|
@mprm[:chan][mod][pr["channel"].downcase] = true
|
||||||
|
elsif pr.key? "roles"
|
||||||
|
@mprm[:role][mod] = pr["roles"]
|
||||||
|
elsif pr.key? "enable"
|
||||||
|
@mprm[:glob][mod] = pr["enable"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# A bot implementation for IRC using cinch.
|
||||||
|
class Bot < Vrobot4::Robots::Bot
|
||||||
|
# The bot type name.
|
||||||
|
def self.type() "IRC" end
|
||||||
|
Vrobot4::Robots.add_bot_type self
|
||||||
|
|
||||||
|
attr_accessor :serv # @return [Vrobot4::Server::Server] the server
|
||||||
|
|
||||||
|
# (see Vrobot4::Robots::Bot#initialize)
|
||||||
|
def initialize info
|
||||||
|
super
|
||||||
|
this = self
|
||||||
|
|
||||||
|
@bot = Cinch::Bot.new do
|
||||||
|
configure do |cfg|
|
||||||
|
cfg.server = info["server"]
|
||||||
|
cfg.nick = info["nick"] || "vrobot4"
|
||||||
|
cfg.port = info["port"] if info.key? "port"
|
||||||
|
cfg.password = info["pass"] if info.key? "pass"
|
||||||
|
cfg.modes = info["modes"] if info.key? "modes"
|
||||||
|
cfg.channels = info["channels"] if info.key? "channels"
|
||||||
|
cfg.realname = "vrobot4"
|
||||||
|
cfg.user = "vrobot4"
|
||||||
|
cfg.message_split_start = "… "
|
||||||
|
cfg.message_split_end = " …"
|
||||||
|
end
|
||||||
|
|
||||||
|
on :message do |evt|
|
||||||
|
return unless evt.channel
|
||||||
|
|
||||||
|
m = Vrobot4::Server::Message.new \
|
||||||
|
msg: evt.message,
|
||||||
|
user: User.new(evt.user, evt.channel),
|
||||||
|
chan: Channel.new(evt.channel),
|
||||||
|
serv: this.serv,
|
||||||
|
reply: -> (text) {evt.reply text},
|
||||||
|
reply_b: -> (text) {evt.reply text}
|
||||||
|
|
||||||
|
this.serv.handle_text_cmd m
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@bot.loggers.level = :warn
|
||||||
|
@serv = Server.new info, self
|
||||||
|
end
|
||||||
|
|
||||||
|
# (see Vrobot4::Robots::Bot#connect)
|
||||||
|
def connect
|
||||||
|
@bot.start
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
## EOF
|
|
@ -1,36 +1,31 @@
|
||||||
require './common.rb'
|
require './common.rb'
|
||||||
require './module.rb'
|
require './module.rb'
|
||||||
require './server.rb'
|
require './server.rb'
|
||||||
|
require './robots.rb'
|
||||||
|
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
module Vrobot4
|
module Vrobot4
|
||||||
private
|
private
|
||||||
|
|
||||||
# Loads a bot from its configuration +botinfo+.
|
# Loads a bot from its configuration +info+.
|
||||||
# @param botinfo [Hash] arbitrary bot information
|
# @param info [Hash] arbitrary bot information
|
||||||
# ["type"] The type by name of the bot.
|
# ["type"] The type by name of the bot.
|
||||||
# @return [Vrobot4::Server] the loaded bot
|
# @return [Vrobot4::Robots::Bot] the loaded bot
|
||||||
def self.load_bot botinfo
|
def self.load_bot info
|
||||||
type = botinfo["type"]
|
type = info["type"]
|
||||||
serv = Server::get_server_type(type).new botinfo
|
Robots::get_bot_type(type).new info
|
||||||
|
|
||||||
for mod in botinfo["modules"] do
|
|
||||||
serv.load_mod mod
|
|
||||||
end
|
|
||||||
|
|
||||||
serv
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Runs all bots in +bots+ in separate threads.
|
# Runs all bots in +bots+ in separate threads.
|
||||||
# @param bots [Array<Vrobot4::Server>] all bots to run
|
# @param bots [Array<Vrobot4::Robots::Bot>] all bots to run
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def self.run_bots bots
|
def self.run_bots bots
|
||||||
threads = []
|
threads = []
|
||||||
|
|
||||||
bots.each do |server|
|
bots.each do |bot|
|
||||||
threads << Thread.new do
|
threads << Thread.new do
|
||||||
server.connect
|
bot.connect
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,8 +60,8 @@ module Vrobot4
|
||||||
begin
|
begin
|
||||||
bots = []
|
bots = []
|
||||||
|
|
||||||
cfg["bots"].each do |botinfo|
|
cfg["bots"].each do |info|
|
||||||
bots << load_bot(botinfo)
|
bots << load_bot(info)
|
||||||
end
|
end
|
||||||
|
|
||||||
log :DEBUGV, "bots: #{bots.to_s}"
|
log :DEBUGV, "bots: #{bots.to_s}"
|
||||||
|
|
|
@ -134,11 +134,7 @@ module Vrobot4::Module
|
||||||
check_arg argv[argn], argn, opt[i]
|
check_arg argv[argn], argn, opt[i]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if opt.length
|
check_arg argv, 0, req[0]
|
||||||
check_arg argv, 0, opt[0] unless argv.empty?
|
|
||||||
else
|
|
||||||
check_arg argv, 0, req[0]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
argv
|
argv
|
||||||
end
|
end
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Mod_Base < Vrobot4::Module::Module
|
||||||
|
|
||||||
def c_dbg m, argv
|
def c_dbg m, argv
|
||||||
check_args argv, "N"
|
check_args argv, "N"
|
||||||
Vrobot4.debug = argv.to_i
|
Vrobot4.set_debug argv.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def c_info m, argv
|
def c_info m, argv
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class Mod_Relay < Vrobot4::Module::Module
|
class Mod_Relay < Vrobot4::Module::Module
|
||||||
def self.type() "Relay" end
|
def self.type() "Relay" end
|
||||||
Vrobot4::Module.add_module_type self, server: "Discord"
|
Vrobot4::Module.add_module_type self
|
||||||
|
|
||||||
def initialize info
|
def initialize info
|
||||||
super
|
super
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Module for vrobot4 bot interfaces.
|
||||||
|
module Vrobot4::Robots
|
||||||
|
# Generic bot interface.
|
||||||
|
class Bot
|
||||||
|
# @param info [Hash] arbitrary extra information for this bot
|
||||||
|
def initialize info
|
||||||
|
@info = info
|
||||||
|
end
|
||||||
|
|
||||||
|
# Connect to all servers.
|
||||||
|
# @abstract
|
||||||
|
# @return [void]
|
||||||
|
def connect
|
||||||
|
raise NotImplementedError, "Bot#connect not implemented"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds a bot type to the global list.
|
||||||
|
# @param type [Class] bot type to add
|
||||||
|
# @return [void]
|
||||||
|
def self.add_bot_type type
|
||||||
|
@@bot_types[type.type] = type
|
||||||
|
Vrobot4.log :INFO, "added bot type: #{type.type}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gets a bot type by name from the global list.
|
||||||
|
# @param name [String] name of the bot type to find
|
||||||
|
# @return [Class] the bot type
|
||||||
|
def self.get_bot_type name
|
||||||
|
@@bot_types[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
# The set of all bot types.
|
||||||
|
@@bot_types = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
## EOF
|
|
@ -57,9 +57,12 @@ module Vrobot4::Server
|
||||||
class Server
|
class Server
|
||||||
attr_reader :mprm # @return [Hash] module permissions for this server
|
attr_reader :mprm # @return [Hash] module permissions for this server
|
||||||
attr_reader :id # @return [Integer] unique identifier for the server
|
attr_reader :id # @return [Integer] unique identifier for the server
|
||||||
|
attr_reader :bot # @return [Vrobot4::Robots::Bot] the bot we belong to
|
||||||
|
|
||||||
# @param info [Hash] arbitrary extra information for this server
|
# @param info [Hash] arbitrary extra information for this server
|
||||||
def initialize info
|
# @param bot [Vrobot4::Robots::Bot] the bot we belong to
|
||||||
|
def initialize info, bot
|
||||||
|
@bot = bot
|
||||||
@info = info
|
@info = info
|
||||||
@modules = [Mod_Base.new(nil)]
|
@modules = [Mod_Base.new(nil)]
|
||||||
load_permissions info["permissions"]
|
load_permissions info["permissions"]
|
||||||
|
@ -72,7 +75,7 @@ module Vrobot4::Server
|
||||||
mt = Vrobot4::Module.get_module_type(mod)
|
mt = Vrobot4::Module.get_module_type(mod)
|
||||||
if mt[:server] and mt[:server] != self.class.type or
|
if mt[:server] and mt[:server] != self.class.type or
|
||||||
mt[:servflags] and mt[:servflags] !~ flags then
|
mt[:servflags] and mt[:servflags] !~ flags then
|
||||||
raise ArgumentError, "Module " + mod + " not valid for this server"
|
raise ArgumentError, "Module #{mod} is not valid for this server"
|
||||||
end
|
end
|
||||||
@modules << mt[:type].new(@info[mod])
|
@modules << mt[:type].new(@info[mod])
|
||||||
end
|
end
|
||||||
|
@ -188,24 +191,6 @@ module Vrobot4::Server
|
||||||
raise NotImplementedError, "AudioServer#voice_play_io not implemented"
|
raise NotImplementedError, "AudioServer#voice_play_io not implemented"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a server type to the global list.
|
|
||||||
# @param type [Class] server type to add
|
|
||||||
# @return [void]
|
|
||||||
def self.add_server_type type
|
|
||||||
@@server_types[type.type] = type
|
|
||||||
Vrobot4.log :INFO, "added server type: #{type.type}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Gets a server type by name from the global list.
|
|
||||||
# @param name [String] name of the server type to find
|
|
||||||
# @return [Vrobot4::Server::Server] the server type
|
|
||||||
def self.get_server_type name
|
|
||||||
@@server_types[name]
|
|
||||||
end
|
|
||||||
|
|
||||||
# The set of all server types.
|
|
||||||
@@server_types = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
## EOF
|
## EOF
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
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
|
|
||||||
|
|
||||||
@id = info["client"]
|
|
||||||
|
|
||||||
@ops = info["admins"] || []
|
|
||||||
@hop = info["halfop"] || []
|
|
||||||
|
|
||||||
@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}```"}
|
|
||||||
|
|
||||||
handle_text_cmd m
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_quit)
|
|
||||||
def voice_quit m
|
|
||||||
@bot.voice_destroy m.chan.real.server.id
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_play)
|
|
||||||
def voice_play m, fname
|
|
||||||
vc = @bot.voice m.chan.real
|
|
||||||
raise RuntimeError, "I'm not in a voice channel" unless vc
|
|
||||||
vc.play_file fname
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_play_io)
|
|
||||||
def voice_play_io m, io
|
|
||||||
vc = @bot.voice m.chan.real
|
|
||||||
raise ArgumentError, "Invalid IO stream" unless io
|
|
||||||
raise RuntimeError, "I'm not in a voice channel" unless vc
|
|
||||||
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
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#connect)
|
|
||||||
def connect
|
|
||||||
@bot.run
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#flags)
|
|
||||||
def flags
|
|
||||||
?A
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#load_permissions)
|
|
||||||
def load_permissions pinf
|
|
||||||
@mprm = {chan: {}, role: {}, glob: {}}
|
|
||||||
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
|
|
||||||
@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
|
|
||||||
end if pinf
|
|
||||||
end
|
|
||||||
|
|
||||||
# Helper for channel permissions handling.
|
|
||||||
class ChannelPerms
|
|
||||||
def initialize() @cprm = {} end
|
|
||||||
|
|
||||||
# @param chan [Sv_Discord::Channel] the channel for this permission
|
|
||||||
# @return [Boolean] true if the channel is enabled, false otherwise.
|
|
||||||
def [](chan) @cprm[chan.name] or @cprm[chan.real.id] end
|
|
||||||
|
|
||||||
# Sets a channel's permission on/off.
|
|
||||||
# @param chan [Sv_Discord::Channel] the channel for this permission
|
|
||||||
# @param set [Boolean] if this permission should be set
|
|
||||||
# @return [void]
|
|
||||||
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
|
|
||||||
@id = user.id
|
|
||||||
@roles = "v"
|
|
||||||
if user.is_a? Discordrb::Member
|
|
||||||
if user.owner?
|
|
||||||
@roles += "Ooh"
|
|
||||||
elsif ops and ops.any? do |role| user.role? role end
|
|
||||||
@roles += "oh"
|
|
||||||
elsif hop and hop.any? do |role| user.role? role end
|
|
||||||
@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
|
|
||||||
@id = chan.id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
## EOF
|
|
|
@ -1,124 +0,0 @@
|
||||||
require 'cinch'
|
|
||||||
|
|
||||||
# A server implementation for IRC using cinch.
|
|
||||||
class Sv_IRC < Vrobot4::Server::Server
|
|
||||||
# The server type name.
|
|
||||||
def self.type() "IRC" end
|
|
||||||
Vrobot4::Server.add_server_type self
|
|
||||||
|
|
||||||
attr_reader :bot # The Cinch::Bot instance.
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#initialize)
|
|
||||||
def initialize info
|
|
||||||
super
|
|
||||||
|
|
||||||
this = self
|
|
||||||
@bot = Cinch::Bot.new do
|
|
||||||
configure do |cfg|
|
|
||||||
cfg.server = info["server"]
|
|
||||||
cfg.nick = info["nick"] || "vrobot4"
|
|
||||||
cfg.port = info["port"] if info.key? "port"
|
|
||||||
cfg.password = info["pass"] if info.key? "pass"
|
|
||||||
cfg.modes = info["modes"] if info.key? "modes"
|
|
||||||
cfg.channels = info["channels"] if info.key? "channels"
|
|
||||||
cfg.realname = "vrobot4"
|
|
||||||
cfg.user = "vrobot4"
|
|
||||||
cfg.message_split_start = "… "
|
|
||||||
cfg.message_split_end = " …"
|
|
||||||
end
|
|
||||||
|
|
||||||
on :message do |evt|
|
|
||||||
return unless evt.channel
|
|
||||||
|
|
||||||
m = Vrobot4::Server::Message.new \
|
|
||||||
msg: evt.message,
|
|
||||||
user: User.new(evt.user, evt.channel),
|
|
||||||
chan: Channel.new(evt.channel),
|
|
||||||
serv: this,
|
|
||||||
reply: -> (text) {evt.reply text},
|
|
||||||
reply_b: -> (text) {evt.reply text}
|
|
||||||
|
|
||||||
this.handle_text_cmd m
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@bot.loggers.level = :warn
|
|
||||||
@id = info["server"].downcase.sum
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#connect)
|
|
||||||
def connect
|
|
||||||
@bot.start
|
|
||||||
end
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#flags)
|
|
||||||
def flags
|
|
||||||
?L
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#load_permissions)
|
|
||||||
def load_permissions pinf
|
|
||||||
@mprm = {chan: {}, role: {}, glob: {}}
|
|
||||||
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
|
|
||||||
@mprm[:chan][mod][pr["channel"].downcase] = true
|
|
||||||
elsif pr.key? "roles"
|
|
||||||
@mprm[:role][mod] = pr["roles"]
|
|
||||||
elsif pr.key? "enable"
|
|
||||||
@mprm[:glob][mod] = pr["enable"]
|
|
||||||
end
|
|
||||||
end if pinf
|
|
||||||
end
|
|
||||||
|
|
||||||
# Helper for channel permissions.
|
|
||||||
class ChannelPerms
|
|
||||||
def initialize() @cprm = {} end
|
|
||||||
|
|
||||||
# @param chan [Sv_IRC::Channel] the channel for this permission
|
|
||||||
# @return [Boolean] true if the channel is enabled, false otherwise.
|
|
||||||
def [](chan) @cprm[chan.name] end
|
|
||||||
|
|
||||||
# Sets a channel's permission on/off.
|
|
||||||
# @param name [String] the channel for this permission
|
|
||||||
# @param set [Boolean] if this permission should be set
|
|
||||||
# @return [void]
|
|
||||||
def []=(name, set) @cprm[name] = set end
|
|
||||||
end
|
|
||||||
private_constant :ChannelPerms
|
|
||||||
|
|
||||||
# An IRC user.
|
|
||||||
class User < Vrobot4::Server::User
|
|
||||||
attr_reader :real # The Cinch::User instance.
|
|
||||||
|
|
||||||
# @param user [Cinch::User] the irc user
|
|
||||||
# @param chan [Cinch::Channel] the irc channel this object was made in
|
|
||||||
def initialize user, chan
|
|
||||||
@real = user
|
|
||||||
@name = user.nick
|
|
||||||
@id = user.nick.downcase.sum
|
|
||||||
if user.oper? then @roles = "Oohv"
|
|
||||||
elsif chan.opped? user then @roles = "ohv"
|
|
||||||
elsif chan.half_opped? user then @roles = "hv"
|
|
||||||
elsif chan.voiced? user then @roles = "v"
|
|
||||||
else @roles = "" end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# An IRC channel.
|
|
||||||
class Channel < Vrobot4::Server::Channel
|
|
||||||
attr_reader :real # The Cinch::Channel instance.
|
|
||||||
|
|
||||||
# @param chan [Cinch::Channel] the irc channel
|
|
||||||
def initialize chan
|
|
||||||
@real = chan
|
|
||||||
@name = chan.name.downcase
|
|
||||||
@id = chan.name.downcase.sum
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
## EOF
|
|
Loading…
Reference in New Issue