2017-08-11 19:40:43 -07:00
|
|
|
# Module for vrobot4 server interfaces.
|
2017-08-06 05:36:15 -07:00
|
|
|
module Vrobot4::Server
|
2017-08-11 19:40:43 -07:00
|
|
|
# Generic user information. May be extended.
|
2017-08-06 05:36:15 -07:00
|
|
|
class User
|
2017-08-12 16:22:31 -07:00
|
|
|
attr_reader :name # @return [String] plaintext name of the user
|
|
|
|
attr_reader :roles # @return [String] list of user's roles
|
2017-08-15 13:48:43 -07:00
|
|
|
attr_reader :id # @return [Integer] unique identifier for the user
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Generic channel information. May be extended.
|
2017-08-08 01:35:20 -07:00
|
|
|
class Channel
|
2017-08-12 16:22:31 -07:00
|
|
|
attr_reader :name # @return [String] plaintext name of the channel
|
2017-08-15 13:48:43 -07:00
|
|
|
attr_reader :id # @return [Integer] unique identifier for the channel
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Generic event information. May not be extended.
|
2017-08-06 05:36:15 -07:00
|
|
|
class Message
|
2017-08-12 16:22:31 -07:00
|
|
|
attr_reader :msg # @return [String] plaintext of message
|
|
|
|
attr_reader :user # @return [User] user that triggered this message
|
|
|
|
attr_reader :chan # @return [Channel] channel this message was sent to
|
|
|
|
attr_reader :serv # @return [Server] server this message was sent to
|
2017-08-11 19:40:43 -07:00
|
|
|
|
|
|
|
# @param info [Hash] A hash containing message info. Keys may be omitted.
|
|
|
|
# [:msg] Plaintext of message.
|
|
|
|
# [:user] User that triggered this message.
|
|
|
|
# [:chan] Channel that this message was sent to.
|
|
|
|
# [:serv] Server this message was sent to.
|
|
|
|
# [:reply] Method that sends a message to the specified channel.
|
|
|
|
# [:reply_b] Method that sends a large message to the specified channel.
|
2017-08-08 21:00:28 -07:00
|
|
|
def initialize(**info)
|
2017-08-11 23:07:09 -07:00
|
|
|
@msg = info[:msg]
|
|
|
|
@user = info[:user]
|
|
|
|
@chan = info[:chan]
|
|
|
|
@serv = info[:serv]
|
|
|
|
@reply = info[:reply]
|
|
|
|
@reply_b = info[:reply_b]
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-15 13:48:43 -07:00
|
|
|
# Sends a message to the originating channel.
|
2017-08-08 01:35:20 -07:00
|
|
|
def reply *args
|
2019-02-23 16:18:39 -08:00
|
|
|
@reply.call args.join(?\s)
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
|
|
|
|
2017-08-15 13:48:43 -07:00
|
|
|
# Sends a large message to the originating channel.
|
2017-08-08 04:33:30 -07:00
|
|
|
def reply_b *args
|
2019-02-23 16:18:39 -08:00
|
|
|
@reply_b.call args.join(?\s)
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Generic server interface.
|
2017-08-06 05:36:15 -07:00
|
|
|
class Server
|
2017-08-12 16:22:31 -07:00
|
|
|
attr_reader :mprm # @return [Hash] module permissions for this server
|
2019-02-23 16:18:39 -08:00
|
|
|
attr_reader :id # @return [Integer] unique identifier for the server
|
2017-08-08 01:35:20 -07:00
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# @param info [Hash] arbitrary extra information for this server
|
2017-08-08 01:35:20 -07:00
|
|
|
def initialize info
|
2017-08-08 21:03:18 -07:00
|
|
|
@info = info
|
2017-08-09 00:52:34 -07:00
|
|
|
@modules = [Mod_Base.new(nil)]
|
2017-08-13 03:48:14 -07:00
|
|
|
load_permissions info["permissions"]
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Loads and initializes a module into the load list.
|
2017-08-13 04:50:52 -07:00
|
|
|
# @param mod [Vrobot4::Module::Module]
|
2017-08-08 01:35:20 -07:00
|
|
|
def load_mod mod
|
|
|
|
mt = Vrobot4::Module.get_module_type(mod)
|
2017-08-11 18:50:43 -07:00
|
|
|
if mt[:server] and mt[:server] != self.class.type or
|
2017-08-13 04:50:52 -07:00
|
|
|
mt[:servflags] and mt[:servflags] !~ flags then
|
2017-08-08 01:35:20 -07:00
|
|
|
raise ArgumentError, "Module " + mod + " not valid for this server"
|
|
|
|
end
|
2017-08-11 23:07:09 -07:00
|
|
|
@modules << mt[:type].new(@info[mod])
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Drops a module from the load list.
|
2017-08-13 04:50:52 -07:00
|
|
|
# @param mod [Vrobot4::Module::Module]
|
2017-08-08 01:35:20 -07:00
|
|
|
def drop_mod mod
|
|
|
|
mt = Vrobot4::Module.get_module_type(mod)
|
|
|
|
@modules.each_index do |i|
|
|
|
|
@modules.delete_at i if @modules[i].is_a? mt[:type]
|
|
|
|
end
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Yields for every module loaded in the server.
|
2017-08-08 01:35:20 -07:00
|
|
|
def each_mod
|
|
|
|
@modules.each {|mod| yield mod}
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# (see Vrobot4::Module::Module#on_message)
|
2017-08-11 21:56:33 -07:00
|
|
|
# Passes information to all modules.
|
2017-08-11 15:16:16 -07:00
|
|
|
def on_message m
|
2017-08-13 04:50:52 -07:00
|
|
|
@modules.each do |mod|
|
|
|
|
break if mod.class.usable_in? m and mod.on_message m
|
|
|
|
end
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# (see Vrobot4::Module::Module#on_command)
|
2017-08-11 21:56:33 -07:00
|
|
|
# Passes information to all modules.
|
2017-08-11 15:16:16 -07:00
|
|
|
def on_command m, cnam, argv
|
2017-08-13 04:50:52 -07:00
|
|
|
@modules.each do |mod|
|
|
|
|
break if mod.class.usable_in? m and mod.on_command m, cnam, argv
|
|
|
|
end
|
2017-08-08 01:35:20 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Connect to the server.
|
|
|
|
def connect
|
|
|
|
raise NotImplementedError, "Server#connect not implemented"
|
|
|
|
end
|
|
|
|
|
|
|
|
# Flags for this server.
|
2017-08-11 21:56:33 -07:00
|
|
|
# [A] Server has audio capabilities and inherits from AudioServer.
|
|
|
|
# [L] Server cannot support large text dumps
|
|
|
|
# (code should assume <=4 lines, 240 characters per as maximum)
|
2017-08-11 19:40:43 -07:00
|
|
|
# @return [String]
|
2017-08-08 04:32:45 -07:00
|
|
|
def flags
|
|
|
|
""
|
|
|
|
end
|
|
|
|
|
2017-08-13 03:48:00 -07:00
|
|
|
# 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 an on_message event.
|
|
|
|
#
|
|
|
|
# @param m [Vrobot4::Server::Message] the message to parse and emit
|
|
|
|
def handle_text_cmd m
|
2019-02-23 16:18:39 -08:00
|
|
|
if m.msg.start_with? ?.
|
|
|
|
arg = m.msg.split(?\s, 2)
|
2017-08-13 04:50:52 -07:00
|
|
|
on_command m, arg[0][1 .. -1], arg[1] || ""
|
2017-08-13 03:48:00 -07:00
|
|
|
else
|
|
|
|
on_message m
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-09 23:31:12 -07:00
|
|
|
protected
|
2017-08-11 19:40:43 -07:00
|
|
|
# Implementation defined permission loader.
|
|
|
|
# Loads information into +@mprm+.
|
2017-08-08 01:35:20 -07:00
|
|
|
def load_permissions pinf
|
2017-08-11 19:40:43 -07:00
|
|
|
raise NotImplementedError, "Server#load_permissions not implemented"
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Basis for an audio-enabled server interface.
|
2017-08-08 21:03:18 -07:00
|
|
|
class AudioServer < Server
|
2017-09-11 04:00:24 -07:00
|
|
|
## TODO: make API for this
|
2017-08-08 21:03:18 -07:00
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# (see Vrobot4::Server::Server#flags)
|
2017-08-08 21:03:18 -07:00
|
|
|
def flags
|
2019-02-23 16:18:39 -08:00
|
|
|
?A
|
2017-08-08 21:03:18 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-13 04:50:52 -07:00
|
|
|
class Mod_Base < Vrobot4::Module::Module
|
|
|
|
def initialize info
|
|
|
|
super
|
|
|
|
register :c_help, "help", "Prints documentation for commands."
|
2019-02-23 16:18:39 -08:00
|
|
|
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
|
2017-08-13 04:50:52 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
# @!visibility private
|
|
|
|
def c_help m, argv
|
|
|
|
if argv.empty?
|
|
|
|
cmds = []
|
|
|
|
m.serv.each_mod {|mod| cmds << mod.cmds(m).keys.join(", ")}
|
|
|
|
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
|
|
|
|
|
|
|
|
# @!visibility private
|
|
|
|
def c_die m, argv
|
2019-02-23 16:18:39 -08:00
|
|
|
m.serv.voice_quit m if m.serv.flags.include? ?A
|
2017-08-13 04:50:52 -07:00
|
|
|
m.reply \
|
|
|
|
["STATUS: DYING",
|
|
|
|
"ded",
|
|
|
|
"proceeding to die",
|
|
|
|
"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
|
|
|
|
private_constant :Mod_Base
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# Adds a server type to the global list.
|
|
|
|
# @param type [Class] server type to add
|
2017-08-11 18:50:43 -07:00
|
|
|
def self.add_server_type type
|
|
|
|
@@server_types[type.type] = type
|
|
|
|
Vrobot4.log :INFO, "added server type:", type.type
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
2017-08-11 19:40:43 -07:00
|
|
|
# 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]
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
2017-08-11 19:40:43 -07:00
|
|
|
|
|
|
|
private
|
|
|
|
@@server_types = {}
|
2017-08-06 05:36:15 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
## EOF
|