Compare commits

...

3 Commits

Author SHA1 Message Date
an 09591b03d1 split quote/fun modules 2019-02-24 06:01:46 -05:00
an 79e6dbd495 change yaml configs to ruby configs 2019-02-24 06:00:41 -05:00
an 8f79a79b4e fix conflation of server and bot 2019-02-24 01:56:59 -05:00
16 changed files with 492 additions and 364 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
*doc *doc
working working
*.yml _config.rb
*.swp *.swp
*.vim *.vim

View File

@ -1 +1 @@
--protected --private --hide-void-return source/*.rb source/servers/*.rb --protected --private --hide-void-return source/*.rb source/backends/*.rb

200
source/backends/discord.rb Normal file
View File

@ -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

144
source/backends/irc.rb Normal file
View File

@ -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

35
source/config_example.rb Normal file
View File

@ -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

View File

@ -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}"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?"

39
source/modules/qdb.rb Normal file
View File

@ -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

View File

@ -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

37
source/robots.rb Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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