This is your plugin to the outside world, usually the only thing publicly visible in the entire module. It only serves as a way of proxying calls to our top-level private functions, as well as to house plugin-specific and -private variables that we want to keep out of top-level scope for the sake of modularity. If the only state is in the plugin, several plugins of the same kind can technically be run alongside each other, which would allow for several bots to be run in parallel. This is not yet supported but there's fundamentally nothing stopping it.
Given a filename, read the contents and load it into a RehashingAA!(long[string]) associative array, then returns it. If there was no file there to read, return an empty array for a fresh start.
Catch a NAMES reply and record each person as having been seen.
When someone changes nickname, update their entry in the array.
When someone quits, update their entry with the current timestamp iff they already have an entry.
Whenever a user does something, record this user as having been seen at the current time.
Catches each user listed in a WHO reply and updates their entries in the seen users list, creating them if they don't exist.
After we have registered on the server and seen the welcome messages, load our seen users from file. Additionally set up a fiber that periodically saves seen users to disk once every timeBetweenSaves seconds.
Reloads seen users from disk.
Save the passed seen users associative array to disk, in JSON format.
Performs self-tests against another bot.
When closing the program or when crashing with grace, save the seen users array to disk for later reloading.
Update all currently observed users.
Update a given nickname's entry in the seen array with the passed time, expressed in UNIX time.
The ChannelPolicy annotation dictates whether or not an annotated function should be called based on the *channel* the event took place in, if applicable.
UserAwareness is a mixin template; it proxies to a few functions defined in kameloso.plugins.common.awareness to deal with common book-keeping that every plugin *that wants to keep track of users* need. If you don't want to track which users you have seen (and are visible to you now), you don't need this.
Complementary to UserAwareness is ChannelAwareness, which will add in book-keeping about the channels the bot is in, their topics, modes, and list of participants. Channel awareness requires user awareness, but not the other way around.
Mixes in a module constructor that registers this module's plugin to be instantiated as part of the program running.
We want our plugin to be *configurable* with a section for itself in the configuration file. For this purpose we create a "Settings" struct housing our configurable bits, which we already made an instance of in SeenPlugin.
Flag denoting that UserAwareness
has been mixed in.
Proxies to onUserAwarenessQuit.
Proxies to onUserAwarenessNick.
Proxies to onUserAwarenessCatchTarget.
Proxies to onUserAwarenessCatchSender.
Proxies to onUserAwarenessNamesReply.
Proxies to onUserAwarenessEndOfList.
Flag denoting that ChannelAwareness has been mixed in.
Proxies to onChannelAwarenessSelfjoin.
Proxies to onChannelAwarenessSelfpart.
Proxies to onChannelAwarenessJoin.
Proxies to onChannelAwarenessPart.
Proxies to onChannelAwarenessNick.
Proxies to onChannelAwarenessQuit.
Proxies to onChannelAwarenessTopic.
Proxies to onChannelAwarenessCreationTime.
Proxies to onChannelAwarenessMode.
Proxies to onChannelAwarenessWhoReply.
Proxies to onChannelAwarenessNamesReply.
Proxies to onChannelAwarenessModeLists.
Proxies to onChannelAwarenessChannelModeIs.
The Seen plugin implements "seen"; the ability for someone to query when a given nickname was last encountered online.
We will implement this by keeping an internal long[string] associative array of timestamps keyed by nickname. Whenever we see a user do something, we will update his or her timestamp to the current time. We'll save this array to disk when closing the program and read it from file when starting it, as well as saving occasionally once every few minutes.
We will rely on the ChanQueryService to query channels for full lists of users upon joining new ones, including the ones we join upon connecting. Elsewise, a completely silent user will never be recorded as having been seen, as they would never be triggering any of the functions we define to listen to. (There's a setting to ignore non-chatty events, as we'll see later.)
kameloso does primarily not use callbacks, but instead annotates functions with UDAs of IRC event *types*. When an event is incoming it will trigger the function(s) annotated with its type.
Callback delegates and Fibers *are* supported, however. Event handlers can be annotated to be called from with in a fiber, and other fibers and delegates can be manually registered to process on incoming events, alternatively scheduled to a point in time with a reasonably high degree of precision.