documentation and version bump
parent
10b23a9d8c
commit
34aeec60dc
|
@ -1 +1 @@
|
||||||
--protected source/*.rb source/servers/*.rb
|
--protected --private --hide-void-return source/*.rb source/servers/*.rb
|
||||||
|
|
|
@ -1,23 +1,30 @@
|
||||||
|
require 'zlib'
|
||||||
|
|
||||||
# Module for the main vrobot4 program and global info.
|
# Module for the main vrobot4 program and global info.
|
||||||
module Vrobot4
|
module Vrobot4
|
||||||
# The current program version.
|
# The current program version.
|
||||||
Version = "4.00".freeze
|
Version = "4.01".freeze
|
||||||
|
|
||||||
def self.debug=(set) @@debug = set end # Sets the current debug level.
|
# Sets the current debug level.
|
||||||
def self.debug ( ) @@debug end # Gets the current debug level.
|
# @param set [Integer] the debug level
|
||||||
|
# @return [void]
|
||||||
|
def self.set_debug set
|
||||||
|
@@debug = set
|
||||||
|
end
|
||||||
|
|
||||||
# Logs to the console.
|
# Logs to the console.
|
||||||
#
|
#
|
||||||
# @param lv [Symbol]
|
# @param lv [Symbol] the log level
|
||||||
# - If +:DEBUG+, this message will not be printed if the global debug
|
# [+:INFO+] This message will always be printed.
|
||||||
# level is less than 1.
|
# [+:DEBUG+] This message will not be printed if the global debug level is
|
||||||
# - If +:DEBUGV+, this message will not be printed if the global debug
|
# less than 1.
|
||||||
# level is less than 2.
|
# [+:DEBUGV+] This message will not be printed if the global debug level is
|
||||||
|
# less than 2.
|
||||||
# @return [Boolean] true if the message was printed, false otherwise
|
# @return [Boolean] true if the message was printed, false otherwise
|
||||||
def self.log lv, *text
|
def self.log lv, text
|
||||||
if (lv != :DEBUG || @@debug >= 1) &&
|
if (lv != :DEBUG || @@debug >= 1) &&
|
||||||
(lv != :DEBUGV || @@debug >= 2)
|
(lv != :DEBUGV || @@debug >= 2)
|
||||||
puts "[" + lv.to_s.ljust(6) + "] " + text.join(?\s)
|
puts "[#{lv.to_s.ljust 6}] #{text}"
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
@ -25,13 +32,18 @@ module Vrobot4
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the argument +s+ is a numeric string.
|
# Checks if the argument +s+ is a numeric string.
|
||||||
# @param str [String] the string to check
|
# @param s [String] the string to check
|
||||||
def self.is_num? str
|
# @return [Boolean] true if +s+ is a numeric string, false otherwise
|
||||||
/\A[-+]?[0-9]*\.?[0-9]+\Z/ === str
|
def self.is_num? s
|
||||||
|
/\A[-+]?[0-9]*\.?[0-9]+\Z/ === s
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
# Does a stable hash on +s+.
|
||||||
@@debug = 0
|
# @param s [String] the string to hash
|
||||||
|
# @return [Integer]
|
||||||
|
def self.hash_str s
|
||||||
|
Zlib.crc32 s
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
## EOF
|
## EOF
|
||||||
|
|
|
@ -6,54 +6,80 @@ require 'yaml'
|
||||||
|
|
||||||
module Vrobot4
|
module Vrobot4
|
||||||
private
|
private
|
||||||
def self.loadBot botinfo
|
|
||||||
type = botinfo["type"]
|
|
||||||
serv = Server::get_server_type(type).new(botinfo)
|
|
||||||
|
|
||||||
if botinfo.key? "modules" then for mod in botinfo["modules"] do
|
# Loads a bot from its configuration +botinfo+.
|
||||||
|
# @param botinfo [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
|
serv.load_mod mod
|
||||||
end end
|
end
|
||||||
|
|
||||||
serv
|
serv
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.runBots bots
|
# Runs all bots in +bots+ in separate threads.
|
||||||
thrds = []
|
# @param bots [Array<Vrobot4::Server>] all bots to run
|
||||||
bots.each {|serv| thrds << Thread.new {serv.connect}}
|
# @return [void]
|
||||||
thrds.each {|th| th.join}
|
def self.run_bots bots
|
||||||
|
threads = []
|
||||||
|
|
||||||
|
bots.each do |server|
|
||||||
|
threads << Thread.new do
|
||||||
|
server.connect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
threads.each do |thread|
|
||||||
|
thread.join
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
public
|
public
|
||||||
|
|
||||||
# Runs the program.
|
# Runs the program.
|
||||||
# @param cfg [IO] configuration file to load
|
# @param cfg [IO] configuration file to read
|
||||||
|
# @return [void]
|
||||||
def self.main cfg
|
def self.main cfg
|
||||||
log :INFO, "vrobot version", Version
|
Thread.abort_on_exception = true
|
||||||
|
|
||||||
|
log :INFO, "vrobot version #{Version}"
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cfg = YAML.load cfg.read
|
cfg = YAML.load cfg.read
|
||||||
rescue
|
rescue
|
||||||
log :ERROR, "error reading bot config:", $!
|
log :ERROR, "error reading bot config: #{$!}"
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
Vrobot4.debug = cfg["debug"] if cfg.key? "debug"
|
Vrobot4.set_debug(cfg["debug"] || 0)
|
||||||
cfg["loadmods"].each {|mod| load mod, true}
|
|
||||||
|
cfg["load"].each do |mod|
|
||||||
|
load mod, true
|
||||||
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
bots = []
|
bots = []
|
||||||
cfg["bots"].each {|botinfo| bots << loadBot(botinfo)}
|
|
||||||
log :DEBUGV, "bots:", bots.to_s
|
cfg["bots"].each do |botinfo|
|
||||||
|
bots << load_bot(botinfo)
|
||||||
|
end
|
||||||
|
|
||||||
|
log :DEBUGV, "bots: #{bots.to_s}"
|
||||||
rescue
|
rescue
|
||||||
log :ERROR, "error loading bot config:",
|
err = $!.to_s + ?\n + $!.backtrace.first(3).join(?\n)
|
||||||
$!.to_s + ?\n + $!.backtrace.first(3).join(?\n)
|
log :ERROR, "error loading bot config: #{err}"
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
runBots bots
|
run_bots bots
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Thread.abort_on_exception = true
|
Vrobot4.main open ARGV[0]
|
||||||
Vrobot4.main open(ARGV[0])
|
|
||||||
|
|
||||||
## EOF
|
## EOF
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Module for vrobot4 bot modules.
|
# Module for vrobot4 bot modules.
|
||||||
module Vrobot4::Module
|
module Vrobot4::Module
|
||||||
# A command function. Holds extra info for i.e. permissions.
|
# A command function. Holds extra info such as help and permissions.
|
||||||
class Command
|
class Command
|
||||||
attr_reader :help_str # @return [String] help string for this command
|
attr_reader :help_str # @return [String] help string for this command
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ module Vrobot4::Module
|
||||||
|
|
||||||
# Checks if this command is usable in a given context.
|
# Checks if this command is usable in a given context.
|
||||||
# @param m [Vrobot4::Server::Message] message for context
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
|
# @return [Boolean] true if command is usable, false otherwise
|
||||||
def usable_in? m
|
def usable_in? m
|
||||||
m.user.roles.scan(@roles).any? and @function.owner.usable_in? m
|
m.user.roles.scan(@roles).any? and @function.owner.usable_in? m
|
||||||
end
|
end
|
||||||
|
@ -22,6 +23,7 @@ module Vrobot4::Module
|
||||||
# Calls the method attached to this command.
|
# Calls the method attached to this command.
|
||||||
# @param m [Vrobot4::Server::Message] message for context
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
# @param argv [String] argument string
|
# @param argv [String] argument string
|
||||||
|
# @return [void]
|
||||||
def run m, argv
|
def run m, argv
|
||||||
@function.call(m, argv)
|
@function.call(m, argv)
|
||||||
end
|
end
|
||||||
|
@ -31,6 +33,7 @@ module Vrobot4::Module
|
||||||
class Module
|
class Module
|
||||||
# Checks if this module is usable in a given context.
|
# Checks if this module is usable in a given context.
|
||||||
# @param m [Vrobot4::Server::Message] message for context
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
|
# @return [Boolean] true if usable, false otherwise
|
||||||
def self.usable_in? m
|
def self.usable_in? m
|
||||||
role = m.user.roles
|
role = m.user.roles
|
||||||
mprm = m.serv.mprm
|
mprm = m.serv.mprm
|
||||||
|
@ -45,7 +48,7 @@ module Vrobot4::Module
|
||||||
def initialize info
|
def initialize info
|
||||||
@commands = {}
|
@commands = {}
|
||||||
@info = info
|
@info = info
|
||||||
Vrobot4.log :DEBUG, "initialized", self.to_s
|
Vrobot4.log :DEBUG, "initialized #{self.to_s}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Callback for message receiving.
|
# Callback for message receiving.
|
||||||
|
@ -75,12 +78,16 @@ module Vrobot4::Module
|
||||||
|
|
||||||
# Gets all commands usable in a specified context.
|
# Gets all commands usable in a specified context.
|
||||||
# @param m [Vrobot4::Server::Message] message for context
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
# @return [Hash] a hash of all commands by name
|
# @return [Hash<String, Vrobot4::Module::Command>]
|
||||||
|
# a hash of all commands by name
|
||||||
def cmds m
|
def cmds m
|
||||||
@commands.select {|name, cmd| cmd.usable_in? m}
|
@commands.select do |name, cmd|
|
||||||
|
cmd.usable_in? m
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Registers a command into this module.
|
# Registers a command into this module.
|
||||||
# @param fn [Symbol] name of method to add
|
# @param fn [Symbol] name of method to add
|
||||||
# @param names [String, Array] name(s) to add this command by
|
# @param names [String, Array] name(s) to add this command by
|
||||||
|
@ -108,7 +115,7 @@ module Vrobot4::Module
|
||||||
# @param argv [String, Array] array of arguments or a string
|
# @param argv [String, Array] array of arguments or a string
|
||||||
# @param req [String] specifier string of required arguments
|
# @param req [String] specifier string of required arguments
|
||||||
# @param opt [String] specifier string of optional arguments
|
# @param opt [String] specifier string of optional arguments
|
||||||
# @return argv
|
# @return [String, Array] argv
|
||||||
def check_args argv, req, opt = ""
|
def check_args argv, req, opt = ""
|
||||||
if argv.is_a? Array then
|
if argv.is_a? Array then
|
||||||
if argv.length < req.length
|
if argv.length < req.length
|
||||||
|
@ -137,15 +144,21 @@ module Vrobot4::Module
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# Helper function for {#check_args}.
|
||||||
|
# @param arg [String] the argument to check
|
||||||
|
# @param i [Integer] which argument this is
|
||||||
|
# @param req [String] type that the argument should be
|
||||||
|
# @return [void]
|
||||||
def check_arg arg, i, req
|
def check_arg arg, i, req
|
||||||
case req
|
case req
|
||||||
when ?N
|
when ?N
|
||||||
unless Vrobot4.is_num? arg.strip
|
unless Vrobot4.is_num? arg.strip
|
||||||
raise ArgumentError, "Expected a number for arg " + i.to_s
|
raise ArgumentError, "Expected a number for arg #{i}"
|
||||||
end
|
end
|
||||||
when ?S # Don't need to check anything here.
|
when ?S # Don't need to check anything here.
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Invalid argument specifier " + req.to_s
|
raise ArgumentError, "Invalid argument specifier #{req}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -154,13 +167,14 @@ module Vrobot4::Module
|
||||||
# @param type [Class] module type to add
|
# @param type [Class] module type to add
|
||||||
# @param server [String] server type this module is restricted to (or none)
|
# @param server [String] server type this module is restricted to (or none)
|
||||||
# @param servflags [String] flags the server must have to use this (or none)
|
# @param servflags [String] flags the server must have to use this (or none)
|
||||||
|
# @return [void]
|
||||||
def self.add_module_type type, server: nil, servflags: nil
|
def self.add_module_type type, server: nil, servflags: nil
|
||||||
@@module_types[type.type] = {
|
@@module_types[type.type] = {
|
||||||
type: type,
|
type: type,
|
||||||
server: server,
|
server: server,
|
||||||
servflags: servflags ? /[#{servflags}]/ : nil
|
servflags: servflags ? /[#{servflags}]/ : nil
|
||||||
}
|
}
|
||||||
Vrobot4.log :INFO, "added module type:", type.type
|
Vrobot4.log :INFO, "added module type #{type.type}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets a module type by name from the global list.
|
# Gets a module type by name from the global list.
|
||||||
|
@ -170,7 +184,7 @@ module Vrobot4::Module
|
||||||
@@module_types[name]
|
@@module_types[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
# The set of all module types.
|
||||||
@@module_types = {}
|
@@module_types = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
class Mod_Base < Vrobot4::Module::Module
|
||||||
|
def initialize info
|
||||||
|
super
|
||||||
|
register :c_help, "help", "Prints documentation for commands."
|
||||||
|
register :c_die, "die", "Kills all bot instances.", roles: ?o
|
||||||
|
register :c_modr, "modr", "Reloads a module.", roles: ?o
|
||||||
|
register :c_modl, "modl", "Loads a module.", roles: ?o
|
||||||
|
register :c_modu, "modu", "Unloads a module.", roles: ?o
|
||||||
|
register :c_dbg, "dbg", "Sets the debug level.", roles: ?o
|
||||||
|
register :c_info, "info", "Prints context info.", roles: ?o
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_help m, argv
|
||||||
|
if argv.empty?
|
||||||
|
cmds = []
|
||||||
|
m.serv.each_mod do |mod|
|
||||||
|
cmds << mod.cmds(m).keys.join(", ")
|
||||||
|
end
|
||||||
|
cmds.delete ""
|
||||||
|
m.reply "Commands:", cmds.join(", ")
|
||||||
|
else
|
||||||
|
m.serv.each_mod do |mod|
|
||||||
|
if (cmd = mod.cmds(m)[argv])
|
||||||
|
return m.reply argv + ":", cmd.help_str
|
||||||
|
end
|
||||||
|
end
|
||||||
|
m.reply "Command not found:", argv
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_die m, argv
|
||||||
|
m.serv.voice_quit m if m.serv.flags.include? ?A
|
||||||
|
m.reply \
|
||||||
|
["STATUS: DYING",
|
||||||
|
"ded",
|
||||||
|
"proceeding to die",
|
||||||
|
"bye",
|
||||||
|
"dedededed",
|
||||||
|
"Thanks, bye!",
|
||||||
|
"GOTTAGOBYE",
|
||||||
|
"the orks insisted upon dying"].sample
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_modr m, argv
|
||||||
|
argv = check_args argv.split, "S", "S"
|
||||||
|
m.serv.drop_mod argv[0]
|
||||||
|
load argv[1], true if argv.length > 1
|
||||||
|
m.serv.load_mod argv[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_modl m, argv
|
||||||
|
m.serv.load_mod argv
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_modu m, argv
|
||||||
|
m.serv.drop_mod argv
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_dbg m, argv
|
||||||
|
check_args argv, "N"
|
||||||
|
Vrobot4.debug = argv.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def c_info m, argv
|
||||||
|
m.reply_b <<~_end_
|
||||||
|
chan.name: #{m.chan.name}
|
||||||
|
chan.id: #{m.chan.id}
|
||||||
|
user.name: #{m.user.name}
|
||||||
|
user.id: #{m.user.id}
|
||||||
|
user.roles: #{m.user.roles}
|
||||||
|
serv.flags: #{m.serv.flags}
|
||||||
|
serv.id: #{m.serv.id}
|
||||||
|
serv.mprm: #{m.serv.mprm}
|
||||||
|
_end_
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_command m, cnam, argv
|
||||||
|
Vrobot4.log :DEBUGV, "command #{cnam.to_s} #{argv}"
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
## EOF
|
136
source/server.rb
136
source/server.rb
|
@ -1,5 +1,7 @@
|
||||||
# Module for vrobot4 server interfaces.
|
# Module for vrobot4 server interfaces.
|
||||||
module Vrobot4::Server
|
module Vrobot4::Server
|
||||||
|
require "./modules/base.rb"
|
||||||
|
|
||||||
# Generic user information. May be extended.
|
# Generic user information. May be extended.
|
||||||
class User
|
class User
|
||||||
attr_reader :name # @return [String] plaintext name of the user
|
attr_reader :name # @return [String] plaintext name of the user
|
||||||
|
@ -37,11 +39,15 @@ module Vrobot4::Server
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a message to the originating channel.
|
# Sends a message to the originating channel.
|
||||||
|
# @param args [Array<String>] the text to send
|
||||||
|
# @return [void]
|
||||||
def reply *args
|
def reply *args
|
||||||
@reply.call args.join(?\s)
|
@reply.call args.join(?\s)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a large message to the originating channel.
|
# Sends a large message to the originating channel.
|
||||||
|
# @param args [Array<String>] the text to send
|
||||||
|
# @return [void]
|
||||||
def reply_b *args
|
def reply_b *args
|
||||||
@reply_b.call args.join(?\s)
|
@reply_b.call args.join(?\s)
|
||||||
end
|
end
|
||||||
|
@ -61,6 +67,7 @@ module Vrobot4::Server
|
||||||
|
|
||||||
# Loads and initializes a module into the load list.
|
# Loads and initializes a module into the load list.
|
||||||
# @param mod [Vrobot4::Module::Module]
|
# @param mod [Vrobot4::Module::Module]
|
||||||
|
# @return [void]
|
||||||
def load_mod mod
|
def load_mod mod
|
||||||
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
|
||||||
|
@ -72,6 +79,7 @@ module Vrobot4::Server
|
||||||
|
|
||||||
# Drops a module from the load list.
|
# Drops a module from the load list.
|
||||||
# @param mod [Vrobot4::Module::Module]
|
# @param mod [Vrobot4::Module::Module]
|
||||||
|
# @return [void]
|
||||||
def drop_mod mod
|
def drop_mod mod
|
||||||
mt = Vrobot4::Module.get_module_type(mod)
|
mt = Vrobot4::Module.get_module_type(mod)
|
||||||
@modules.each_index do |i|
|
@modules.each_index do |i|
|
||||||
|
@ -80,12 +88,16 @@ module Vrobot4::Server
|
||||||
end
|
end
|
||||||
|
|
||||||
# Yields for every module loaded in the server.
|
# Yields for every module loaded in the server.
|
||||||
|
# @yieldparam mod [Vrobot4::Module::Module] an individual module
|
||||||
|
# @return [void]
|
||||||
def each_mod
|
def each_mod
|
||||||
@modules.each {|mod| yield mod}
|
@modules.each do |mod|
|
||||||
|
yield mod
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# (see Vrobot4::Module::Module#on_message)
|
# (see Vrobot4::Module::Module#on_message)
|
||||||
# Passes information to all modules.
|
# This function passes information to all modules.
|
||||||
def on_message m
|
def on_message m
|
||||||
@modules.each do |mod|
|
@modules.each do |mod|
|
||||||
break if mod.class.usable_in? m and mod.on_message m
|
break if mod.class.usable_in? m and mod.on_message m
|
||||||
|
@ -93,7 +105,7 @@ module Vrobot4::Server
|
||||||
end
|
end
|
||||||
|
|
||||||
# (see Vrobot4::Module::Module#on_command)
|
# (see Vrobot4::Module::Module#on_command)
|
||||||
# Passes information to all modules.
|
# This function passes information to all modules.
|
||||||
def on_command m, cnam, argv
|
def on_command m, cnam, argv
|
||||||
@modules.each do |mod|
|
@modules.each do |mod|
|
||||||
break if mod.class.usable_in? m and mod.on_command m, cnam, argv
|
break if mod.class.usable_in? m and mod.on_command m, cnam, argv
|
||||||
|
@ -101,27 +113,27 @@ module Vrobot4::Server
|
||||||
end
|
end
|
||||||
|
|
||||||
# Connect to the server.
|
# Connect to the server.
|
||||||
|
# @abstract
|
||||||
|
# @return [void]
|
||||||
def connect
|
def connect
|
||||||
raise NotImplementedError, "Server#connect not implemented"
|
raise NotImplementedError, "Server#connect not implemented"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Flags for this server.
|
# Flags for this server.
|
||||||
# [A] Server has audio capabilities and inherits from AudioServer.
|
# [A] Server has audio capabilities and inherits from
|
||||||
|
# {Vrobot4::Server::AudioServer}.
|
||||||
# [L] Server cannot support large text dumps
|
# [L] Server cannot support large text dumps
|
||||||
# (code should assume <=4 lines, 240 characters per as maximum)
|
# (code should assume <=4 lines, 240 characters per as maximum)
|
||||||
# @return [String]
|
# @return [String] all available flags
|
||||||
def flags
|
def flags
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
|
|
||||||
# Basic command message handler.
|
# Checks if the message starts with +.+ and splits the command from the
|
||||||
#
|
# arguments, then emits an {#on_command} event. Otherwise, it will emit
|
||||||
# Checks if the message starts with "." and splits the command
|
# an {#on_message} event.
|
||||||
# from the arguments, then emits an on_command event.
|
|
||||||
#
|
|
||||||
# Otherwise, it will emit an on_message event.
|
|
||||||
#
|
|
||||||
# @param m [Vrobot4::Server::Message] the message to parse and emit
|
# @param m [Vrobot4::Server::Message] the message to parse and emit
|
||||||
|
# @return [void]
|
||||||
def handle_text_cmd m
|
def handle_text_cmd m
|
||||||
if m.msg.start_with? ?.
|
if m.msg.start_with? ?.
|
||||||
arg = m.msg.split(?\s, 2)
|
arg = m.msg.split(?\s, 2)
|
||||||
|
@ -132,8 +144,12 @@ module Vrobot4::Server
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Implementation defined permission loader.
|
# Implementation defined permission loader.
|
||||||
# Loads information into +@mprm+.
|
# Loads information into +@mprm+.
|
||||||
|
# @abstract
|
||||||
|
# @param pinf [Hash] arbitrary permissions information
|
||||||
|
# @return [void]
|
||||||
def load_permissions pinf
|
def load_permissions pinf
|
||||||
raise NotImplementedError, "Server#load_permissions not implemented"
|
raise NotImplementedError, "Server#load_permissions not implemented"
|
||||||
end
|
end
|
||||||
|
@ -141,94 +157,44 @@ module Vrobot4::Server
|
||||||
|
|
||||||
# Basis for an audio-enabled server interface.
|
# Basis for an audio-enabled server interface.
|
||||||
class AudioServer < Server
|
class AudioServer < Server
|
||||||
## TODO: make API for this
|
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#flags)
|
# (see Vrobot4::Server::Server#flags)
|
||||||
def flags
|
def flags
|
||||||
?A
|
?A
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
class Mod_Base < Vrobot4::Module::Module
|
# Quit using voice channels.
|
||||||
def initialize info
|
# @abstract
|
||||||
super
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
register :c_help, "help", "Prints documentation for commands."
|
# @return [void]
|
||||||
register :c_die, "die", "Kills all bot instances.", roles: ?o
|
def voice_quit m
|
||||||
register :c_modr, "modr", "Reloads a module.", roles: ?o
|
raise NotImplementedError, "AudioServer#voice_quit not implemented"
|
||||||
register :c_modl, "modl", "Loads a module.", roles: ?o
|
|
||||||
register :c_modu, "modu", "Unloads a module.", roles: ?o
|
|
||||||
register :c_dbg, "dbg", "Sets the debug level.", roles: ?o
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# Plays an audio file by name into the current voice channel.
|
||||||
def c_help m, argv
|
# @abstract
|
||||||
if argv.empty?
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
cmds = []
|
# @param fname [String] file name
|
||||||
m.serv.each_mod {|mod| cmds << mod.cmds(m).keys.join(", ")}
|
# @return [void]
|
||||||
cmds.delete ""
|
def voice_play m, fname
|
||||||
m.reply "Commands:", cmds.join(", ")
|
raise NotImplementedError, "AudioServer#voice_play not implemented"
|
||||||
else
|
|
||||||
m.serv.each_mod do |mod|
|
|
||||||
if (cmd = mod.cmds(m)[argv])
|
|
||||||
return m.reply argv + ":", cmd.help_str
|
|
||||||
end
|
|
||||||
end
|
|
||||||
m.reply "Command not found:", argv
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# Plays an audio I/O stream into the current voice channel.
|
||||||
def c_die m, argv
|
# @abstract
|
||||||
m.serv.voice_quit m if m.serv.flags.include? ?A
|
# @param m [Vrobot4::Server::Message] message for context
|
||||||
m.reply \
|
# @param io [IO] io stream
|
||||||
["STATUS: DYING",
|
# @return [void]
|
||||||
"ded",
|
def voice_play_io m, io
|
||||||
"proceeding to die",
|
raise NotImplementedError, "AudioServer#voice_play_io not implemented"
|
||||||
"bye",
|
|
||||||
"dedededed",
|
|
||||||
"Thanks, bye!",
|
|
||||||
"GOTTAGOBYE",
|
|
||||||
"the orks insisted upon dying"].sample
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def c_modr m, argv
|
|
||||||
argv = check_args argv.split, "S", "S"
|
|
||||||
m.serv.drop_mod argv[0]
|
|
||||||
load argv[1], true if argv.length > 1
|
|
||||||
m.serv.load_mod argv[0]
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def c_modl m, argv
|
|
||||||
m.serv.load_mod argv
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def c_modu m, argv
|
|
||||||
m.serv.drop_mod argv
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def c_dbg m, argv
|
|
||||||
check_args argv, "N"
|
|
||||||
Vrobot4.debug = argv.to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def on_command m, cnam, argv
|
|
||||||
Vrobot4.log :DEBUGV, "command", cnam.to_s, argv
|
|
||||||
super
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private_constant :Mod_Base
|
|
||||||
|
|
||||||
# Adds a server type to the global list.
|
# Adds a server type to the global list.
|
||||||
# @param type [Class] server type to add
|
# @param type [Class] server type to add
|
||||||
|
# @return [void]
|
||||||
def self.add_server_type type
|
def self.add_server_type type
|
||||||
@@server_types[type.type] = type
|
@@server_types[type.type] = type
|
||||||
Vrobot4.log :INFO, "added server type:", type.type
|
Vrobot4.log :INFO, "added server type: #{type.type}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets a server type by name from the global list.
|
# Gets a server type by name from the global list.
|
||||||
|
@ -238,7 +204,7 @@ module Vrobot4::Server
|
||||||
@@server_types[name]
|
@@server_types[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
# The set of all server types.
|
||||||
@@server_types = {}
|
@@server_types = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,30 +28,32 @@ class Sv_Discord < Vrobot4::Server::AudioServer
|
||||||
chan: Channel.new(evt.channel),
|
chan: Channel.new(evt.channel),
|
||||||
serv: self,
|
serv: self,
|
||||||
reply: -> (text) {evt.respond text},
|
reply: -> (text) {evt.respond text},
|
||||||
reply_b: -> (text) {evt.respond "```\n" + text + "```"}
|
reply_b: -> (text) {evt.respond "```\n#{text}```"}
|
||||||
|
|
||||||
handle_text_cmd m
|
handle_text_cmd m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_join)
|
# (see Vrobot4::Server::AudioServer#voice_quit)
|
||||||
def voice_quit m
|
def voice_quit m
|
||||||
@bot.voice_destroy m.chan.real.server.id
|
@bot.voice_destroy m.chan.real.server.id
|
||||||
end
|
end
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_play)
|
# (see Vrobot4::Server::AudioServer#voice_play)
|
||||||
def voice_play m, fname
|
def voice_play m, fname
|
||||||
vc = @bot.voice(m.chan.real)
|
vc = @bot.voice m.chan.real
|
||||||
raise RuntimeError, "I'm not in a voice channel" unless vc
|
raise RuntimeError, "I'm not in a voice channel" unless vc
|
||||||
vc.play_file fname
|
vc.play_file fname
|
||||||
end
|
end
|
||||||
|
|
||||||
# (see Vrobot4::Server::AudioServer#voice_play_io)
|
# (see Vrobot4::Server::AudioServer#voice_play_io)
|
||||||
def voice_play_io m, io
|
def voice_play_io m, io
|
||||||
vc = @bot.voice(m.chan.real)
|
vc = @bot.voice m.chan.real
|
||||||
raise ArgumentError, "Invalid i/o stream" unless io
|
raise ArgumentError, "Invalid IO stream" unless io
|
||||||
raise RuntimeError, "I'm not in a voice channel" unless vc
|
raise RuntimeError, "I'm not in a voice channel" unless vc
|
||||||
Thread.new {vc.play_io io}
|
Thread.new do
|
||||||
|
vc.play_io io
|
||||||
|
end
|
||||||
# HACK
|
# HACK
|
||||||
sleep 1
|
sleep 1
|
||||||
oldst = nil
|
oldst = nil
|
||||||
|
@ -72,6 +74,7 @@ class Sv_Discord < Vrobot4::Server::AudioServer
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# (see Vrobot4::Server::Server#load_permissions)
|
# (see Vrobot4::Server::Server#load_permissions)
|
||||||
def load_permissions pinf
|
def load_permissions pinf
|
||||||
@mprm = {chan: {}, role: {}, glob: {}}
|
@mprm = {chan: {}, role: {}, glob: {}}
|
||||||
|
@ -88,13 +91,18 @@ class Sv_Discord < Vrobot4::Server::AudioServer
|
||||||
end if pinf
|
end if pinf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Helper for channel permissions handling.
|
||||||
class ChannelPerms
|
class ChannelPerms
|
||||||
def initialize() @cprm = {} end
|
def initialize() @cprm = {} end
|
||||||
|
|
||||||
# Returns true if the channel is enabled, false otherwise.
|
# @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
|
def [](chan) @cprm[chan.name] or @cprm[chan.real.id] end
|
||||||
|
|
||||||
# Sets a channel's permission on/off.
|
# 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
|
def []=(chan, set) @cprm[chan] = set end
|
||||||
end
|
end
|
||||||
private_constant :ChannelPerms
|
private_constant :ChannelPerms
|
||||||
|
@ -114,9 +122,9 @@ class Sv_Discord < Vrobot4::Server::AudioServer
|
||||||
if user.is_a? Discordrb::Member
|
if user.is_a? Discordrb::Member
|
||||||
if user.owner?
|
if user.owner?
|
||||||
@roles += "Ooh"
|
@roles += "Ooh"
|
||||||
elsif ops and ops.any? {|role| user.role? role}
|
elsif ops and ops.any? do |role| user.role? role end
|
||||||
@roles += "oh"
|
@roles += "oh"
|
||||||
elsif hop and hop.any? {|role| user.role? role}
|
elsif hop and hop.any? do |role| user.role? role end
|
||||||
@roles += "h"
|
@roles += "h"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue