Commit Graph

65 Commits

Author SHA1 Message Date
d2a1cb541d Change message routing logic to be an implication instead of AND
Previously, a message wouldn't be admitted if it didn't have a prefix,
(logical) AND if the message was equal to the bot's nickname.

Now, a message with a blank prefix passes through, but if the prefix is
the bot's nickname, it does not.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 22:14:40 -07:00
b72071793b Remove unnecessary kruft
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 22:14:33 -07:00
9fac85cc9a Remove extraneous IO.inspect calls
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 21:43:48 -07:00
109cd67b37 Add reply_chance to markov chains and markov commands
Every time a user sends a message, there is now a chance that markov
will reply with a random message based on what they said. !markov chance
allows lookups and setting of the chance that a user may receive a
message.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 21:39:39 -07:00
e375f1604a Finish up markov with implementation of !markov status
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 20:51:01 -07:00
04a4c740bd Add allchain and implement "all", "emulate" commands for markov plugin
* Markov allchain is generated from all markov chains in the save
  directory for the given channel. This omits starting processes for
  known markov chains.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 20:08:18 -07:00
9dc1033cd2 Add merge/1 and merge/2 to Markov.Chain
merge/1 takes a nonempty list of markov chains to merge

merge/2 takes two markov chains of the same order and sums their weights

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 20:07:02 -07:00
6f625c21ca Add Markov.ChainServer for Markov plugin
* Markov chains each have their own process keeping it updated and
  synchronized. The markov plugin has been upgraded to account for this.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 17:40:22 -07:00
9cfc77d1a4 Squash warning in wordbot re: function parens
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 17:40:14 -07:00
880f363792 Remove (supervisor) opts from Omnibot.Plugin opts, update Plugin.Supervisor to use :one_for_all strategy by default
Plugin opts no longer contains options for the supervisors that watch
plugins, and said supervisors now adopt the one_for_all strategy. This
is because these servers *generally* need one another to stay alive.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 17:37:55 -07:00
e88bd58229 Update markov chains to be backed by maps instead of lists
This should hopefully speed up lookups and stuff like that.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-17 17:33:52 -07:00
bb8ebca0b8 IRC messages are not routed if they are sent by the bot
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-16 18:00:43 -07:00
02470bcf1d Add "ignore" list to wordbot plugin
Wordbot can now ignore users who send messages to the channel.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-16 17:54:34 -07:00
4c93b42fdc Finish markov chain generation impl
* Markov chains will train and generate chains correctly now
* Implement Markov.save_chains/0
* Add a couple more utils that help accomplish the above

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-15 16:25:25 -07:00
c43c075588 Minor changes all around
* Wordbot does not IO.inspect() the winners of the round
* Split Omnibot.Plugin.base_children/1 into base_children_before/1 and
  base_children_after/1 for plugins that come before and after the
  children in the module
* Other minor changes

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-14 19:13:43 -07:00
522c62a55c Finish plugin and routing overhaul, there's a new model in town:
* Plugins all derive from Omnibot.Plugin. There still is a base plugin,
  in case we want to have another plugin backend instead of a GenServer
* All plugins are monitored by a unique Plugin.Supervisor, which is in
  turn started by the PluginSupervisor (yes this is confusing, yes it
  needs to be renamed)
* Any other auxiliary child processes may be started through the
  Plugin.children/1 function.
* By default, plugins have a CfgState process which is an Agent that
  keeps track of the plugin's configuration and state
* Plugin API is now called through the GenServer backend for better
  synchronicity.
* Very few changes to the front-facing Plugin API, which is nice

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-14 15:05:00 -07:00
9679c46e15 WIP: Supervisor-based plugin base
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-12 12:19:14 -07:00
e2a746709d Update Plugin.GenServer to match the same pattern that Plugin.Supervisor does, remove Omnibot.Plugin
* using Plugin.GenServer now uses Plugin.Base so that is not required
* Remove Omnibot.Plugin because all it did was include Plugin.GenServer
  and Plugin.Base

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-11 16:01:57 -07:00
9a8c6f2472 Finish up Plugin.Supervisor, replace markov and wordbot implementations with it
Both markov and wordbot have some auxiliary processes that run to keep
track of things. Previously, they both had custom supervisors grafted on
to the Plugin.Base - now, this grafting is automated with
Plugin.Supervisor.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-11 15:43:07 -07:00
369c9824fb Rename Plugin.Supervisor to PluginSupervisor
This is in preparation to make a bonafide Plugin.Supervisor import.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-09 16:39:24 -07:00
8cddd8e78e Move markov to be a supervisor plugin
This is probably going to be necessary to avoid race conditions in the
ETS storage

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-09 14:51:33 -07:00
010d60f4f9 Actually remove Hooks from Plugin.Base - forgot to add this two commits
ago oopz

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-09 14:50:49 -07:00
9c69ca7b72 Markov chains appear to be training correctly
* Markov chains record words correctly from a single line to the end of
  their line with a couple of exceptions.
* Start working on using ETS for storing markov chains, and saving it as
  a DETS periodically

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-08 17:25:26 -07:00
1a73a62a2c Add train/2 and add_weight/4 implementations to Markov Chain
* train/2 takes a chain and a list of words to train them on
* add_weight/4 takes a chain, a list of words (the key), the word it
  points to, and an optional increment which will increment the value of
  a weight, or insert the weight.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-08 12:59:34 -07:00
dd65d87fef Remove binary_test because it's not actually needed
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-08 12:59:19 -07:00
6d503089e4 Add binary search to Util
For some reason there doesn't appear to be a binary search function in
Elixir's standard library, so this implements that.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-08 11:29:13 -07:00
1105d6c0e1 Remove Plugin.Agent, replace everywhere with Plugin.GenServer
Being able to handle arbitrary messages from other processes is a
generally useful thing to have for fine-grained control of the plugin.
Agents don't provide that, while GenServers do. I've removed all
instances of the Agent and replaced it with the GenServer and everything
appears fine so far.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-06 17:12:35 -07:00
b12a7d76f8 Fix small bug where plugins that don't override on_msg/2 would report errors
Since route_msg expects msg.prefix to be present, every plugin that
calls route_msg when no prefix is specified in the message (e.g. with
PING messages) would cause a crash of the process.

Now, it just calls a no-op function, since all behavior covered by
route_message requires information in the prefix at some point.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-06 17:02:41 -07:00
d1428623a6 Add OnConnect plugin
Use this plugin to run IRC commands upon connecting to the server.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-06 17:01:29 -07:00
a190114a30 Rename module_supervisor.ex -> plugin/supervisor.ex, and PluginSupervisor -> Plugin.Supervisor
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:53:45 -07:00
d73dabef43 Rename lib/contrib/wordbot.ex -> lib/contrib/wordbot/wordbot.ex
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:50:34 -07:00
96c5ed78cf Rename lib/irc.ex -> lib/irc/irc.ex
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:49:48 -07:00
8f112487c1 Update the instance of "module" with "plugin" and "mod" with "plug" where appropriate
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:30:46 -07:00
62a1064e87 Remove a couple of files that were accidentally introduced in the last commit
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:30:34 -07:00
f004b0ed01 Add lib/plugin that was removed in the last commit, whoops
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:23:55 -07:00
4d7073cfcd Rename Module -> Plugin with basic find/replace
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:23:24 -07:00
fcfdb17daa Format and add some comments to the linkbot module
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:14:38 -07:00
e3f30d30c1 Make linkbot title parsing more robust
Linkbot titles now check the "meta" tags for either "og:title" or
"title" attributes. This is usually a more accurate/correct title than
using the "title" tag, but this is checked as a last resort.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:09:09 -07:00
67192f2c5e Fix small bug with wordbot word score choice
The game ID was accidentally being added as a word to the wordlist. This
is no longer the case.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 18:04:13 -07:00
d56c0bf75c Update wordbot leaderboard and scoreboard to use "denotified" nicks
Nicknames that are sent by wordbot for the leaderboard command and the
end-of-game scoreboard are split up by zero-width space characters, to
avoid pinging the users at random times.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 17:23:29 -07:00
9b11c1c44d Remove old TODO
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 16:35:52 -07:00
0c15496579 Implement wordbot leaderboard command
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 16:35:19 -07:00
7f8a886550 Polish off wordbot implementation, add Omnibot.Module.GenServer
Wordbot implementation now uses the new Omnibot.Module.GenServer module,
which uses a GenServer instead of an Agent. This way, the module can
receive messages and makes storage a little easier.

Beyond that, minor changes all around.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-02 16:23:38 -07:00
67ba7a5847 WIP: Wordbot
Wordbot is a little more complex of a bot module and I've been working
on it here.

Other than wordbot module, a few minor tweaks have been added all around
that don't really affect anything.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-07-01 12:04:51 -07:00
871b7771fe Further separate module agents and module impl
Add Omnibot.Module.Agent which implements the basic agent cfg + state
persistence functionality, which is then included in the Omnibot.Module.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 18:46:19 -04:00
7f6a5e8a90 Fix small bug with linkbot where Regex.scan() would return a list of lists, instead of a list of strings
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 18:10:10 -04:00
4b269675d5 Clean up tasks being started by Omnibot.Irc.route_msg/2
Previously, tasks would be started with an auxiliary task that would
time out based on the module's timeout value - i.e. two tasks per module
per message. This was a little silly, so I've migrated to using
Task.Supervisor.async_stream_nolink/4. The only downside is that
module-defined timeout is not available for config, because all function
calls need to have the same timeout. This can probably be fixed by
breaking down the async_stream_nolink() function, but for now setting a
hard 30 second timeout works well enough.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 18:00:31 -04:00
76d96c2fe2 Rename Omnibot.Module -> Omnibot.Module.Base, add Omnibot.Module with agent
Previously, all modules were Agents. This renames the Omnibot.Module to
be the base module, and the new Omnibot.Module uses an Agent by default.

This opens the doors to possibly allowing metamodule supervisors for
modules that may be more complex.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 17:34:06 -04:00
95fc775349 Update main supervisor to only start the IRC connection if IEx is *not* running
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 16:47:44 -04:00
f12bc13e13 Remove test code and add hostname blacklist to Linkbot
Linkbot will now block addresses that attempt to use localhost, *.local,
*.home, *.localdomain, hosts that don't have a dot in them, and IP
addresses. This is to avoid exposing the bot to local addresses on the
host computer.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-14 16:41:40 -04:00