Compare commits
3 Commits
34aeec60dc
...
09591b03d1
Author | SHA1 | Date |
---|---|---|
an | 09591b03d1 | |
an | 79e6dbd495 | |
an | 8f79a79b4e |
|
@ -1,5 +1,5 @@
|
|||
*doc
|
||||
working
|
||||
*.yml
|
||||
_config.rb
|
||||
*.swp
|
||||
*.vim
|
||||
|
|
|
@ -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,200 @@
|
|||
# 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 # @return [Discordrb::User] the 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 # @return [Discordrb::Channel] the 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
|
||||
|
||||
attr_reader :real # @return [Discordrb::Server] the instance
|
||||
|
||||
# (see Vrobot4::Server::Server#initialize)
|
||||
# @param real [Discordrb::Server] the instance
|
||||
def initialize info, bot, real
|
||||
super info, bot
|
||||
|
||||
@real = real
|
||||
@id = real.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.ready do |evt|
|
||||
for _, serv in evt.bot.servers
|
||||
add_server serv
|
||||
end
|
||||
end
|
||||
|
||||
@real.message do |evt|
|
||||
if evt.server
|
||||
serv = get_server evt.server
|
||||
|
||||
m = Vrobot4::Server::Message.new \
|
||||
msg: evt.message.content,
|
||||
user: User.new(evt.user, @ops, @hop),
|
||||
chan: Channel.new(evt.channel),
|
||||
serv: serv,
|
||||
bot: self,
|
||||
reply: -> (text) {evt.channel.send text},
|
||||
reply_b: -> (text) {evt.channel.send "```\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 serv [Discordrb::Server] server instance
|
||||
# @return [Server]
|
||||
def add_server serv
|
||||
Vrobot4.log :DEBUG, "initializing server #{serv.id}"
|
||||
@servers[serv.id] = Server.new @info[serv.id] || {}, self, serv
|
||||
end
|
||||
|
||||
# Finds a server in the hash, potentially adding it.
|
||||
# @param serv [Discordrb::Server] server instance
|
||||
# @return [Server]
|
||||
def get_server serv
|
||||
@servers[serv.id] || add_server(serv)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## EOF
|
|
@ -0,0 +1,144 @@
|
|||
# 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,
|
||||
bot: this,
|
||||
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
|
|
@ -0,0 +1,35 @@
|
|||
module Config
|
||||
def self.get
|
||||
{
|
||||
debug: 0,
|
||||
|
||||
load: %w[
|
||||
./backends/discord.rb
|
||||
./backends/irc.rb
|
||||
|
||||
./modules/util.rb
|
||||
],
|
||||
|
||||
bots: [
|
||||
{
|
||||
type: "Discord",
|
||||
client: your_bot_client_id_here,
|
||||
apikey: your_api_key_here,
|
||||
admins: [your_personal_client_id_here],
|
||||
your_server_id_here => {
|
||||
modules: %w[Utilities],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "IRC",
|
||||
server: your_server_here,
|
||||
port: 6667,
|
||||
channels: %w[#my_cool_channel],
|
||||
modules: %w[Utilities],
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
## EOF
|
|
@ -1,36 +1,29 @@
|
|||
require './common.rb'
|
||||
require './module.rb'
|
||||
require './server.rb'
|
||||
|
||||
require 'yaml'
|
||||
require './robots.rb'
|
||||
|
||||
module Vrobot4
|
||||
private
|
||||
|
||||
# Loads a bot from its configuration +botinfo+.
|
||||
# @param botinfo [Hash] arbitrary bot information
|
||||
# Loads a bot from its configuration +info+.
|
||||
# @param info [Hash] arbitrary bot information
|
||||
# ["type"] The type by name of the bot.
|
||||
# @return [Vrobot4::Server] the loaded bot
|
||||
def self.load_bot botinfo
|
||||
type = botinfo["type"]
|
||||
serv = Server::get_server_type(type).new botinfo
|
||||
|
||||
for mod in botinfo["modules"] do
|
||||
serv.load_mod mod
|
||||
end
|
||||
|
||||
serv
|
||||
# @return [Vrobot4::Robots::Bot] the loaded bot
|
||||
def self.load_bot info
|
||||
type = info[:type]
|
||||
Robots::get_bot_type(type).new info
|
||||
end
|
||||
|
||||
# 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]
|
||||
def self.run_bots bots
|
||||
threads = []
|
||||
|
||||
bots.each do |server|
|
||||
bots.each do |bot|
|
||||
threads << Thread.new do
|
||||
server.connect
|
||||
bot.connect
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -42,31 +35,27 @@ module Vrobot4
|
|||
public
|
||||
|
||||
# Runs the program.
|
||||
# @param cfg [IO] configuration file to read
|
||||
# @param cfg [String] configuration file to read
|
||||
# @return [void]
|
||||
def self.main cfg
|
||||
Thread.abort_on_exception = true
|
||||
|
||||
log :INFO, "vrobot version #{Version}"
|
||||
|
||||
begin
|
||||
cfg = YAML.load cfg.read
|
||||
rescue
|
||||
log :ERROR, "error reading bot config: #{$!}"
|
||||
return
|
||||
end
|
||||
load cfg
|
||||
cfg = Config.get
|
||||
|
||||
Vrobot4.set_debug(cfg["debug"] || 0)
|
||||
Vrobot4.set_debug(cfg[:debug] || 0)
|
||||
|
||||
cfg["load"].each do |mod|
|
||||
cfg[:load].each do |mod|
|
||||
load mod, true
|
||||
end
|
||||
|
||||
begin
|
||||
bots = []
|
||||
|
||||
cfg["bots"].each do |botinfo|
|
||||
bots << load_bot(botinfo)
|
||||
cfg[:bots].each do |info|
|
||||
bots << load_bot(info)
|
||||
end
|
||||
|
||||
log :DEBUGV, "bots: #{bots.to_s}"
|
||||
|
|
|
@ -134,11 +134,7 @@ module Vrobot4::Module
|
|||
check_arg argv[argn], argn, opt[i]
|
||||
end
|
||||
else
|
||||
if opt.length
|
||||
check_arg argv, 0, opt[0] unless argv.empty?
|
||||
else
|
||||
check_arg argv, 0, req[0]
|
||||
end
|
||||
check_arg argv, 0, req[0]
|
||||
end
|
||||
argv
|
||||
end
|
||||
|
|
|
@ -43,9 +43,9 @@ class Mod_Base < Vrobot4::Module::Module
|
|||
end
|
||||
|
||||
def c_modr m, argv
|
||||
argv = check_args argv.split, "S", "S"
|
||||
argv = argv.split
|
||||
m.serv.drop_mod argv[0]
|
||||
load argv[1], true if argv.length > 1
|
||||
load argv[1], true if argv[1]
|
||||
m.serv.load_mod argv[0]
|
||||
end
|
||||
|
||||
|
@ -59,7 +59,7 @@ class Mod_Base < Vrobot4::Module::Module
|
|||
|
||||
def c_dbg m, argv
|
||||
check_args argv, "N"
|
||||
Vrobot4.debug = argv.to_i
|
||||
Vrobot4.set_debug argv.to_i
|
||||
end
|
||||
|
||||
def c_info m, argv
|
||||
|
|
|
@ -102,8 +102,8 @@ class Mod_DoomRLA < Vrobot4::Module::Module
|
|||
def reload_info
|
||||
@winfo = []
|
||||
@minfo = []
|
||||
@info["wep_info"].each {|wi| @winfo += JSON.parse(open(wi).read)}
|
||||
@info["mon_info"].each {|mi| @minfo += JSON.parse(open(mi).read)}
|
||||
@info[:wep_info].each {|wi| @winfo += JSON.parse(open(wi).read)}
|
||||
@info[:mon_info].each {|mi| @minfo += JSON.parse(open(mi).read)}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
require 'open-uri'
|
||||
require 'json'
|
||||
|
||||
class Mod_Fun < Vrobot4::Module::Module
|
||||
def self.type() "Fun" end
|
||||
Vrobot4::Module.add_module_type self
|
||||
|
||||
QDB = "http://greyserv.net/qdb"
|
||||
|
||||
def initialize info
|
||||
super
|
||||
register :c_carmack, "carmack", "mmmmmmmmmm"
|
||||
|
@ -16,7 +11,6 @@ class Mod_Fun < Vrobot4::Module::Module
|
|||
register :c_box, "box", "S H I T P O S T I N G"
|
||||
register :c_zdoom, "zdoom", "ZDoom™"
|
||||
register :c_marble, "marble", "mararuaruaruaruarb"
|
||||
register :c_quote, "quote", "Queries the Doominati Quote Database."
|
||||
register :c_what, "what", "What the fuck did you just fucking say about"
|
||||
end
|
||||
|
||||
|
@ -40,7 +34,7 @@ class Mod_Fun < Vrobot4::Module::Module
|
|||
end
|
||||
|
||||
def c_marble m, argv
|
||||
check_args argv, "", "N"
|
||||
check_args argv, "N"
|
||||
|
||||
if argv.empty? then n = 20
|
||||
else n = argv.to_i end
|
||||
|
@ -57,29 +51,6 @@ class Mod_Fun < Vrobot4::Module::Module
|
|||
m.reply text
|
||||
end
|
||||
|
||||
def c_quote m, argv
|
||||
if argv.empty?
|
||||
q, num = nil, nil
|
||||
max = JSON.parse(open(QDB + "/interface.cgi").read)["numQuotes"]
|
||||
loop do
|
||||
num = rand(max) + 1
|
||||
q = open(QDB + "/q/" + num.to_s).read
|
||||
break unless m.serv.flags.include? "L" and
|
||||
(q.lines.count > 4 or q.length > 1000)
|
||||
end
|
||||
m.reply_b "Quote %i:\n" % [num] + q
|
||||
elsif Vrobot4.is_num? argv
|
||||
m.reply_b open(QDB + "/q/" + argv.to_i.to_s).read
|
||||
else
|
||||
raise ArgumentError, "Invalid query" if argv.include? ?&
|
||||
q = URI.escape argv
|
||||
info = JSON.parse(open(QDB + "/interface.cgi?query=" + q).read)
|
||||
raise ArgumentError, "No results" unless info["searchResults"].any?
|
||||
res = info["searchResults"].sample
|
||||
m.reply_b "Quote %i:\n" % [res] + open(QDB + "/q/" + res.to_s).read
|
||||
end
|
||||
end
|
||||
|
||||
def c_what m, argv
|
||||
if m.serv.flags.include? ?L
|
||||
m.reply "What the fuck did you just fucking say about me, you little bitch?"
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
require 'open-uri'
|
||||
require 'json'
|
||||
|
||||
class Mod_QDB < Vrobot4::Module::Module
|
||||
def self.type() "QDB" end
|
||||
Vrobot4::Module.add_module_type self
|
||||
|
||||
QDB = "http://greyserv.net/qdb"
|
||||
|
||||
def initialize info
|
||||
super
|
||||
register :c_quote, "quote", "Queries the Doominati Quote Database."
|
||||
end
|
||||
|
||||
def c_quote m, argv
|
||||
if argv.empty?
|
||||
q, num = nil, nil
|
||||
max = JSON.parse(open(QDB + "/interface.cgi").read)["numQuotes"]
|
||||
loop do
|
||||
num = rand(max) + 1
|
||||
q = open(QDB + "/q/" + num.to_s).read
|
||||
break unless m.serv.flags.include? "L" and
|
||||
(q.lines.count > 4 or q.length > 1000)
|
||||
end
|
||||
m.reply_b "Quote %i:\n" % [num] + q
|
||||
elsif Vrobot4.is_num? argv
|
||||
m.reply_b open(QDB + "/q/" + argv.to_i.to_s).read
|
||||
else
|
||||
raise ArgumentError, "Invalid query" if argv.include? ?&
|
||||
q = URI.escape argv
|
||||
info = JSON.parse(open(QDB + "/interface.cgi?query=" + q).read)
|
||||
raise ArgumentError, "No results" unless info["searchResults"].any?
|
||||
res = info["searchResults"].sample
|
||||
m.reply_b "Quote %i:\n" % [res] + open(QDB + "/q/" + res.to_s).read
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## EOF
|
|
@ -1,6 +1,6 @@
|
|||
class Mod_Relay < Vrobot4::Module::Module
|
||||
def self.type() "Relay" end
|
||||
Vrobot4::Module.add_module_type self, server: "Discord"
|
||||
Vrobot4::Module.add_module_type self
|
||||
|
||||
def initialize info
|
||||
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
|
|
@ -21,12 +21,14 @@ module Vrobot4::Server
|
|||
attr_reader :user # @return [User] user that triggered this message
|
||||
attr_reader :chan # @return [Channel] channel this message was sent to
|
||||
attr_reader :serv # @return [Server] server this message was sent to
|
||||
attr_reader :bot # @return [Vrobot4::Robots::Bot] bot this was sent to
|
||||
|
||||
# @param info [Hash] A hash containing message info. Keys may be omitted.
|
||||
# [:msg] Plaintext of message.
|
||||
# [:user] User that triggered this message.
|
||||
# [:chan] Channel that this message was sent to.
|
||||
# [:serv] Server this message was sent to.
|
||||
# [:bot] Bot this message was sent to.
|
||||
# [:reply] Method that sends a message to the specified channel.
|
||||
# [:reply_b] Method that sends a large message to the specified channel.
|
||||
def initialize(**info)
|
||||
|
@ -34,6 +36,7 @@ module Vrobot4::Server
|
|||
@user = info[:user]
|
||||
@chan = info[:chan]
|
||||
@serv = info[:serv]
|
||||
@bot = info[:bot]
|
||||
@reply = info[:reply]
|
||||
@reply_b = info[:reply_b]
|
||||
end
|
||||
|
@ -57,12 +60,15 @@ module Vrobot4::Server
|
|||
class Server
|
||||
attr_reader :mprm # @return [Hash] module permissions for this 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
|
||||
def initialize info
|
||||
# @param bot [Vrobot4::Robots::Bot] the bot we belong to
|
||||
def initialize info, bot
|
||||
@bot = bot
|
||||
@info = info
|
||||
@modules = [Mod_Base.new(nil)]
|
||||
load_permissions info["permissions"]
|
||||
load_permissions info[:permissions]
|
||||
end
|
||||
|
||||
# Loads and initializes a module into the load list.
|
||||
|
@ -72,9 +78,9 @@ module Vrobot4::Server
|
|||
mt = Vrobot4::Module.get_module_type(mod)
|
||||
if mt[:server] and mt[:server] != self.class.type or
|
||||
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
|
||||
@modules << mt[:type].new(@info[mod])
|
||||
@modules << mt[:type].new(@info[mod.to_sym])
|
||||
end
|
||||
|
||||
# Drops a module from the load list.
|
||||
|
@ -188,24 +194,6 @@ module Vrobot4::Server
|
|||
raise NotImplementedError, "AudioServer#voice_play_io not implemented"
|
||||
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
|
||||
|
||||
## 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