mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 01:09:22 +01:00
Yet another documentation refresh (#113)
This commit is contained in:
parent
9811df3dfc
commit
11adee9d78
@ -9,7 +9,7 @@
|
||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>inspircd</strong></big></big></font></td
|
||||
><td align=right valign=bottom
|
||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/gl/pylink/protocols/inspircd.py">/home/gl/pylink/protocols/inspircd.py</a></font></td></tr></table>
|
||||
<p></p>
|
||||
<p><tt>inspircd.py: InspIRCd 2.x protocol module for PyLink.</tt></p>
|
||||
<p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#aa55cc">
|
||||
@ -111,8 +111,13 @@ This is used to keep track of whether th
|
||||
internals - a server that fails to reply to our PINGs eventually<br>
|
||||
times out and is disconnected.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_rsquit"><strong>handle_rsquit</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles the RSQUIT command, which is sent by opers to SQUIT remote<br>
|
||||
servers.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_server"><strong>handle_server</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles incoming SERVER commands (introduction of servers).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_svstopic"><strong>handle_svstopic</strong></a> = <a href="#InspIRCdProtocol-handle_ftopic">handle_ftopic</a>(self, numeric, command, args)</dt></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_uid"><strong>handle_uid</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles incoming UID commands (user introduction).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-inviteClient"><strong>inviteClient</strong></a>(self, numeric, target, channel)</dt><dd><tt>Sends an INVITE from a PyLink client..</tt></dd></dl>
|
||||
@ -151,10 +156,15 @@ Example uses:<br>
|
||||
Note: No nick collision / valid nickname checks are done here; it is<br>
|
||||
up to plugins to make sure they don't introduce anything invalid.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-spawnServer"><strong>spawnServer</strong></a>(self, name, sid=None, uplink=None, desc=None)</dt><dd><tt>Spawns a server off a PyLink server. desc (server description)<br>
|
||||
<dl><dt><a name="InspIRCdProtocol-spawnServer"><strong>spawnServer</strong></a>(self, name, sid=None, uplink=None, desc=None, endburst_delay=0)</dt><dd><tt>Spawns a server off a PyLink server. desc (server description)<br>
|
||||
defaults to the one in the config. uplink defaults to the main PyLink<br>
|
||||
server, and sid (the server ID) is automatically generated if not<br>
|
||||
given.</tt></dd></dl>
|
||||
given.<br>
|
||||
<br>
|
||||
If endburst_delay is set greater than zero, the sending of ENDBURST<br>
|
||||
will be delayed by the amount given. This can be used to prevent<br>
|
||||
pseudoserver bursts from triggering IRCd join-flood preventions,<br>
|
||||
and prevent connections from filling up the snomasks too much.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-squitServer"><strong>squitServer</strong></a>(self, source, target, text='No reason given')</dt><dd><tt>SQUITs a PyLink server.</tt></dd></dl>
|
||||
|
||||
@ -213,6 +223,8 @@ be used for multi-word arguments that last un
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-removeClient"><strong>removeClient</strong></a>(self, numeric)</dt><dd><tt>Internal function to remove a client from our internal state.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-updateTS"><strong>updateTS</strong></a>(self, channel, their_ts)</dt></dl>
|
||||
|
||||
<hr>
|
||||
Data descriptors inherited from <a href="classes.html#Protocol">classes.Protocol</a>:<br>
|
||||
<dl><dt><strong>__dict__</strong></dt>
|
||||
@ -290,8 +302,13 @@ This is used to keep track of whether th
|
||||
internals - a server that fails to reply to our PINGs eventually<br>
|
||||
times out and is disconnected.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_rsquit"><strong>handle_rsquit</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles the RSQUIT command, which is sent by opers to SQUIT remote<br>
|
||||
servers.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_server"><strong>handle_server</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles incoming SERVER commands (introduction of servers).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_svstopic"><strong>handle_svstopic</strong></a> = <a href="#InspIRCdProtocol-handle_ftopic">handle_ftopic</a>(self, numeric, command, args)</dt></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-handle_uid"><strong>handle_uid</strong></a>(self, numeric, command, args)</dt><dd><tt>Handles incoming UID commands (user introduction).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-inviteClient"><strong>inviteClient</strong></a>(self, numeric, target, channel)</dt><dd><tt>Sends an INVITE from a PyLink client..</tt></dd></dl>
|
||||
@ -330,10 +347,15 @@ Example uses:<br>
|
||||
Note: No nick collision / valid nickname checks are done here; it is<br>
|
||||
up to plugins to make sure they don't introduce anything invalid.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-spawnServer"><strong>spawnServer</strong></a>(self, name, sid=None, uplink=None, desc=None)</dt><dd><tt>Spawns a server off a PyLink server. desc (server description)<br>
|
||||
<dl><dt><a name="InspIRCdProtocol-spawnServer"><strong>spawnServer</strong></a>(self, name, sid=None, uplink=None, desc=None, endburst_delay=0)</dt><dd><tt>Spawns a server off a PyLink server. desc (server description)<br>
|
||||
defaults to the one in the config. uplink defaults to the main PyLink<br>
|
||||
server, and sid (the server ID) is automatically generated if not<br>
|
||||
given.</tt></dd></dl>
|
||||
given.<br>
|
||||
<br>
|
||||
If endburst_delay is set greater than zero, the sending of ENDBURST<br>
|
||||
will be delayed by the amount given. This can be used to prevent<br>
|
||||
pseudoserver bursts from triggering IRCd join-flood preventions,<br>
|
||||
and prevent connections from filling up the snomasks too much.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-squitServer"><strong>squitServer</strong></a>(self, source, target, text='No reason given')</dt><dd><tt>SQUITs a PyLink server.</tt></dd></dl>
|
||||
|
||||
@ -392,6 +414,8 @@ be used for multi-word arguments that last un
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-removeClient"><strong>removeClient</strong></a>(self, numeric)</dt><dd><tt>Internal function to remove a client from our internal state.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="InspIRCdProtocol-updateTS"><strong>updateTS</strong></a>(self, channel, their_ts)</dt></dl>
|
||||
|
||||
<hr>
|
||||
Data descriptors inherited from <a href="classes.html#Protocol">classes.Protocol</a>:<br>
|
||||
<dl><dt><strong>__dict__</strong></dt>
|
||||
@ -407,6 +431,6 @@ Data descriptors inherited from <a href="classes.html#Protocol">classes.Protocol
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><strong>curdir</strong> = 'protocols'<br>
|
||||
<td width="100%"><strong>curdir</strong> = '../../protocols'<br>
|
||||
<strong>log</strong> = <logging.RootLogger object></td></tr></table>
|
||||
</body></html>
|
@ -1,42 +1,45 @@
|
||||
# PyLink Protocol Module Specification
|
||||
|
||||
In PyLink, each protocol module is a single file consisting of a protocol class, and a global `Class` attribute that is set equal to it (e.g. `Class = InspIRCdProtocol`). These classes should be based off of either [`classes.Protocol`](https://github.com/GLolol/PyLink/blob/0.4.0-dev/classes.py#L404), a boilerplate class that only defines a few variables, or [`ts6_common.TS6BaseProtocol`](https://github.com/GLolol/PyLink/blob/0.4.0-dev/protocols/ts6_common.py#L10), which includes elements of the TS6 protocol that are shared by both the InspIRCd and TS6 protocols. IRC objects initialize protocol modules by creating an instance of its class, and passing it the IRC object itself.
|
||||
In PyLink, each protocol module is a single file consisting of a protocol class, and a global `Class` attribute that is set equal to it (e.g. `Class = InspIRCdProtocol`). These classes should be based off of either [`classes.Protocol`](https://github.com/GLolol/PyLink/blob/e4fb64aebaf542122c70a8f3a49061386a00b0ca/classes.py#L532), a boilerplate class that only defines a few basic things, or [`ts6_common.TS6BaseProtocol`](https://github.com/GLolol/PyLink/blob/0.5.0-dev/protocols/ts6_common.py), which includes elements of the TS6 protocol that are shared by the InspIRCd, UnrealIRCd, and TS6 protocols. IRC objects load protocol modules by creating an instance of its main class, and sends it commands accordingly.
|
||||
|
||||
See also: [inspircd.html](inspircd.html) for an auto-generated specification of the InspIRCd protocol module.
|
||||
See also: [inspircd.html](inspircd.html) for auto-generated documentation the InspIRCd protocol module.
|
||||
|
||||
## Tasks
|
||||
|
||||
Protocol modules have some *very* ***important*** jobs. If any of these aren't done correctly, you will be left with a very **broken, desynced** services server:
|
||||
Protocol modules have some very important jobs. If any of these aren't done correctly, you will be left with a broken, desynced services server:
|
||||
|
||||
1) Handle incoming commands from the uplink IRCd.
|
||||
|
||||
2) Return [hook data](hooks-reference.md) for relevant commands, so that plugins can receive data from IRC.
|
||||
|
||||
3) Make sure channel/user states are kept correctly. Joins, quits, parts, kicks, mode changes, nick changes, etc. **must** be handled accurately.
|
||||
3) Make sure channel/user states are kept correctly. Joins, quits, parts, kicks, mode changes, nick changes, etc. should all be handled accurately.
|
||||
|
||||
4) Respond to both pings *and* pongs - the `irc.lastping` attribute **must** be set to the current time whenever a `PONG` is received from the uplink, so PyLink's internals don't [lag out the uplink thinking it isn't responding to our `PING`s](https://github.com/GLolol/PyLink/blob/0.4.0-dev/classes.py#L202-L204).
|
||||
4) Respond to both pings *and* pongs - the `irc.lastping` attribute **must** be set to the current time whenever a `PONG` is received from the uplink, so PyLink's doesn't [lag out the uplink thinking that it isn't responding to our pings](https://github.com/GLolol/PyLink/blob/e4fb64aebaf542122c70a8f3a49061386a00b0ca/classes.py#L309-L311).
|
||||
|
||||
5) Implement a series of camelCase `commandServer/Client` functions - plugins use these for sending outgoing commands. See the `Outbound commands` section below for a list of which ones are needed.
|
||||
|
||||
6) Set the threaded event `irc.connected` (via `irc.connected.set()`) when the initial connection + burst phase is complete. This is important for plugins like relay that do state checking, and they will fail to work if this is not set.
|
||||
6) Set the threading.Event object `irc.connected` (via `irc.connected.set()`) when the protocol negotiation with the uplink is complete. This is important for plugins like relay which must check that links are ready before spawning clients, and they will fail to work if this is not set.
|
||||
|
||||
## Core functions
|
||||
|
||||
The following functions *must* be implemented by any protocol module within its main class, since they are used by the IRC internals.
|
||||
The following functions *must* be implemented by any protocol module within its main class, since they are used by the IRC object internals.
|
||||
|
||||
- **`connect`**`(self)` - Initializes a connection to a server.
|
||||
|
||||
- **`handle_events`**`(self, line)` - Handles inbound data (lines of text) from the uplink IRC server. Normally, this will pass commands to other command handlers within the protocol module, dropping commands that are unrecognized (wildcard handling), but it's really up to you how to structure your modules. You will want to be able to parse command arguments properly into a list: many protocols send RFC1459-style commands that can be parsed using the [`self.parseArgs(line)` function within the `Protocol` class](https://github.com/GLolol/PyLink/blob/c77d170765d20b0ac55b945fba4a6257fb15cf43/classes.py#L411).
|
||||
- All of the outbound commands mentioned in the next section (minus raw numerics) should have their incoming version handled and [hook data](hooks-reference.md) returned.
|
||||
- **`handle_events`**`(self, line)` - Handles inbound data (lines of text) from the uplink IRC server. Normally, this will pass commands to other command handlers within the protocol module, while dropping commands that are unrecognized (wildcard handling). But, it's really up to you how to structure your modules. You will want to be able to parse command arguments properly into a list: many protocols send RFC1459-style commands that can be parsed using the [`Protocol.parseArgs()`](https://github.com/GLolol/PyLink/blob/e4fb64aebaf542122c70a8f3a49061386a00b0ca/classes.py#L539) function.
|
||||
|
||||
### Outgoing command functions
|
||||
|
||||
- **`spawnClient`**`(self, nick, ident='null', host='null', realhost=None, modes=set(), server=None, ip='0.0.0.0', realname=None, ts=None, opertype=None)` - Spawns a client on the given IRC connection. Note that no nick collision / valid nickname checks are done here, and it is up to plugins to make sure they don't introduce anything invalid.
|
||||
- **`spawnClient`**`(self, nick, ident='null', host='null', realhost=None, modes=set(), server=None, ip='0.0.0.0', realname=None, ts=None, opertype=None, manipulatable=False)` - Spawns a client on the PyLink server. No nick collision / valid nickname checks are done by protocol modules, as it is up to plugins to make sure they don't introduce anything invalid.
|
||||
- `modes` is a set of `(mode char, mode arg)` tuples in the form of [`utils.parseModes()` output](using-utils.md#parseModes).
|
||||
- `ident` and `host` default to "null", while `realhost` defaults to the same things as `host` if not defined.
|
||||
- `realname` defaults to the real name specified in the PyLink config, if not given. `ts` defaults to the current time and `opertype` (the oper type name, if applicable) defaults to the simple text of `IRC Operator`.
|
||||
- `realname` defaults to the real name specified in the PyLink config, if not given.
|
||||
- `ts` defaults to the current time if not given.
|
||||
- `opertype` (the oper type name, if applicable) defaults to the simple text of `IRC Operator`.
|
||||
- The `manipulatable` option toggles whether the client spawned should be considered protected. Currently, all this does is prevent commands from plugins like `bots` from modifying these clients, but future client protections (anti-kill flood, etc.) may also depend on this.
|
||||
- The `server` option optionally takes a SID of any PyLink server, and spawns the client on the one given. It will default to the root PyLink server.
|
||||
|
||||
- **`joinClient`**`(self, client, channel)` - Joins the client UID given to a channel.
|
||||
- **`joinClient`**`(self, client, channel)` - Joins the given client UID given to a channel.
|
||||
|
||||
- **`awayClient`**`(self, source, text)` - Sends an AWAY message from a PyLink client. `text` can be an empty string to unset AWAY status.
|
||||
|
||||
@ -87,9 +90,10 @@ optional, and defaults to the one we've stored in the channel state if not given
|
||||
- **`updateClient`**`(self, source, field, text)` - Updates the ident, host, or realname of a PyLink client. `field` should be either "IDENT", "HOST", "GECOS", or
|
||||
"REALNAME". If changing the field given on the IRCd isn't supported, `NotImplementedError` should be raised.
|
||||
|
||||
## Variables to note
|
||||
## Special variables
|
||||
|
||||
A protocol module should also set the following variables in their protocol class:
|
||||
|
||||
- `self.casemapping`: set this to `rfc1459` (default) or `ascii` to determine which case mapping should be used.
|
||||
- `self.hook_map`: map a list of non-standard command names sent by the IRCd to those more commonly used: examples in the [TS6](https://github.com/GLolol/PyLink/blob/0.4.0-dev/protocols/ts6.py#L19) and [InspIRCd](https://github.com/GLolol/PyLink/blob/0.4.0-dev/protocols/inspircd.py#L24) modules.
|
||||
- `self.casemapping`: set this to `rfc1459` (default) or `ascii` to determine which case mapping the IRCd uses.
|
||||
- `self.hook_map`: this is a `dict`, which maps non-standard command names sent by the IRCd to those that PyLink plugins use internally.
|
||||
- Examples exist in the [UnrealIRCd](https://github.com/GLolol/PyLink/blob/0.5-dev/protocols/unreal.py#L22) and [InspIRCd](https://github.com/GLolol/PyLink/blob/0.5-dev/protocols/inspircd.py#L24) modules.
|
||||
|
@ -1 +1 @@
|
||||
This page is under construction: see [utils.html ](utils.html) for autogenerated documentation for the utils module.
|
||||
See [utils.html](utils.html) for auto-generated documentation for the utils module.
|
||||
|
@ -9,7 +9,10 @@
|
||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>utils</strong></big></big></font></td
|
||||
><td align=right valign=bottom
|
||||
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/gl/pylink/utils.py">/home/gl/pylink/utils.py</a></font></td></tr></table>
|
||||
<p></p>
|
||||
<p><tt>utils.py - PyLink utilities module.<br>
|
||||
<br>
|
||||
This module contains various utility functions related to IRC and/or the PyLink<br>
|
||||
framework.</tt></p>
|
||||
<p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#aa55cc">
|
||||
@ -17,12 +20,14 @@
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="imp.html">imp</a><br>
|
||||
<a href="inspect.html">inspect</a><br>
|
||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="conf.html">conf</a><br>
|
||||
<a href="importlib.html">importlib</a><br>
|
||||
</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
|
||||
<a href="os.html">os</a><br>
|
||||
</td><td width="25%" valign=top><a href="re.html">re</a><br>
|
||||
<a href="string.html">string</a><br>
|
||||
</td><td width="25%" valign=top><a href="world.html">world</a><br>
|
||||
</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
|
||||
</td></tr></table></td></tr></table><p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#ee77aa">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
@ -51,7 +56,8 @@
|
||||
<font color="#000000" face="helvetica, arial"><a name="NotAuthenticatedError">class <strong>NotAuthenticatedError</strong></a>(<a href="builtins.html#Exception">builtins.Exception</a>)</font></td></tr>
|
||||
|
||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
|
||||
<td colspan=2><tt># This is separate from classes.py to prevent import loops.<br> </tt></td></tr>
|
||||
<td colspan=2><tt><a href="builtins.html#Exception">Exception</a> raised by <a href="#-checkAuthenticated">checkAuthenticated</a>() when a user fails authentication<br>
|
||||
requirements.<br> </tt></td></tr>
|
||||
<tr><td> </td>
|
||||
<td width="100%"><dl><dt>Method resolution order:</dt>
|
||||
<dd><a href="utils.html#NotAuthenticatedError">NotAuthenticatedError</a></dd>
|
||||
@ -129,9 +135,9 @@ Example queries:<br>
|
||||
<td width="100%">Methods defined here:<br>
|
||||
<dl><dt><a name="TS6SIDGenerator-__init__"><strong>__init__</strong></a>(self, irc)</dt></dl>
|
||||
|
||||
<dl><dt><a name="TS6SIDGenerator-increment"><strong>increment</strong></a>(self, pos=2)</dt></dl>
|
||||
<dl><dt><a name="TS6SIDGenerator-increment"><strong>increment</strong></a>(self, pos=2)</dt><dd><tt>Increments the SID generator to the next available SID.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="TS6SIDGenerator-next_sid"><strong>next_sid</strong></a>(self)</dt></dl>
|
||||
<dl><dt><a name="TS6SIDGenerator-next_sid"><strong>next_sid</strong></a>(self)</dt><dd><tt>Returns the next unused TS6 SID for the server.</tt></dd></dl>
|
||||
|
||||
<hr>
|
||||
Data descriptors defined here:<br>
|
||||
@ -148,15 +154,15 @@ Data descriptors defined here:<br>
|
||||
<font color="#000000" face="helvetica, arial"><a name="TS6UIDGenerator">class <strong>TS6UIDGenerator</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
|
||||
|
||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
|
||||
<td colspan=2><tt>TS6 UID Generator module, adapted from InspIRCd source<br>
|
||||
<td colspan=2><tt>TS6 UID Generator module, adapted from InspIRCd source:<br>
|
||||
https://github.com/inspircd/inspircd/blob/f449c6b296ab/src/server.cpp#L85-L156<br> </tt></td></tr>
|
||||
<tr><td> </td>
|
||||
<td width="100%">Methods defined here:<br>
|
||||
<dl><dt><a name="TS6UIDGenerator-__init__"><strong>__init__</strong></a>(self, sid)</dt></dl>
|
||||
|
||||
<dl><dt><a name="TS6UIDGenerator-increment"><strong>increment</strong></a>(self, pos=5)</dt></dl>
|
||||
<dl><dt><a name="TS6UIDGenerator-increment"><strong>increment</strong></a>(self, pos=5)</dt><dd><tt>Increments the SID generator to the next available SID.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="TS6UIDGenerator-next_uid"><strong>next_uid</strong></a>(self)</dt></dl>
|
||||
<dl><dt><a name="TS6UIDGenerator-next_uid"><strong>next_uid</strong></a>(self)</dt><dd><tt>Returns the next unused TS6 UID for the server.</tt></dd></dl>
|
||||
|
||||
<hr>
|
||||
Data descriptors defined here:<br>
|
||||
@ -173,17 +179,24 @@ Data descriptors defined here:<br>
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><dl><dt><a name="-add_cmd"><strong>add_cmd</strong></a>(func, name=None)</dt></dl>
|
||||
<dl><dt><a name="-add_hook"><strong>add_hook</strong></a>(func, command)</dt><dd><tt>Add a hook <func> for command <command>.</tt></dd></dl>
|
||||
<td width="100%"><dl><dt><a name="-add_cmd"><strong>add_cmd</strong></a>(func, name=None)</dt><dd><tt>Binds an IRC command function to the given command name.</tt></dd></dl>
|
||||
<dl><dt><a name="-add_hook"><strong>add_hook</strong></a>(func, command)</dt><dd><tt>Binds a hook function to the given command name.</tt></dd></dl>
|
||||
<dl><dt><a name="-applyModes"><strong>applyModes</strong></a>(irc, target, changedmodes)</dt><dd><tt>Takes a list of parsed IRC modes, and applies them on the given target.<br>
|
||||
<br>
|
||||
The target can be either a channel or a user; this is handled automatically.</tt></dd></dl>
|
||||
<dl><dt><a name="-checkAuthenticated"><strong>checkAuthenticated</strong></a>(irc, uid, allowAuthed=True, allowOper=True)</dt><dd><tt>Checks whetherthe given user has operator status on PyLink, raising<br>
|
||||
<dl><dt><a name="-checkAuthenticated"><strong>checkAuthenticated</strong></a>(irc, uid, allowAuthed=True, allowOper=True)</dt><dd><tt>Checks whether the given user has operator status on PyLink, raising<br>
|
||||
<a href="#NotAuthenticatedError">NotAuthenticatedError</a> and logging the access denial if not.</tt></dd></dl>
|
||||
<dl><dt><a name="-clientToServer"><strong>clientToServer</strong></a>(irc, numeric)</dt><dd><tt>Finds the SID of the server a user is on.</tt></dd></dl>
|
||||
<dl><dt><a name="-getHostmask"><strong>getHostmask</strong></a>(irc, user)</dt><dd><tt>Gets the hostmask of the given user, if present.</tt></dd></dl>
|
||||
<dl><dt><a name="-getProtoModule"><strong>getProtoModule</strong></a>(protoname)</dt><dd><tt>Imports and returns the protocol module requested.</tt></dd></dl>
|
||||
<dl><dt><a name="-isChannel"><strong>isChannel</strong></a>(s)</dt><dd><tt>Checks whether the string given is a valid channel name.</tt></dd></dl>
|
||||
<dl><dt><a name="-getDatabaseName"><strong>getDatabaseName</strong></a>(dbname)</dt><dd><tt>Returns a database filename with the given base DB name appropriate for the<br>
|
||||
current PyLink instance.<br>
|
||||
<br>
|
||||
This returns '<dbname>.db' if the running config name is PyLink's default<br>
|
||||
(config.yml), and '<dbname>-<config name>.db' for anything else. For example,<br>
|
||||
if this is called from an instance running as './pylink testing.yml', it<br>
|
||||
would return '<dbname>-testing.db'.</tt></dd></dl>
|
||||
<dl><dt><a name="-getHostmask"><strong>getHostmask</strong></a>(irc, user)</dt><dd><tt>Returns the hostmask of the given user, if present.</tt></dd></dl>
|
||||
<dl><dt><a name="-getProtocolModule"><strong>getProtocolModule</strong></a>(protoname)</dt><dd><tt>Imports and returns the protocol module requested.</tt></dd></dl>
|
||||
<dl><dt><a name="-isChannel"><strong>isChannel</strong></a>(s)</dt><dd><tt>Returns whether the string given is a valid channel name.</tt></dd></dl>
|
||||
<dl><dt><a name="-isHostmask"><strong>isHostmask</strong></a>(text)</dt><dd><tt>Returns whether the given text is a valid hostmask.</tt></dd></dl>
|
||||
<dl><dt><a name="-isInternalClient"><strong>isInternalClient</strong></a>(irc, numeric)</dt><dd><tt>Checks whether the given numeric is a PyLink Client,<br>
|
||||
returning the SID of the server it's on if so.</tt></dd></dl>
|
||||
@ -192,18 +205,18 @@ returning the SID of the server it's on
|
||||
client. Usually, automatically spawned services clients should have this<br>
|
||||
set True to prevent interactions with opers (like mode changes) from<br>
|
||||
causing desyncs.</tt></dd></dl>
|
||||
<dl><dt><a name="-isNick"><strong>isNick</strong></a>(s, nicklen=None)</dt><dd><tt>Checks whether the string given is a valid nick.</tt></dd></dl>
|
||||
<dl><dt><a name="-isNick"><strong>isNick</strong></a>(s, nicklen=None)</dt><dd><tt>Returns whether the string given is a valid nick.</tt></dd></dl>
|
||||
<dl><dt><a name="-isOper"><strong>isOper</strong></a>(irc, uid, allowAuthed=True, allowOper=True)</dt><dd><tt>Returns whether the given user has operator status on PyLink. This can be achieved<br>
|
||||
by either identifying to PyLink as admin (if allowAuthed is True),<br>
|
||||
or having user mode +o set (if allowOper is True). At least one of<br>
|
||||
allowAuthed or allowOper must be True for this to give any meaningful<br>
|
||||
results.</tt></dd></dl>
|
||||
<dl><dt><a name="-isServerName"><strong>isServerName</strong></a>(s)</dt><dd><tt>Checks whether the string given is a server name.</tt></dd></dl>
|
||||
<dl><dt><a name="-isServerName"><strong>isServerName</strong></a>(s)</dt><dd><tt>Returns whether the string given is a valid IRC server name.</tt></dd></dl>
|
||||
<dl><dt><a name="-joinModes"><strong>joinModes</strong></a>(modes)</dt><dd><tt>Takes a list of (mode, arg) tuples in <a href="#-parseModes">parseModes</a>() format, and<br>
|
||||
joins them into a string.<br>
|
||||
<br>
|
||||
See testJoinModes in tests/test_utils.py for some examples.</tt></dd></dl>
|
||||
<dl><dt><a name="-loadModuleFromFolder"><strong>loadModuleFromFolder</strong></a>(name, folder)</dt><dd><tt>Attempts an import of name from a specific folder, returning the resulting module.</tt></dd></dl>
|
||||
<dl><dt><a name="-loadModuleFromFolder"><strong>loadModuleFromFolder</strong></a>(name, folder)</dt><dd><tt>Imports and returns a module, if existing, from a specific folder.</tt></dd></dl>
|
||||
<dl><dt><a name="-nickToUid"><strong>nickToUid</strong></a>(irc, nick)</dt><dd><tt>Returns the UID of a user named nick, if present.</tt></dd></dl>
|
||||
<dl><dt><a name="-parseModes"><strong>parseModes</strong></a>(irc, target, args)</dt><dd><tt>Parses a modestring list into a list of (mode, argument) tuples.<br>
|
||||
['+mitl-o', '3', 'person'] => [('+m', None), ('+i', None), ('+t', None), ('+l', '3'), ('-o', 'person')]</tt></dd></dl>
|
||||
|
@ -1,3 +1,7 @@
|
||||
"""
|
||||
inspircd.py: InspIRCd 2.x protocol module for PyLink.
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
@ -1,3 +1,7 @@
|
||||
"""
|
||||
ts6.py: PyLink protocol module for TS6-based IRCds (charybdis, elemental-ircd).
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
@ -1,8 +1,14 @@
|
||||
"""
|
||||
ts6_common.py: Common base protocol class with functions shared by the UnrealIRCd, InspIRCd, and TS6 protocol modules.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Import hacks to access utils and classes...
|
||||
curdir = os.path.dirname(__file__)
|
||||
sys.path += [curdir, os.path.dirname(curdir)]
|
||||
|
||||
import utils
|
||||
from log import log
|
||||
from classes import *
|
||||
|
@ -1,3 +1,7 @@
|
||||
"""
|
||||
unreal.py: UnrealIRCd 4.0 protocol module for PyLink.
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
@ -5,8 +9,10 @@ import codecs
|
||||
import socket
|
||||
import re
|
||||
|
||||
# Import hacks to access utils and classes...
|
||||
curdir = os.path.dirname(__file__)
|
||||
sys.path += [curdir, os.path.dirname(curdir)]
|
||||
|
||||
import utils
|
||||
from log import log
|
||||
from classes import *
|
||||
|
38
utils.py
38
utils.py
@ -16,10 +16,15 @@ import world
|
||||
import conf
|
||||
|
||||
class NotAuthenticatedError(Exception):
|
||||
"""
|
||||
Exception raised by checkAuthenticated() when a user fails authentication
|
||||
requirements.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TS6UIDGenerator():
|
||||
"""TS6 UID Generator module, adapted from InspIRCd source
|
||||
"""
|
||||
TS6 UID Generator module, adapted from InspIRCd source:
|
||||
https://github.com/inspircd/inspircd/blob/f449c6b296ab/src/server.cpp#L85-L156
|
||||
"""
|
||||
|
||||
@ -32,6 +37,9 @@ class TS6UIDGenerator():
|
||||
self.sid = sid
|
||||
|
||||
def increment(self, pos=5):
|
||||
"""
|
||||
Increments the SID generator to the next available SID.
|
||||
"""
|
||||
# If we're at the last character in the list of allowed ones, reset
|
||||
# and increment the next level above.
|
||||
if self.uidchars[pos] == self.allowedchars[-1]:
|
||||
@ -44,6 +52,9 @@ class TS6UIDGenerator():
|
||||
self.uidchars[pos] = self.allowedchars[idx+1]
|
||||
|
||||
def next_uid(self):
|
||||
"""
|
||||
Returns the next unused TS6 UID for the server.
|
||||
"""
|
||||
uid = self.sid + ''.join(self.uidchars)
|
||||
self.increment()
|
||||
return uid
|
||||
@ -71,13 +82,18 @@ class TS6SIDGenerator():
|
||||
self.query = query = list(irc.serverdata["sidrange"])
|
||||
except KeyError:
|
||||
raise RuntimeError('(%s) "sidrange" is missing from your server configuration block!' % irc.name)
|
||||
|
||||
self.iters = self.query.copy()
|
||||
self.output = self.query.copy()
|
||||
self.allowedchars = {}
|
||||
qlen = len(query)
|
||||
|
||||
assert qlen == 3, 'Incorrect length for a SID (must be 3, got %s)' % qlen
|
||||
assert '#' in query, "Must be at least one wildcard (#) in query"
|
||||
|
||||
for idx, char in enumerate(query):
|
||||
# Iterate over each character in the query string we got, along
|
||||
# with its index in the string.
|
||||
assert char in (string.digits+string.ascii_uppercase+"#"), \
|
||||
"Invalid character %r found." % char
|
||||
if char == '#':
|
||||
@ -91,6 +107,9 @@ class TS6SIDGenerator():
|
||||
|
||||
|
||||
def increment(self, pos=2):
|
||||
"""
|
||||
Increments the SID generator to the next available SID.
|
||||
"""
|
||||
if pos < 0:
|
||||
# Oh no, we've wrapped back to the start!
|
||||
raise RuntimeError('No more available SIDs!')
|
||||
@ -106,7 +125,11 @@ class TS6SIDGenerator():
|
||||
self.increment(pos-1)
|
||||
|
||||
def next_sid(self):
|
||||
"""
|
||||
Returns the next unused TS6 SID for the server.
|
||||
"""
|
||||
while ''.join(self.output) in self.irc.servers:
|
||||
# Increment until the SID we have doesn't already exist.
|
||||
self.increment()
|
||||
sid = ''.join(self.output)
|
||||
return sid
|
||||
@ -474,7 +497,7 @@ def isOper(irc, uid, allowAuthed=True, allowOper=True):
|
||||
|
||||
def checkAuthenticated(irc, uid, allowAuthed=True, allowOper=True):
|
||||
"""
|
||||
Checks whetherthe given user has operator status on PyLink, raising
|
||||
Checks whether the given user has operator status on PyLink, raising
|
||||
NotAuthenticatedError and logging the access denial if not.
|
||||
"""
|
||||
lastfunc = inspect.stack()[1][3]
|
||||
@ -494,7 +517,7 @@ def isManipulatableClient(irc, uid):
|
||||
return isInternalClient(irc, uid) and irc.users[uid].manipulatable
|
||||
|
||||
def getHostmask(irc, user):
|
||||
"""Gets the hostmask of the given user, if present."""
|
||||
"""Returns the hostmask of the given user, if present."""
|
||||
userobj = irc.users.get(user)
|
||||
if userobj is None:
|
||||
return '<user object not found>'
|
||||
@ -513,14 +536,17 @@ def getHostmask(irc, user):
|
||||
return '%s!%s@%s' % (nick, ident, host)
|
||||
|
||||
def loadModuleFromFolder(name, folder):
|
||||
"""Attempts and returns an import of the given module name from a specific
|
||||
folder."""
|
||||
"""
|
||||
Imports and returns a module, if existing, from a specific folder.
|
||||
"""
|
||||
fullpath = os.path.join(folder, '%s.py' % name)
|
||||
m = importlib.machinery.SourceFileLoader(name, fullpath).load_module()
|
||||
return m
|
||||
|
||||
def getProtocolModule(protoname):
|
||||
"""Imports and returns the protocol module requested."""
|
||||
"""
|
||||
Imports and returns the protocol module requested.
|
||||
"""
|
||||
return loadModuleFromFolder(protoname, world.protocols_folder)
|
||||
|
||||
def getDatabaseName(dbname):
|
||||
|
Loading…
Reference in New Issue
Block a user