Compare commits
3 Commits
34aeec60dc
...
09591b03d1
Author | SHA1 | Date |
---|---|---|
an | 09591b03d1 | |
an | 79e6dbd495 | |
an | 8f79a79b4e |
|
@ -1,5 +1,5 @@
|
||||||
*doc
|
*doc
|
||||||
working
|
working
|
||||||
*.yml
|
_config.rb
|
||||||
*.swp
|
*.swp
|
||||||
*.vim
|
*.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 './common.rb'
|
||||||
require './module.rb'
|
require './module.rb'
|
||||||
require './server.rb'
|
require './server.rb'
|
||||||
|
require './robots.rb'
|
||||||
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
|
||||||
|
|
||||||
|
@ -42,31 +35,27 @@ module Vrobot4
|
||||||
public
|
public
|
||||||
|
|
||||||
# Runs the program.
|
# Runs the program.
|
||||||
# @param cfg [IO] configuration file to read
|
# @param cfg [String] configuration file to read
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def self.main cfg
|
def self.main cfg
|
||||||
Thread.abort_on_exception = true
|
Thread.abort_on_exception = true
|
||||||
|
|
||||||
log :INFO, "vrobot version #{Version}"
|
log :INFO, "vrobot version #{Version}"
|
||||||
|
|
||||||
begin
|
load cfg
|
||||||
cfg = YAML.load cfg.read
|
cfg = Config.get
|
||||||
rescue
|
|
||||||
log :ERROR, "error reading bot config: #{$!}"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
load mod, true
|
||||||
end
|
end
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -43,9 +43,9 @@ class Mod_Base < Vrobot4::Module::Module
|
||||||
end
|
end
|
||||||
|
|
||||||
def c_modr m, argv
|
def c_modr m, argv
|
||||||
argv = check_args argv.split, "S", "S"
|
argv = argv.split
|
||||||
m.serv.drop_mod argv[0]
|
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]
|
m.serv.load_mod argv[0]
|
||||||
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
|
||||||
|
|
|
@ -102,8 +102,8 @@ class Mod_DoomRLA < Vrobot4::Module::Module
|
||||||
def reload_info
|
def reload_info
|
||||||
@winfo = []
|
@winfo = []
|
||||||
@minfo = []
|
@minfo = []
|
||||||
@info["wep_info"].each {|wi| @winfo += JSON.parse(open(wi).read)}
|
@info[:wep_info].each {|wi| @winfo += JSON.parse(open(wi).read)}
|
||||||
@info["mon_info"].each {|mi| @minfo += JSON.parse(open(mi).read)}
|
@info[:mon_info].each {|mi| @minfo += JSON.parse(open(mi).read)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
require 'open-uri'
|
|
||||||
require 'json'
|
|
||||||
|
|
||||||
class Mod_Fun < Vrobot4::Module::Module
|
class Mod_Fun < Vrobot4::Module::Module
|
||||||
def self.type() "Fun" end
|
def self.type() "Fun" end
|
||||||
Vrobot4::Module.add_module_type self
|
Vrobot4::Module.add_module_type self
|
||||||
|
|
||||||
QDB = "http://greyserv.net/qdb"
|
|
||||||
|
|
||||||
def initialize info
|
def initialize info
|
||||||
super
|
super
|
||||||
register :c_carmack, "carmack", "mmmmmmmmmm"
|
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_box, "box", "S H I T P O S T I N G"
|
||||||
register :c_zdoom, "zdoom", "ZDoom™"
|
register :c_zdoom, "zdoom", "ZDoom™"
|
||||||
register :c_marble, "marble", "mararuaruaruaruarb"
|
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"
|
register :c_what, "what", "What the fuck did you just fucking say about"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,7 +34,7 @@ class Mod_Fun < Vrobot4::Module::Module
|
||||||
end
|
end
|
||||||
|
|
||||||
def c_marble m, argv
|
def c_marble m, argv
|
||||||
check_args argv, "", "N"
|
check_args argv, "N"
|
||||||
|
|
||||||
if argv.empty? then n = 20
|
if argv.empty? then n = 20
|
||||||
else n = argv.to_i end
|
else n = argv.to_i end
|
||||||
|
@ -57,29 +51,6 @@ class Mod_Fun < Vrobot4::Module::Module
|
||||||
m.reply text
|
m.reply text
|
||||||
end
|
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
|
def c_what m, argv
|
||||||
if m.serv.flags.include? ?L
|
if m.serv.flags.include? ?L
|
||||||
m.reply "What the fuck did you just fucking say about me, you little bitch?"
|
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
|
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
|
|
@ -21,12 +21,14 @@ module Vrobot4::Server
|
||||||
attr_reader :user # @return [User] user that triggered this message
|
attr_reader :user # @return [User] user that triggered this message
|
||||||
attr_reader :chan # @return [Channel] channel this message was sent to
|
attr_reader :chan # @return [Channel] channel this message was sent to
|
||||||
attr_reader :serv # @return [Server] server 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.
|
# @param info [Hash] A hash containing message info. Keys may be omitted.
|
||||||
# [:msg] Plaintext of message.
|
# [:msg] Plaintext of message.
|
||||||
# [:user] User that triggered this message.
|
# [:user] User that triggered this message.
|
||||||
# [:chan] Channel that this message was sent to.
|
# [:chan] Channel that this message was sent to.
|
||||||
# [:serv] Server 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] Method that sends a message to the specified channel.
|
||||||
# [:reply_b] Method that sends a large message to the specified channel.
|
# [:reply_b] Method that sends a large message to the specified channel.
|
||||||
def initialize(**info)
|
def initialize(**info)
|
||||||
|
@ -34,6 +36,7 @@ module Vrobot4::Server
|
||||||
@user = info[:user]
|
@user = info[:user]
|
||||||
@chan = info[:chan]
|
@chan = info[:chan]
|
||||||
@serv = info[:serv]
|
@serv = info[:serv]
|
||||||
|
@bot = info[:bot]
|
||||||
@reply = info[:reply]
|
@reply = info[:reply]
|
||||||
@reply_b = info[:reply_b]
|
@reply_b = info[:reply_b]
|
||||||
end
|
end
|
||||||
|
@ -57,12 +60,15 @@ 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]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Loads and initializes a module into the load list.
|
# Loads and initializes a module into the load list.
|
||||||
|
@ -72,9 +78,9 @@ 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.to_sym])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Drops a module from the load list.
|
# Drops a module from the load list.
|
||||||
|
@ -188,24 +194,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