-
Notifications
You must be signed in to change notification settings - Fork 15
API Python Events
This is part of the documentation of Verlihub's Python Plugin version 1.2.4.
A Python script can react to events happening in the hub and change their outcome. It is possible by the use of so-called hooks — top-level functions declared in the script that have names recognized by the Python plugin. All of them are called OnSomething (except one), where Something describes the type of event. For example, if a user enters the hub, the hub will ask the plugins to process the OnUserLogin
event. When some user issues a command, it will trigger the OnUserCommand
event.
Generally (exceptions will be discussed later), if a hook function returns nothing (None) or one (1), the hub will continue processing the event normally. However, if any of the scripts returns zero (0), it will be a sign to Verlihub to stop processing the event and abort the operation (if it can be blocked).
It is important to note that returning zero only blocks the handling of the event by other plugins and Verlihub itself. It will not block other Python scripts (or plugins that were called before Python) from noticing the event. All Python scripts are guaranteed to receive the event in the order that they appear in the output of the !pylist
command.
OnUserCommand
is a good example to show first. In the code below we implement our own version of the +myip
command. If the command name matches, the script prints a main-chat message to the user with his IP and then returns zero to block further processing (because we don't want the user to see the IP information the hub normally prints when it receives this command). If the user writes a different command, the tested condition is not satisfied and the function returns the default value, None, which allows that command to be processed by other plugins and the hub.
import vh
def OnUserCommand(nick, command):
if command[1:] == "myip":
vh.usermc("Your IP is: %s" % vh.GetUserIP(nick), nick)
return 0
Here return 0
blocks further processing by the hub. Had we wanted to exit the function without blocking the event, we would have written return
without arguments (which returns the special value None).
When writing your own hook functions, make sure they can take in the expected number of required arguments. You can add optional arguments with specified default values if you wish, but if your definition cannot take all arguments from the caller or expects more, the function call will fail and an error will be reported in the logs. Look at OnUserCommand
for example. It requires two arguments (nick and command). Let's see which definitions will be good and which will fail (function bodies not included):
def OnUserCommand(a, b): # OK
def OnUserCommand(a, b, c=1): # OK
def OnUserCommand(a="", b="", c=1): # OK
def OnUserCommand(a, b="", c=1, d=2): # OK
def OnUserCommand(a, b, **c): # OK
def OnUserCommand(a): # WRONG: expects fewer arguments
def OnUserCommand(a, b, c): # WRONG: expects more arguments
Also note that in the functions that contained parsed NMDC messages, the trailing pipe character is removed.
OnTimer
, UnLoad
, and OnUnLoad
are three events that serve special purposes, instead of reporting that some user has performed some action, like all other events. They also ignore the return values. Other special events are OnScriptCommand
and OnScriptQuery
, because they were introduced to facilitate cooperation between scripts by the use of message passing. OnSetConfig
can also be considered special — it's a way to tell plugins that a configuration variable is going to be changed and giving them the chance to prevent that.
Call: OnTimer(timestamp)
Arguments: timestamp
(float; seconds since the epoch).
OnTimer
is called by the hub roughly every second or every few seconds. The interval between the calls to OnTimer
is specified in seconds by the timer_serv_period
configuration variable, with default value being one second. The argument timestamp
is the time in seconds that passed since the epoch (1970-01-01 00:00:00 UTC).
History: Originally OnTimer
was called without arguments. Then, on 2015-09-27, in late version 1.2.0, the timestamp
argument (int, showing milliseconds since the epoch) was added, breaking existing scripts and flooding hub logs with error messages about wrong number of arguments. If that wasn't bad enough, timestamp
value was wrong on 32-bit systems, because the hub used only a 4-byte integer to store it (that made the value will go from −2147483648 to +2147483647 and then wrap around). Finally, on 2016-02-14, in version 1.2.4 this was fixed: timestamp
is now a double-precision float showing the number of seconds since the epoch (with millisecond resolution), and you can also use the old OnTimer
without arguments (first, the plugin will try to use OnTimer(timestamp)
, and if that fails, it will subsequently use OnTimer()
).
If you want to achieve maximum backwards compatibility, it is wise to specify a default value for the timestamp
argument (because it didn't exist before September 27, 2015) and not use it, but instead get the timestamp from Python's time module. This is the preferred way to handle the OnTimer
event:
import vh, time
def OnTimer(tstamp=0):
now = time.time()
... do something ...
If you want to know how much time has passed since the last call to OnTimer
, that code becomes:
import vh, time
now = then = 0
def OnTimer(tstamp=0):
global now, then
now = time.time()
info = "Time since last call: %s seconds" % (now - then)
... do something ...
then = now
Call: UnLoad()
UnLoad is called before the script is removed from the plugin (by using the !pyunload
or !pyreload
commands, unloading the plugin, or closing the hub). Use it when you have to do some cleanup tasks before the script ends, for example: close network sockets, save configuration files, write statistics to the database, or say farewell to the users. It is also the right moment to remove a bot that was added previously by the script.
The following example is a complete script that adds a bot when it is loaded and removes the bot when it is unloaded. Thanks to the declaration and use of the script_online
variable, you can even activate and deactivate the script without having to reload it (adding the necessary OnOperatorCommand function to do that is left to you).
import vh
script_online = False
def UnLoad():
global script_online
if script_online:
script_online = False
vh.DelRobot("SuperBOT")
def OnUnLoad(error_code):
if not error_code:
UnLoad()
def Init():
global script_online
if not script_online:
vh.AddRobot("SuperBOT", 3, "I am a bot", "DSL", "[email protected]", 0)
script_online = True
Init()
Call: OnUnLoad(error_code)
Arguments: error_code
(int).
Added in late version 1.2.0 on 2015-09-27.
This function is called when the hub is shutting down (for example using the QUIT or SEGV signals, or commands like !restart
or !quit
). The error_code
is normally zero, except the situation when the hub received a SEGV signal. Note that terminating the hub with the TERM and, obviously, KILL signals will not generate the OnUnLoad
event.
After receiving this event you should perform necessary cleanup, but preferably only when error_code
is zero, because you cannot trust the state of memory after a memory violation (SEGV signal). The UnLoad
function is not called on hub termination, so you can put the cleanup code there and call UnLoad
from OnUnLoad
. Look at the example script in the description of UnLoad
.
Call: OnScriptCommand(command, data, plugin, script)
Arguments: command
(str), data
(str), plugin
(str), script
(str).
Added in version 1.2.3.
This event is generated when a script calls the ScriptCommand(command, data)
callback function. Before it is sent to all the plugins, another two arguments are added: plugin
— the name of the plugin where the caller script runs, for example "python" or "lua", and script
— the full path to the caller script, for example "/home/mario/myhub/scripts/test.py". Return value is ignored; you cannot block further processing of this event.
Note that all plugins and all scripts receive the event, including the caller, so you should compare script
against your vh.path
.
Let's say that you have a script that blocks certain online users. You would like it to broadcast to other scripts that it has added someone to the blacklist and you would also like to give other scripts the ability to add nicks to the blacklist. You could do it like this:
import vh
blacklist = set()
def block(nick):
if vh.GetUserClass(nick) not in [0, 1, 2]:
return 0
if nick in blacklist:
return 2
blacklist.add(nick)
vh.ScriptCommand("blacklist_addition", nick)
return 1
def OnScriptCommand(cmd, data, plug, script):
if cmd == "add_to_blacklist":
block(data)
def OnOperatorCommand(op, cmd):
if cmd[1:10] == "blockuser":
nick = cmd[11:]
res = block(nick)
if res == 1:
vh.usermc("Added user %s to the blacklist" % nick, op)
if res == 2:
vh.usermc("User %s was already on the blacklist" % nick, op)
else:
vh.usermc("Could not add user %s to the blacklist" % nick, op)
return 0
Call: OnScriptQuery(command, data, plugin, script)
Arguments: command
(str), data
(str), plugin
(str), script
(str).
Added in version 1.2.4.
This function is seemingly similar to OnScriptCommand, but has two differences: it is generated by a call to ScriptQuery
and you may return a string — it will be passed back to the script that called ScriptQuery
. Using the example of the blacklist described earlier with OnScriptCommand
, that makes life easier for the person who writes the script that interfaces with the blacklist script, because he can get immediate confirmation if the request was successful. For that purpose you would add the following function to the blacklist script:
def OnScriptQuery(cmd, data, plug, script):
if cmd == "add_to_blacklist":
return str(block(data))
The difference is that we now return a stringified result of the call to block(data)
. The script that called ScriptQuery
will receive that string in the list that ScriptQuery
returns and will be able to handle that response appropriately. That would be harder to do with ScriptCommand
(caller would have to define a handler for the "blacklist_addition" script command and check if it registered the nick when the "add_to_blacklist" ScriptCommand
he gave returns).
Call: OnSetConfig(nick, conf, var, val_new, val_old, val_type)
Arguments: nick
(str), conf
(str), var
(str), val_new
(str), val_old
(str), val_type
(int).
Added in version 1.2.4.
This event is triggered when a configuration variable var
in file conf
is about to be changed from val_old
to val_new
by an operator (then nick
stores his name) or by a plugin (then nick == vh.botname
). You can block this configuration change by returning 0.
val_type
is the type of value the variable is represented inside the hub. Since version 1.2.5 you can compare val_type
against the available types stored as vh module constants:
vh.eIT_VOID (unspecified), vh.eIT_BOOL, vh.eIT_CHAR, vh.eIT_INT, vh.eIT_UINT (unsigned int), vh.eIT_LONG, vh.eIT_ULONG, vh.eIT_PCHAR (cstring), vh.eIT_TIMET, vh.eIT_LLONG (64-bit int), vh.eIT_ULLONG, vh.eIT_AR_BYTE (array of bytes), vh.eIT_STRING (std::string), vh.eIT_DOUBLE.
Call: OnUserCommand(nick, command)
Arguments: nick
(str), command
(str).
This function is called when a user identified by nick
writes a user command. If you recognize the command and handle it, you should return zero to block processing of this command by other plugins and the hub, which would end in the message "Unknown hub command" displayed to the user. However, if you only want to add to the output of an existing command or are writing a script that writes a log of all issued commands, you do not want to block further processing, so in that case do not return zero.
Command start with a special control character. It's good practice to ignore it and check if the string following that character is "something" rather than check if the whole command starts with "+something". You should not assume that +
is the magical trigger. Therefore in the following example we check the substring command[1:]
against "myip"
instead of checking command
against "+myip"
:
import vh
def OnUserCommand(nick, command):
# Here we return 0, because we want to block the built-in +myip command.
if command[1:] == "myip":
vh.usermc("Your IP is: %s" % vh.GetUserIP(nick), nick)
return 0
# And here we pass all commands trough, registering them for specific users.
if nick in ["Mario", "Luigi"]:
vh.classmc("%s wrote command: %s" % (nick, command), 5, 10)
return
Like it was said above, user commands are usually recognized by the prefix character +
, but hub administrators can set other trigger characters with the config variable cmd_start_user
. In the past it was only +
, but in recent Verlihub builds it defaults to +!/
— these are the same characters as for operator commands. That creates a problem, because it changes behavior. In the old days, when an operator wrote a command starting with +
, an OnUserCommand event was fired. Now, using default settings, the OnOperatorCommand event is triggered instead. It would make sense that any command issued by an operator is an OperatorCommand, but unfortunately that depends on hub settings. Scripts running on plugin version 1.2.4 and higher can use OnHubCommand
to handle all commands in one place, like this:
import vh
def OnHubCommand(nick, command, uclass, in_pm, prefix):
write = vh.pm if in_pm else vh.usermc
if command == "info":
if uclass > 2:
write(get_all_hub_secrets(), nick)
else:
write(get_only_public_info(), nick)
return 0
if command == "myip":
write("Your IP is: %s" % vh.GetUserIP(nick), nick)
return 0
Scripts running on older plugin versions can instead use this command routing idea:
import vh
def OnOperatorCommand(nick, command):
# Handle all privileged stuff reserved for operators:
if command[1:] == "info":
vh.usermc(get_all_hub_secrets(), nick)
return 0
def OnUserCommand(nick, command):
# First handle all commands common to operators and normal users:
if command[1:] == "myip":
vh.usermc("Your IP is: %s" % vh.GetUserIP(nick), nick)
return 0
if vh.GetUserClass(nick) > 2:
return OnOperatorCommand(nick, command)
# Now handle only commands for normal users:
if command[1:] == "info":
vh.usermc(get_only_public_info(), nick)
return 0
Call: OnUserCommand(nick, command)
Arguments: nick
(str), command
(str).
This function is called when an operator (user with class 3 or above) identified by nick
writes a command that starts with a trigger character listed in the config variable cmd_start_op
(and if the trigger isn't listed there, an OnUserCommand
event will be sent instead). Other than that, this command works exactly like OnUserCommand
.
Call: OnHubCommand(nick, clean_command, user_class, in_pm, prefix)
Arguments: nick
(str), clean_command
(str), user_class
(int), in_pm
(int; 0 or 1), prefix
(str; one character).
Added in version 1.2.4.
OnHubCommand
is called after OnOperatorCommand
or OnUserCommand
, so it can be blocked if any script returns 0 in those event handlers. What are the benefits of using OnHubCommand
instead of the two other commands? Here they are:
- Those two events are combined into one and you only have to check the
user_class
argument to get the class of the user; -
clean_command
has the first character removed, so you do not have to skip over it or bother deciding if it's+
or!
; - and if for some reason you need to know the trigger character (like when you show the user how to use the command and are wondering: start it with
+
or!
...), it is stored in theprefix
argument; -
in_pm
gives you context information, so you know if to respond usingvh.pm
(whenin_pm
equals 1) orvh.usermc
(whenin_pm
equals 0); - it's more versatile — it gives you class number instead of dividing into op commands and everything else;
- and it's more maintainable — you don't have to keep around two event handlers.
Example use:
import vh
def OnHubCommand(nick, command, uclass, in_pm, prefix):
write = vh.pm if in_pm else vh.usermc
if command == "myip":
write("Your IP is: %s" % vh.GetUserIP(nick), nick)
return 0
if uclass > 2:
if command[:5] == "close":
user = command[6:]
if vh.GetUserClass(nick) < uclass:
vh.CloseConnection(nick)
write("User %s dropped." % user, nick)
else:
write("Cannot drop %s." % user, nick)
return 0
if command == "help close":
info = "%sclose <nick> --- " % prefix
info += "Disconnects a user of a class lower than yours."
write(info, nick)
return 0
Call: OnParsedMsgChat(nick, msg)
Arguments: nick
(str), msg
(str).
Return: 0 — block; (nick, message) — substitute the message; 1 or None — continue processing.
This event is triggered when user nick
writes a message msg
in main chat. As usual, you can block the message by returning zero from this function, but additionally you can change it's contents (or the nick) by returning a tuple with two strings: new nick and new message — other scripts and plugins processing OnParsedMsgChat
, and eventually the hub, will receive and process the altered message.
Here is an example utilizing both blocking and substitution:
import vh, string, re
leet_users = []
leet_repl = string.maketrans(\
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", \
"@8cd3fgh1jk1mn0pqr5+uvwxy2@8cd3fgh1jk1mn0pqR5+Uvwxy2")
def leet(s):
return s.translate(leet_repl)
re_banned = re.compile(r"\b(dat ass|bromance|petextrian)\b", re.I)
def OnParsedMsgChat(nick, msg):
if nick in leet_users:
return nick, leet(data)
if re_banned.search(data):
vh.usermc("Message blocked. Learn to speak normally.", nick)
return 0
Call: OnParsedMsgPM(nick, msg, to_nick)
Arguments: nick
(str), msg
(str), to_nick
(str).
User nick
was about to send the private message msg
to user to_nick
. You can block the message by returning zero.
Call: OnParsedMsgMCTo(nick, msg, to_nick)
Arguments: nick
(str), msg
(str), to_nick
(str).
User nick
was about to send the private mainchat message msg
to user to_nick
. You can block the message by returning zero.
Call: OnOpChatMessage(nick, msg)
Arguments: nick
(str), msg
(str).
Function is called when an operator identified by nick
tries to send a message msg
to operator chat (vh.opchatname). You can block the message by returning zero.
Call: OnPublicBotMessage(nick, msg, min_class, max_class)
Arguments: nick
(str), msg
(str), min_class
(int), max_class
(int).
Barely ever used, so it's irrelevant.
Call: OnOperatorKicks(op, nick, reason)
Arguments: op
(str), nick
(str), reason
(str).
This function is called when an operator op
kicks the user nick
, providing a specified reason
. You can block the kick by returning zero from this function.
Call: OnOperatorDrops(op, nick)
Arguments: op
(str), nick
(str).
This function is called when an operator op
drops a user nick
using the !drop
command. To prevent the user from being dropped return zero, for example:
import vh
def OnOperatorDrops(op, nick):
if nick == 'Mario':
vh.usermc("%s is under my protection!" % nick, op)
return 0
Call: OnOperatorDropsWithReason(op, nick, reason)
Arguments: op
(str), nick
(str), reason
(str).
Added in version 1.2.2
Since February 2016 an operator can send a message to the user he drops using the command !drop nick reason
and plugins also receive the reason
string. To prevent older Python scripts from breaking, OnOperatorDrops
was preserved in the original form, with two arguments, but a new event handler was added instead, OnOperatorDropsWithReason
, with the extra third argument, reason
. When an operator drops someone (using either !drop nick
or !drop nick reason
), both functions will always be called — first the old one, then the new one. If the operator drops without giving a reason, reason
will be an empty string.
Replace OnOperatorDrops
with OnOperatorDropsWithReason
in your scripts, if you care about why someone was dropped and have checked that the Python plugin's version is at least 1.2.2. If not, you can keep using OnOperatorDrops
like before.
Call: OnNewBan(op, ip, nick, reason)
Arguments: op
(str), ip
(str), nick
(str), reason
(str).
This event is triggered when an operator op
is trying to ban user nick
with goven ip
, providing a specified reason
. You can prevent the ban by returning zero.
Call: OnNewConn(ip)
Arguments: ip
(str).
This function is called at the first stage of the client's connection process. The client will be disconnected if you return zero.
import vh
banned_ips = set()
def OnNewConn(ip):
if ip in banned_ips:
vh.classmc("Blocked incoming connection from %s" % ip, 3, 10)
return 0
Call: OnCloseConn(ip)
Arguments: ip
(str).
This function is called when a client's connection to the hub is closed.
Call: OnCloseConnEx(ip, close_reason, nick)
Arguments: ip
(str), close_reason
(int), nick
(str).
Added in version 1.2.4.
Can be used instead of OnCloseConn
because it gives more valuable information by including the reason why the connection was closed (close_reason
) and user's nick
. If the connection was closed before login, nick
will be an empty string. The close_reason
is an integer that can be compared against the following vh module constants to get the actual reason for closing the connection:
vh.eCR_DEFAULT # means not closed or unknown reason
vh.eCR_INVALID_USER # bad nick, banned nick, ip or whatever
vh.eCR_KICKED # user was kicked
vh.eCR_FORCEMOVE # operator redirect command
vh.eCR_QUIT # user quits himself
vh.eCR_HUB_LOAD # critical hub load, no new users accepted
vh.eCR_TIMEOUT # some kind of timeout
vh.eCR_TO_ANYACTION # user did nothing for too long time
vh.eCR_USERLIMIT # user limit exceeded for this user
vh.eCR_SHARE_LIMIT # min or max share limit
vh.eCR_TAG_NONE # no tags in description, or badly parsed
vh.eCR_TAG_INVALID # tags not validated, slots, hubs etc.
vh.eCR_PASSWORD # wrong password
vh.eCR_LOGIN_ERR # error in login sequence
vh.eCR_SYNTAX # syntax error in some message
vh.eCR_INVALID_KEY # lock2key is invalid
vh.eCR_RECONNECT # too fast reconnect
vh.eCR_CLONE # clone detected
vh.eCR_SELF # same user connects twice
vh.eCR_BADNICK # bad nick, already used, too short etc.
vh.eCR_NOREDIR # do not redirect, special reason
For example, you could log failed authentication like this:
import vh
def OnCloseConnEx(ip, reason, nick):
if reason == vh.eCR_PASSWORD:
vh.SendToOpChat("Failed login attempt as %s from %s" % (nick, ip))
Call: OnUserLogin(nick)
Arguments: nick
(str).
This function is called when the user initiates the connection, successfully validates his nick and receives hub and user info. It has nothing to do with being a registered user — the event is triggered by any kind of user. If you return zero, the user will be disconnected.
import vh
def OnUserLogin(nick):
vh.mc("Welcome, %s!" % nick)
return
Call: OnUserLogout(nick)
Arguments: nick
(str).
This function is called after a user disconnects. Naturally, you cannot block that event.
Call: OnNewReg(op, nick, uclass)
Arguments: op
(str), nick
(str), uclass
(int).
Called when operator op
is registering user nick
with class uclass
. If you return zero, the registration process will be aborted.
Call: OnValidateTag(nick, data)
Arguments: nick
(str), data
(str).
You can use it to reject a user with a bad tag (to do that return zero). data
holds the tag itself, for example: "<++ V:0.761,M:A,H:16/0/1,S:17>"
.
Call: OnParsedMsgValidateNick(data)
Arguments: data
(str).
When the client connects to the hub it will try to verify that it can use a nick by sending a message data
which looks like: "$ValidateNick Mario"
. The hub sends OnParsedMsgValidateNick event to the plugins and this is your chance to reject a nick that is inappropriate — if you return zero from this function, the client will be disconnected.
Call: OnParsedMsgSearch(nick, data)
Arguments: nick
(str), data
(str).
Event triggered when user nick
tries to perform search. data
is something like: "$Search ip:port F?T?0?9?TTH:hash"
(replace ip, port, and hash with actual values). You can block this search by returning zero.
Call: OnParsedMsgSR(nick, data)
Arguments: nick
(str), data
(str).
Function called when nick
sends a search result data
to user other_nick
. data
has the form: "$SR nick path_and_bytes free/slotsTTH:tth (ip:port)other_nick"
. Note that the hub receives this message only when other_nick
is passive (and then you can block is by returning zero from this event handler). Active users receive search results directly from other people.
Call: OnParsedMsgMyINFO(nick, desc, tag, speed, mail, sharesize)
Arguments: nick
(str), desc
(str), tag
(str), speed
(str), mail
(str), sharesize
(str).
Return: 0 — block; tuple — substitute the MyINFO; 1 or None — continue processing.
Function is called when user nick
sends a MyINFO message. The message has been split into chunks for easier handling. You can block the user from changing his MyINFO by returning zero. You also have a possibility to alter his MyINFO by returning a tuple with five elements: (desc, tag, speed, mail, sharesize). Those elements are strings that will replace parts of MyINFO. If any of the five elements has the value None, that part of MyINFO will remain unchanged.
Call: OnFirstMyINFO(nick, desc, tag, speed, mail, sharesize)
Arguments: nick
(str), desc
(str), tag
(str), speed
(str), mail
(str), sharesize
(str).
Return: 0 — disconnect user; tuple — substitute the MyINFO; 1 or None — continue processing.
This is called when user nick
sends MyINFO for the first time. It works exactly like OnParsedMsgMyINFO
, except that when you return zero the user will be kicked from the hub.
Call: OnParsedMsgAny(nick, data)
Arguments: nick
(str), data
(str).
This function is called for every message coming from a client if the nick is known (so not at the initial connecting stage, but for everything else).
Call: OnParsedMsgAnyEx(ip, data)
Arguments: ip
(str), data
(str).
This function is called for every message coming from a client at the initial stage, when the nick isn't yet known.
Call: OnCtmToHub(nick, ip, port, server_port, referrer)
Arguments: nick
(str), ip
(str), port
(int), server_port
(int), referrer
(str).
No idea what it does; never seen it being used.
Call: OnParsedMsgSupports(ip, data, filtered)
Arguments: ip
(str), data
(str), filtered
(str).
Changed in version 1.2.1 on 2015-12-01. Before that, it was called OnParsedMsgSupport
, did not have the third argument and was useless, because it did not store the IP address in the first argument.
Supports message is used to negotiate protocol extensions by indicating what extended features a DC client possesses. The first argument is the ip
of the connected client, data
is the original supports string sent by that client, which may look like this: "$Supports BotINFO ChatOnly NoGetINFO NoHello"
, and filtered
is the list of supported features (without the $Supports
string) that has been filtered but the hub and other plugins, so it could look for example like this: "HubINFO NoGetINFO NoHello "
.
Call: OnParsedMsgMyHubURL(nick, data)
Arguments: nick
(str), data
(str).
No idea what this is exactly. It's probably sent only by the pingers to let the hub know how they reached it. data
is something like this: "$MyHubURL dchub://example.com:1234".
Call: OnParsedMsgExtJSON(nick, data)
Arguments: nick
(str), data
(str).
No idea what this is and haven't seen anyone use it.
Call: OnParsedMsgBotINFO(nick, data)
Arguments: nick
(str), data
(str).
Sent by pingers. data
is something like: "$BotINFO The Super Pinger, www.example.com"
.
Call: OnParsedMsgVersion(ip, data)
Arguments: ip
(str), data
(str).
The NMDC protocol version sent during handshake. Currently data
is: "$Version 1,0091"
.
Call: OnParsedMsgMyPass(nick, data)
Arguments: nick
(str), data
(str).
Sent when user nick
tries to log in. data
is something like: "$MyPass password"
. You can use this function to register login attempts and detect attacks. Returning zero will instantly close the connection to the user.
Call: OnParsedMsgConnectToMe(nick, other_nick, ip, port)
Arguments: nick
(str), other_nick
(str), ip
(str), port
(str).
Sent by user nick
when he wants user other_nick
to connect to him on given port
and ip
. Returning zero blocks the message.
Call: OnParsedMsgRevConnectToMe(nick, other_nick)
Arguments: nick
(str), other_nick
(str).
Sent by a passive user nick
when he wants to connect with user other_nick
. If other_nick
is active and willing, he will respond with a OnParsedMsgConnectToMe message. Returning zero blocks the message.
Call: OnUnknownMsg(nick, data)
Arguments: nick
(str), data
(str).
Every message that isn't part of NMDC protocol. Otherwise OnParsedMsgAny
would have been used instead.
Copyright © 2006-2024 Verlihub Team
Verlihub menu
- Verlihub Repository
- Wiki Home
- Installation
- Setup and Deployment
- Configuration
- Users
- Connections
- Messages
- Kicks and Bans
- Redirects
- Command List
- Variable List
- How-to
- FAQ's
- Utilities
Verlihub scripts