# Module for vrobot4 server interfaces. module Vrobot4::Server 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" end # @!visibility private def c_help m, argv check_args argv, "", "S" if argv.length == 0 cmds = [] m.serv.each_mod {|mod| cmds << mod.all_cmds(m).keys.join(", ")} cmds.delete "" m.reply "Commands:", cmds.join(", ") else name = argv[0] m.serv.each_mod do |mod| if (cmd = mod.get_cmd m, name) return m.reply name + ":", cmd.help_str end end m.reply "Command not found:", name end end # @!visibility private 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 # @!visibility private def c_modr m, argv check_args argv, "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 check_args argv, "S" m.serv.load_mod argv[0] end # @!visibility private def c_modu m, argv check_args argv, "S" m.serv.drop_mod argv[0] end # @!visibility private def c_dbg m, argv check_args argv, "N" Vrobot4.debug = argv[0].to_i end # @!visibility private def on_command m, cnam, argv Vrobot4.log :DEBUGV, "command", cnam.to_s, argv.to_s super end end private_constant :Mod_Base # Generic user information. May be extended. class User attr_reader :name # Plaintext name of the user. attr_reader :roles # List of user's roles. end # Generic channel information. May be extended. class Channel attr_reader :name # Plaintext name of the channel. end # Generic event information. May not be extended. class Message attr_reader :msg # Plaintext of message (if any.) attr_reader :user # User that triggered this message (if any.) attr_reader :chan # Channel this message was sent to (if any.) attr_reader :serv # Server this message was sent to. # @param info [Hash] A hash containing message info. Keys may be omitted. # [:msg] Plaintext of message. # [:user] User that triggered this message. # [:chan] Channel that this message was sent to. # [:serv] Server this message was sent to. # [:reply] Method that sends a message to the specified channel. # [:reply_b] Method that sends a large message to the specified channel. def initialize(**info) @msg = info[:msg] if info.key? :msg @user = info[:user] if info.key? :user @chan = info[:chan] if info.key? :chan @serv = info[:serv] if info.key? :serv @reply = info[:reply] if info.key? :reply @reply_b = info[:reply_b] if info.key? :reply_b end # Sends a message to the channel this message originated from. def reply *args @reply.call args.join(" ") end # Sends a large message to the channel this message originated from. def reply_b *args @reply_b.call args.join(" ") end end # Generic server interface. class Server attr_reader :mprm # Module permissions for this server. # @param info [Hash] arbitrary extra information for this server def initialize info @info = info @modules = [Mod_Base.new(nil)] load_permissions info["permissions"] if info.key? "permissions" end # Loads and initializes a module into the load list. def load_mod mod mt = Vrobot4::Module.get_module_type(mod) if mt[:server] and mt[:server] != self.class.type or mt[:servflags] and mt[:servflags] !~ flags raise ArgumentError, "Module " + mod + " not valid for this server" end @modules << mt[:type].new(@info.key?(mod) ? @info[mod] : nil) end # Drops a module from the load list. 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 end # Yields for every module loaded in the server. def each_mod @modules.each {|mod| yield mod} end # (see Vrobot4::Module::Module#on_message) # @note Passes information to all modules. def on_message m @modules.each {|mod| break if mod.on_message m} end # (see Vrobot4::Module::Module#on_command) # @note Passes information to all modules. def on_command m, cnam, argv @modules.each {|mod| break if mod.on_command m, cnam, argv} end # Connect to the server. def connect raise NotImplementedError, "Server#connect not implemented" end # Flags for this server. # @return [String] def flags "" end protected # Implementation defined permission loader. # Loads information into +@mprm+. def load_permissions pinf raise NotImplementedError, "Server#load_permissions not implemented" end end # Basis for an audio-enabled server interface. class AudioServer < Server # Joins a voice channel, using a message for context. def voice_join m raise NotImplementedError, "AudioServer#voice_join not implemented" end # Quits a voice channel, using a message for context. def voice_quit m raise NotImplementedError, "AudioServer#voice_quit not implemented" end # Plays an arbitrary audio file in a given context. def play m, io raise NotImplementedError, "AudioServer#play not implemented" end # Check if the bot is playing audio in a given context. def is_playing? m raise NotImplementedError, "AudioServer#is_playing? not implemented" end # (see Vrobot4::Server::Server#flags) def flags "A" end end # Adds a server type to the global list. # @param type [Class] server type to add 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 private @@server_types = {} end ## EOF