Finish migration to using a module to control core behavior

Previously, core behavior was handled in the Omnibot.Router module.
However, since the module system is robust enough, this work has been
delegated to the Omnibot.Core module.

Additionally, the Omnibot.State module has been augmented to keep track
of the modules that have been currently loaded, and methods that are
used to get the list of loaded modules and routing information for those
modules are coming from Omnibot.State as well (as opposed to
Omnibot.Config). This is to avoid requiring the Omnibot.Core module be
included in the config, plus avoiding modification of the runtime config
after it has already been loaded.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-06-13 18:01:40 -04:00
parent 304a8d4164
commit 4d27e30b88
5 changed files with 49 additions and 28 deletions

43
lib/core.ex Normal file
View File

@@ -0,0 +1,43 @@
defmodule Omnibot.Core do
use Omnibot.Module
alias Omnibot.State
def on_join(irc, channel, nick) do
cfg = State.cfg()
if nick == cfg.nick do
State.add_channel(channel)
# Sync if we join a channel we shouldn't be in
if !Enum.member?(State.all_channels(), channel),
do: Irc.sync_channels(irc)
end
end
def on_part(irc, channel, nick) do
cfg = State.cfg()
if nick == cfg.nick do
State.remove_channel(channel)
# Sync if we join a channel we forcibly part a channel we shouldn't leave
if Enum.member?(State.all_channels(), channel),
do: Irc.sync_channels(irc)
end
end
def on_kick(irc, channel, _nick, target) do
cfg = State.cfg()
if target == cfg.nick do
State.remove_channel(channel)
# Generally, being kicked is not intentionally leaving a channel, so always sync here
Irc.sync_channels(irc)
end
end
@impl true
def on_msg(irc, msg) do
case String.upcase(msg.command) do
"001" -> Irc.sync_channels(irc)
"PING" -> Irc.send_msg(irc, "PONG", msg.params)
_ -> route_msg(irc, msg)
end
end
end

View File

@@ -1,11 +0,0 @@
defmodule Omnibot.Core.Join do
use Omnibot.Module
alias Omnibot.State
def on_join(channel, nick) do
cfg = State.cfg()
if nick == cfg.nick do
State.add_channel(channel)
end
end
end

View File

@@ -1,11 +0,0 @@
defmodule Omnibot.Core.Welcome do
use Omnibot.Module
require Logger
@impl true
def on_msg(irc, _) do
Logger.info("Syncing channels")
Irc.sync_channels(irc)
end
end

View File

@@ -14,11 +14,13 @@ defmodule Omnibot.ModuleSupervisor do
compile_files(cfg.module_paths || []) compile_files(cfg.module_paths || [])
# These are modules that need to be loaded for core functionality of the bot # These are modules that need to be loaded for core functionality of the bot
#{Omnibot.Core.Welcome, cfg: [channels: :all]}, core = [
#{Omnibot.Core.Join, cfg: [channels: :all]}, {Omnibot.Core, cfg: [channels: :all]},
]
# Map the modules in the configuration to the children # Map the modules in the configuration to the children
children = children =
core ++
for mod <- cfg.modules do for mod <- cfg.modules do
case mod do case mod do
{name, cfg} -> {name, cfg: cfg, name: name} {name, cfg} -> {name, cfg: cfg, name: name}
@@ -27,7 +29,7 @@ defmodule Omnibot.ModuleSupervisor do
end end
# Add each child to the "loaded modules" list in the State # Add each child to the "loaded modules" list in the State
Enum.each(children, fn module -> State.add_loaded_module(module) end) Enum.each(IO.inspect(children), fn {module, opts} -> State.add_loaded_module({module, opts[:cfg]}) end)
Supervisor.init(children, strategy: :one_for_one) Supervisor.init(children, strategy: :one_for_one)
end end

View File

@@ -3,9 +3,7 @@ defmodule Omnibot.Router do
alias Omnibot.{Irc.Msg, State} alias Omnibot.{Irc.Msg, State}
def route(irc, msg) do def route(irc, msg) do
#channel = Msg.channel(msg) channel = Msg.channel(msg)
channel = IO.inspect(Msg.channel(msg))
IO.inspect(State.channel_modules(channel))
State.channel_modules(channel) State.channel_modules(channel)
|> Enum.each(fn {module, _} -> module.on_msg(irc, msg) end) |> Enum.each(fn {module, _} -> module.on_msg(irc, msg) end)
end end