Update how Addons are used
After some more reading, update the logic for handling the addons. Leverage an "addons module" (Addon), and require that each addon be a class within that module. Within that class, optionally include a `self.register` method, which will be called when the bot is initialized. This method takes one parameter: the bot instance.Registering the addon adds the bot's instance to an instance of the addon, and vice versa, allowing the instances to communicate. Additionally, registering adds the addons commands. Each registered addon must also include a `matrix_command` method, which takes the message String from Matrix. The intention here is to include additional `*_command` methods for different protocols, without having to change much else. Adding additional protocols will determine how well that works. chronicle_bot.rb: Redo addon logic (details above) addons/utils.rb: Update for new addon logic (details above) addons/roller.rb: Update for new addon logic (details above)
This commit is contained in:
parent
faa62604ef
commit
6fe1a7a251
3 changed files with 158 additions and 110 deletions
|
@ -1,30 +1,42 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Chronicle
|
module Chronicle
|
||||||
module Matrix
|
module Addon
|
||||||
# Roll dice and get the results
|
# Roll dice and get the results
|
||||||
|
class Roller
|
||||||
|
def self.register(bot)
|
||||||
|
addon_instance = new(bot)
|
||||||
|
addon_command = ['roll']
|
||||||
|
|
||||||
|
[addon_instance, addon_command]
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(bot)
|
||||||
|
@bot = bot
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle a command from the Matrix protocol
|
||||||
#
|
#
|
||||||
# @param message [hash] The message data from Matrix
|
# @param message [hash] The message data from Matrix
|
||||||
def handle_roll(client, message)
|
def matrix_command(message)
|
||||||
msgstr = message.content[:body]
|
msgstr = message.content[:body]
|
||||||
.gsub(/!roll\s*/, '')
|
.gsub(/!roll\s*/, '')
|
||||||
.strip
|
.strip
|
||||||
|
|
||||||
room = client.ensure_room(message.room_id)
|
room = @bot.client.ensure_room(message.room_id)
|
||||||
|
|
||||||
res = Roller.roll(msgstr)
|
res = roll(msgstr)
|
||||||
|
|
||||||
final_msg = res.reduce("") { |x,y| x+y+"\n" }
|
final_msg = res.reduce('') { |x, y| x + y + "\n" }
|
||||||
|
|
||||||
room.send_notice(final_msg)
|
room.send_notice(final_msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
module Roller
|
|
||||||
# Solve an arithmatic forumla from a string
|
# Solve an arithmatic forumla from a string
|
||||||
#
|
#
|
||||||
# @param string [String] The string representation of the formula
|
# @param string [String] The string representation of the formula
|
||||||
# @return Integer of the solution
|
# @return Integer of the solution
|
||||||
def self.solve(string)
|
def solve(string)
|
||||||
formatted = string.gsub(/\s+/, '')
|
formatted = string.gsub(/\s+/, '')
|
||||||
formatted = formatted.gsub(/\[[\d,]*\]/) do |a|
|
formatted = formatted.gsub(/\[[\d,]*\]/) do |a|
|
||||||
a.scan(/\d*/).reduce(0) { |x, y| x + y.to_i }
|
a.scan(/\d*/).reduce(0) { |x, y| x + y.to_i }
|
||||||
|
@ -77,7 +89,7 @@ module Chronicle
|
||||||
# @param string [String] The processed request
|
# @param string [String] The processed request
|
||||||
# @param res [String] The result of the process
|
# @param res [String] The result of the process
|
||||||
# @return String re-formatted
|
# @return String re-formatted
|
||||||
def self.pretty(func, orig, string, res)
|
def pretty(func, orig, string, res)
|
||||||
orig.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
orig.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
||||||
string.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
string.gsub!(/[\+\-*\/]/) { |s| " #{s} " }
|
||||||
"#{func.capitalize}: #{orig} (#{string}) ==> #{res}"
|
"#{func.capitalize}: #{orig} (#{string}) ==> #{res}"
|
||||||
|
@ -88,7 +100,7 @@ module Chronicle
|
||||||
# @param string [String] The string representation of the dice roll
|
# @param string [String] The string representation of the dice roll
|
||||||
# example: 2d4+6
|
# example: 2d4+6
|
||||||
# @return Array of the message and the result
|
# @return Array of the message and the result
|
||||||
def self.roll(string)
|
def roll(string)
|
||||||
results = []
|
results = []
|
||||||
string.gsub(/\s+/,'').split(',').each do |roll|
|
string.gsub(/\s+/,'').split(',').each do |roll|
|
||||||
orig = roll
|
orig = roll
|
||||||
|
|
|
@ -1,27 +1,52 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Chronicle
|
module Chronicle
|
||||||
module Matrix
|
module Addon
|
||||||
# Ping - Pong. Useful for testing
|
# Ping - Pong. Useful for testing
|
||||||
|
class Ping
|
||||||
|
def self.register(bot)
|
||||||
|
addon_instance = new(bot)
|
||||||
|
addon_command = ['ping']
|
||||||
|
|
||||||
|
[addon_instance, addon_command]
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(bot)
|
||||||
|
@bot = bot
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle a command from the Matrix protocol
|
||||||
#
|
#
|
||||||
# @param client [Client object] The current Matrix client connection
|
|
||||||
# @param message [Message object] The relevant message object
|
# @param message [Message object] The relevant message object
|
||||||
def handle_ping(client, message)
|
def matrix_command(message)
|
||||||
room = client.ensure_room message.room_id
|
room = @bot.client.ensure_room(message.room_id)
|
||||||
|
|
||||||
room.send_notice('Pong!')
|
room.send_notice('Pong!')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# 8-Ball: Give a random, vague response to a question
|
# 8-Ball: Give a random, vague response to a question
|
||||||
|
class Eightball
|
||||||
|
def self.register(bot)
|
||||||
|
addon_instance = new(bot)
|
||||||
|
addon_command = ['8ball']
|
||||||
|
|
||||||
|
[addon_instance, addon_command]
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(bot)
|
||||||
|
@bot = bot
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle a command from the Matrix protocol
|
||||||
#
|
#
|
||||||
# @param client [Client object] The current Matrix client connection
|
|
||||||
# @param message [Message object] The relevant message object
|
# @param message [Message object] The relevant message object
|
||||||
def handle_8ball(client, message)
|
def matrix_command(message)
|
||||||
msgstr = message.content[:body]
|
msgstr = message.content[:body]
|
||||||
.gsub(/!8ball\s*/, '')
|
.gsub(/!8ball\s*/, '')
|
||||||
.strip
|
.strip
|
||||||
|
|
||||||
room = client.ensure_room(message.room_id)
|
room = @bot.client.ensure_room(message.room_id)
|
||||||
|
|
||||||
fates = [
|
fates = [
|
||||||
'Resoundingly, yes.',
|
'Resoundingly, yes.',
|
||||||
|
@ -54,3 +79,4 @@ module Chronicle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -4,13 +4,13 @@ require 'faraday'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'matrix_sdk'
|
require 'matrix_sdk'
|
||||||
|
|
||||||
# Chronicle Bot
|
|
||||||
module Chronicle
|
|
||||||
# Require any addons
|
# Require any addons
|
||||||
Dir[File.join(__dir__, 'addons', '*.rb')].each do |file|
|
Dir[File.join(__dir__, 'addons', '*.rb')].each do |file|
|
||||||
require file
|
require file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Chronicle Bot
|
||||||
|
module Chronicle
|
||||||
# A filter to simplify syncs
|
# A filter to simplify syncs
|
||||||
BOT_FILTER = {
|
BOT_FILTER = {
|
||||||
presence: { types: [] },
|
presence: { types: [] },
|
||||||
|
@ -30,23 +30,6 @@ module Chronicle
|
||||||
|
|
||||||
# Chronicle Bot for Matrix
|
# Chronicle Bot for Matrix
|
||||||
module Matrix
|
module Matrix
|
||||||
@@default_allowed_commands = %w[ping]
|
|
||||||
@@room_allowed_commands = {}
|
|
||||||
|
|
||||||
# Update allowed commands
|
|
||||||
def add_allowed_commands(cmds, msgid='')
|
|
||||||
if msgid
|
|
||||||
@@room_allowed_commands[msgid].concat(cmds)
|
|
||||||
else
|
|
||||||
@@room_allowed_commands.each { |_,v| v.concat(cmds) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Establish or return allowed commands for a room
|
|
||||||
def allowed_commands(msgid)
|
|
||||||
@@room_allowed_commands[msgid] ||= @@default_allowed_commands
|
|
||||||
end
|
|
||||||
|
|
||||||
# Begin the beast
|
# Begin the beast
|
||||||
def self.start(args)
|
def self.start(args)
|
||||||
unless args.length >= 2
|
unless args.length >= 2
|
||||||
|
@ -65,11 +48,68 @@ module Chronicle
|
||||||
|
|
||||||
# The bot
|
# The bot
|
||||||
class ChronicleBot
|
class ChronicleBot
|
||||||
include Matrix
|
attr_reader :all_commands, :cmd_prefix
|
||||||
|
|
||||||
def initialize(hs_url, access_token)
|
def initialize(hs_url, access_token)
|
||||||
@hs_url = hs_url
|
@hs_url = hs_url
|
||||||
@token = access_token
|
@token = access_token
|
||||||
|
|
||||||
|
@cmd_prefix = '!'
|
||||||
|
@all_commands = {}
|
||||||
|
@allowed_commands = {}
|
||||||
|
|
||||||
|
register_commands
|
||||||
|
end
|
||||||
|
|
||||||
|
# All available commands
|
||||||
|
def available_commands(addon, commands)
|
||||||
|
commands.each do |command|
|
||||||
|
@all_commands[command] = addon
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def client
|
||||||
|
@client ||= MatrixSdk::Client.new(
|
||||||
|
@hs_url,
|
||||||
|
access_token: @token,
|
||||||
|
client_cache: :all
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def deep_copy(hash)
|
||||||
|
Marshal.load(Marshal.dump(hash))
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable_commands(*commands)
|
||||||
|
commands.each do |command|
|
||||||
|
@all_commands.delete(command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_message(message)
|
||||||
|
return unless message.content[:msgtype] == 'm.text'
|
||||||
|
|
||||||
|
msgstr = message.content[:body]
|
||||||
|
roomid = message.room_id
|
||||||
|
cmds = @all_commands.keys.join('|')
|
||||||
|
|
||||||
|
return unless msgstr =~ /^#{@cmd_prefix}#{cmds}\s*/
|
||||||
|
|
||||||
|
msgstr.match(/^#{@cmd_prefix}(#{cmds})\s*/) do |m|
|
||||||
|
@all_commands[m.to_s[1..-1].strip].matrix_command(message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def register_commands
|
||||||
|
Chronicle::Addon.constants.each do |addon|
|
||||||
|
cmd = Object.const_get("Chronicle::Addon::#{addon.to_s}")
|
||||||
|
|
||||||
|
if cmd.methods.include?(:register)
|
||||||
|
instance, commands = cmd.send(:register, self)
|
||||||
|
|
||||||
|
available_commands(instance, commands)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run Chronicle
|
# Run Chronicle
|
||||||
|
@ -95,36 +135,6 @@ module Chronicle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_message(message)
|
|
||||||
return unless message.content[:msgtype] == 'm.text'
|
|
||||||
|
|
||||||
msgstr = message.content[:body]
|
|
||||||
msgid = message.room_id
|
|
||||||
cmds = allowed_commands(msgid).join('|')
|
|
||||||
|
|
||||||
return unless msgstr =~ /^!#{cmds}\s*/
|
|
||||||
|
|
||||||
msgstr.match(/^!(#{cmds})\s*/) do |m|
|
|
||||||
send(
|
|
||||||
"handle_#{m.to_s[1..-1].strip}",
|
|
||||||
client,
|
|
||||||
message
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def client
|
|
||||||
@client ||= MatrixSdk::Client.new(
|
|
||||||
@hs_url,
|
|
||||||
access_token: @token,
|
|
||||||
client_cache: :none
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def deep_copy(hash)
|
|
||||||
Marshal.load(Marshal.dump(hash))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue