If you send a message that says:
"!command foo bar "
(note the ending space) - the parameters given back to the plugin would
be:
["foo", "bar "]
which is kind of strange in this instance. Therefore, ending whitespace
is trimmed for parameters and trailing parameters.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Only a handful of locations are shared with the docker-compose file,
instead of the entire directory, to prevent build files from being
overwritten by root.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
If you want all modules to act on all channels, you can simply set
`channels: :all` on all modules, and add `channels: ["#channel",
"#channel", ...]` to the same configuration level as `plugins`. These
are added to the "all channels" list and joined automatically.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
The core module keeps track of the last message received. If the last
message received was more than X seconds ago (configurable), it will
send a ping. If the last message was received more than Y seconds ago
(again, configurable) then reset the connection.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Core module now pings the server and attempts to reconnect if a
respective pong has not been received in a certain amount of time.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This new callback gets called immediately upon connecting to the server.
It is automatically implemented as a no-op by default.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This allows getting a specific key from the configuration instead of
getting the full array. Allows for using this:
cfg(:some_config)
instead of this:
cfg()[:some_config]
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
More things need to be added to Omnibot.Core's state, so it's been
expanded to a map to allow for that.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Omnibot.State shouldn't be used anywhere anymore except as a GenServer
being started up in the supervisor.
Also, configuration must be loaded through Config.load/1 rather than
being constructed, because everything expects a tuple of {plugin,
config} now.
Finally, Omnibot.Core must be added to the configuration in order for
basic functionality.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Deprecating Omnibot.State:
Config.all_channels/1 has the same logic as this, and is better
documented anyway.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
There's probably a better way to make this less expensive, but I'm not
sure what it is. Until then, we'll leave this feature out.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
We're getting rid of the State hack module, because each IRC connection
should hold onto its own config.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Markov.Chain.add_weight/4 would return a fresh new markov chain,
instead of using all of the previous values of the chain that was
being modified. This would result in resetting the reply_chance value
to the default of 0.01.
* Add tests to make sure this doesn't happen to add_weights in the
future.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Previously, messages were only routed from IRC if they were *not* for
the current user. This should only be happening for privmsg messages,
since a plugin is generally aware of what it's sending out.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
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>
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>
* 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>
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>
* 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>
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>
* 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>
* 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>
* 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>
* 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>