Browse Source

Make a start on documentation

tags/v0.11.0
Chris Smith 5 years ago
parent
commit
25c0b69a92
1 changed files with 500 additions and 0 deletions
  1. 500
    0
      docs/index.adoc

+ 500
- 0
docs/index.adoc View File

@@ -0,0 +1,500 @@
1
+= KtIrc {version}
2
+Chris Smith
3
+:version: 0.10.3
4
+:toc: left
5
+:toc-position: left
6
+:toclevels: 5
7
+
8
+== About KtIrc
9
+
10
+KtIrc is a Kotlin JVM library for connecting to and interacting with IRC servers.
11
+It is still in an early stage of development. Its main features:
12
+
13
+.Built for Kotlin
14
+KtIrc is written in and designed for use in Kotlin; it uses extension methods,
15
+DSLs, sealed classes, and so on, to make it much easier to use than an
16
+equivalent Java library.
17
+
18
+.Coroutine-powered
19
+KtIrc uses co-routines for all of its input/output which lets it deal with
20
+IRC messages in the background while your app does other things, without
21
+the overhead of creating a new thread per IRC client.
22
+
23
+.Modern IRC standards
24
+KtIrc supports many IRCv3 features such as SASL authentication, message IDs,
25
+server timestamps, replies, reactions, account tags, and more. These features
26
+(where server support is available) make it easier to develop bots and
27
+clients, and enhance IRC with new user-facing functionality.
28
+
29
+== Getting started
30
+
31
+=== Installing
32
+
33
+All you need to do to start using KtIrc is add a single dependency.
34
+KtIrc is published to JCenter, making it quick and easy to pull in
35
+to almost any project. The examples below show how to add the JCenter
36
+repository and then the KtIrc dependency; you may already be using
37
+JCenter for other dependencies -- in that case just skip the
38
+repository configuration!
39
+
40
+[TIP]
41
+====
42
+KtIrc adheres to semantic versioning: you can expect to upgrade between
43
+minor versions without problems (e.g. from `0.1.2` to `0.13.7`); major
44
+version changes may include breaking changes such as the removal of
45
+deprecated methods. You should check the changelog before updating to
46
+a new major version.
47
+====
48
+
49
+.Gradle (using Kotlin DSL)
50
+[source,kotlin,subs="attributes"]
51
+----
52
+repositories {
53
+    jcenter()
54
+}
55
+
56
+dependencies {
57
+    implementation("com.dmdirc:ktirc:{version}")
58
+}
59
+----
60
+
61
+.Gradle (using Groovy DSL)
62
+[source,groovy,subs="attributes"]
63
+----
64
+buildscript {
65
+    repositories {
66
+        jcenter()
67
+    }
68
+}
69
+
70
+implementation 'com.dmdirc:ktirc:{version}'
71
+----
72
+
73
+.Maven
74
+[source,xml,subs="attributes"]
75
+----
76
+<repositories>
77
+    <repository>
78
+      <id>jcenter</id>
79
+      <url>https://jcenter.bintray.com</url>
80
+    </repository>
81
+</repositories>
82
+
83
+<dependencies>
84
+    <dependency>
85
+        <groupId>com.dmdirc</groupId>
86
+        <artifactId>ktirc</artifactId>
87
+        <version>{version}</version>
88
+    </dependency>
89
+</dependencies>
90
+----
91
+
92
+=== Creating your first client
93
+
94
+KtIrc provides a DSL ("domain specific language") for configuring a
95
+client that allows you to set the connection details, the user's
96
+details, and configure the behaviour of KtIrc itself. The DSL is
97
+accessed through the `IrcClient` function. For full details of all
98
+supported options, see the <<IrcClient DSL>> reference.
99
+
100
+A basic client will look like this:
101
+
102
+[source,kotlin]
103
+----
104
+val client = IrcClient {
105
+    server {
106
+        host = "my.server.com"
107
+    } 
108
+    profile {
109
+        nickname = "nick"
110
+        username = "username"
111
+        realName = "Hi there"
112
+    }
113
+}
114
+----
115
+
116
+=== Connecting and handling events
117
+
118
+Getting KtIrc to start connecting is as simple as calling the `connect()`
119
+method, but before that we probably want to add an event listener to deal
120
+with incoming messages:
121
+
122
+[source,kotlin]
123
+----
124
+client.onEvent { event -> <1>
125
+    when (event) { <2>
126
+        is ServerReady ->
127
+            client.sendJoin("#ktirc") <3>
128
+        is ServerDisconnected ->
129
+            client.connect()
130
+        is MessageReceived ->
131
+            if (event.message == "!test") <4>
132
+                client.reply(event, "Test successful!") <5>
133
+    }
134
+}
135
+
136
+client.connect() <6>
137
+----
138
+<1> An event listener is registered using the `onEvent` method. It receives
139
+    a single IrcEvent.
140
+<2> A Kotlin `when` statement provides a convenient way to switch on the
141
+    type of event received.
142
+<3> Most common IRC commands have `send` methods defined to quickly and
143
+    safely send the message with the right formatting.
144
+<4> Kotlin smart-casts the event, so you can access the properties specific
145
+    to the matched event class, such as `message`.
146
+<5> The IrcClient class provides useful methods to react and respond to
147
+    events.
148
+<6> The connect() method starts connecting and returns immediately. You'll
149
+    receive events updating you on the progress.
150
+
151
+In this example, we're waiting for three events: `ServerReady`, which occurs
152
+after we have connected and the server has sent us all of the pre-amble
153
+such as its configuration and capabilities; `ServerDisconnected` which
154
+is raised whenever KtIrc gets disconnected from (or fails to connect to) the
155
+IRC server; and `MessageReceived` which occurs, unsuprisingly, whenever a
156
+message is received. KtIrc has many events: for more information, see the
157
+<<Events>> reference.
158
+
159
+[CAUTION]
160
+====
161
+With this code, KtIrc will immediately try to reconnect as soon as it is
162
+disconnected. If the server closes the connection early (due to, for
163
+example, a bad password or the user being banned) this will result in a
164
+huge number of connection attempts in a short time. In real code you should
165
+always delay reconnections -- preferably with a backoff -- to avoid
166
+excessive connection attempts.
167
+====
168
+
169
+You can see that KtIrc provides a number of useful methods for sending
170
+requests to the server, and reacting and responding to events. IRC
171
+commands that KtIrc supports can be invoked using the `send*` methods,
172
+which are documented in the <<Messages>> reference. Other useful methods
173
+such as `reply` can be found in the <<Utility methods>> reference.
174
+
175
+== Reference
176
+
177
+=== IrcClient DSL
178
+
179
+The DSL for creating a new `IrcClient` allows you to set a number of
180
+options relating to how KtIrc connects, what user details it provides,
181
+and how it behaves. The full range of options available in the DSL is
182
+shown below:
183
+
184
+[source,kotlin]
185
+----
186
+server {
187
+    host = "irc.example.com"
188
+    port = 6667
189
+    useTls = true
190
+    password = "H4ckTh3Pl4n3t"
191
+}
192
+
193
+profile {
194
+    nickname = "MyBot"
195
+    username = "bot"
196
+    realName = "Botomatic v1.2"
197
+}
198
+
199
+behaviour {
200
+    requestModesOnJoin = true
201
+    alwaysEchoMessages = true
202
+}
203
+
204
+sasl {
205
+    mechanisms += "PLAIN"
206
+    username = "botaccount"
207
+    password = "s3cur3"
208
+}
209
+----
210
+
211
+==== Server settings
212
+
213
+The server block allows you to specify the details of the IRC server you
214
+wish to connect to:
215
+
216
+ * `host` - the hostname or IP address of the server *(required)*
217
+ * `port` - the port to connect on _(default: 6667)_
218
+ * `useTls` - whether to use a secure connection or not _(default: false)_
219
+ * `password` - the password to provide to the server _(default: null)_
220
+
221
+An alternative more compact syntax is available for configuring server details:
222
+
223
+[source,kotlin]
224
+----
225
+server("irc.example.com", 6667, true, "H4ckTh3Pl4n3t")
226
+----
227
+
228
+You can, if you wish, combine the two or use named parameters:
229
+
230
+[source,kotlin]
231
+----
232
+server(useTls = true, port = 6697) {
233
+    host = "irc.example.com"
234
+    password = "H4ckTh3Pl4n3t"
235
+}
236
+----
237
+
238
+==== User profile
239
+
240
+The user profile controls how KtIrc will present itself to the IRC server, and
241
+how other users on that server will see the KtIrc user:
242
+
243
+ * `nickname` - the initial nickname you wish to use *(required)*
244
+ * `username` - the "username" to provide to the server _(default: KtIrc)_
245
+ * `realName` - the "real name" that will be seen by other clients
246
+   _(default: KtIrc User)_
247
+
248
+[TIP]
249
+====
250
+The "username" is sometimes called the "ident" or "gecos". Some IRC servers
251
+will check for an ident reply from your host and use that in place of the
252
+username provided if it gets a response. The username (or ident reply)
253
+becomes part of your client's hostmask, and is visible to other users. It
254
+is unrelated to nickserv or other account usernames.
255
+====
256
+
257
+As with the <<Server settings>> you can use a more compact syntax:
258
+
259
+[source,kotlin]
260
+----
261
+profile("nickname", "username", "real name")
262
+----
263
+
264
+==== Behaviour
265
+
266
+The behaviour block allows you to tweak how KtIrc itself operates. These
267
+options allow you perform common operations automatically, or enjoy more
268
+advanced IRC features even if the server doesn't support them:
269
+
270
+ * `requestModesOnJoin` - if enabled, automatically requests channel modes
271
+   when the client joins a new channel _(default: false)_
272
+ * `alwaysEchoMessages` - if enabled, every message you send will result
273
+   in a `MessageReceived` event being returned. Servers that support the
274
+   IRCv3 `echo-message` capability will do this automatically; enabling the
275
+   behaviour will make all servers act the same way _(default: false)_
276
+
277
+The behaviour block is optional in its entirety.
278
+
279
+==== SASL configuration
280
+
281
+SASL ("Simple Authentication and Security Layer") is a standard mechanism
282
+for securely authenticating to a service that has recently been adopted
283
+for use in IRC. SASL supports a number of 'mechanisms' that describe how
284
+the data will be exchanged between the client and server. KtIrc supports
285
+the following mechanisms:
286
+
287
+ * `EXTERNAL` - the server uses some external means to authenticate the
288
+   client, instead of a username and password. On most servers this
289
+   means checking the client certificate against one registered with
290
+   the user's account. _(disabled by default)_
291
+ * `PLAIN` - the client sends the username and password in plain text
292
+   during the connection phase. This offers slightly more security
293
+   than calling `nickserv identify` (for example) after connecting.
294
+ * `SCRAM-SHA-1` - this mechanism involves a "salted challenge" being
295
+   completed which results in both the server and the client proving that
296
+   they know the user's password, but without it every being transmitted.
297
+   This is based on the `SHA-1` algorithm which has known issues, but is
298
+   more than sufficient when used in this manner.
299
+ * `SCRAM-SHA-256` - the same as `SCRAM-SHA-1` but using the `SHA-256`
300
+   algorithm instead, which is more modern and secure.
301
+
302
+To use `PLAIN`, `SCRAM-SHA-1` or `SCRAM-SHA-256`, you must supply a username
303
+and password in the configuration:
304
+
305
+[source,kotlin]
306
+----
307
+sasl {
308
+    username = "botaccount"
309
+    password = "s3cur3"
310
+}
311
+----
312
+
313
+KtIrc enables `SCRAM-SHA-256`, `SCRAM-SHA-1` and `PLAIN` by default, and will
314
+use them in that order of preference if the server supports more than one.
315
+You can modify the `mechanisms` parameter if you wish to disable one:
316
+
317
+
318
+[source,kotlin]
319
+----
320
+sasl {
321
+    mechanisms -= "PLAIN"
322
+    username = "botaccount"
323
+    password = "s3cur3"
324
+}
325
+----
326
+
327
+You can also clear all the default mechanisms and provide your own list:
328
+
329
+[source,kotlin]
330
+----
331
+sasl {
332
+    mechanisms("SCRAM-SHA-256", "PLAIN")
333
+    username = "botaccount"
334
+    password = "s3cur3"
335
+}
336
+----
337
+
338
+
339
+If you wish to enable the `EXTERNAL` mechanism, you do not need to provide
340
+a username or password:
341
+
342
+[source,kotlin]
343
+----
344
+sasl {
345
+    mechanisms("EXTERNAL")
346
+}
347
+----
348
+
349
+Alternatively, if you wish to enable `EXTERNAL` but fall back to other
350
+mechanisms if it doesn't work:
351
+
352
+[source,kotlin]
353
+----
354
+sasl {
355
+    mechanisms += "EXTERNAL"
356
+    username = "botaccount"
357
+    password = "s3cur3"
358
+}
359
+----
360
+
361
+The SASL block is optional in its entirety.
362
+
363
+=== State
364
+
365
+KtIrc attempts to track all reasonable state of the IRC network. This includes
366
+details about the server, channels the client is joined to, and users that are
367
+also in those channels. The state is exposed in a several fields accessible
368
+from the `IrcClient`:
369
+
370
+==== ServerState
371
+
372
+The server state provides information about the server, and our connection to
373
+it.
374
+
375
+[IMPORTANT]
376
+====
377
+The server state will be updated frequently while KtIrc is connecting to a
378
+server. The values within it should not be relied upon until a `ServerReady`
379
+event is received, as they may be incomplete or estimates before then.
380
+====
381
+
382
+.serverState.status (ServerStatus)
383
+Provides an enum containing the current server state. One of:
384
+
385
+* `Disconnected` - the server is not connected
386
+* `Connecting` - we are attempting to establish a connection
387
+* `Negotiating` - we are logging in, negotiating capabilities, etc
388
+* `Ready` - we are connected and commands may be sent
389
+
390
+.serverState.localNickname (String)
391
+The current nickname we are using on the IRC server. While connecting this
392
+will default to the nickname from the <<User profile>>, but it may be updated
393
+if e.g. the nick is in use or not allowed.
394
+
395
+.serverState.serverName (String)
396
+The name the server uses for itself. While connecting this defaults to the
397
+hostname given in the <<Server settings>>, but it will be updated to the
398
+value provided by the server. For example, you may connect to
399
+`irc.example.com` and during the negotiation phase KtIrc will see that it
400
+is actually talking to `server3.uk.irc.example.com` and update the
401
+serverName to reflect that.
402
+
403
+[TIP]
404
+====
405
+For a user-friendly identifier most servers provide a `NETWORK` token in
406
+the ISUPPORT reply, which is available via the <<Features>> property.
407
+====
408
+
409
+.serverState.channelModePrefix (ModePrefixMapping)
410
+Provides a mapping from channel user modes (such as "o" for op, "v" for
411
+voice) to the prefixes used before nicknames (such as "@" and "+").
412
+
413
+To map prefixes to modes, you can use the `getMode()` or `getModes()`
414
+functions:
415
+
416
+[source,kotlin]
417
+----
418
+'o' == getMode('@')
419
+"ov" == getModes("@+")
420
+----
421
+
422
+.serverState.channelTypes (String)
423
+Contains the types of channels that are allowed by the server, such as
424
+`\#&amp;` for normal channels ("#") and local channels ("&").
425
+
426
+===== Capabilities
427
+
428
+The IRCv3 specifications introduce the concept of 'capability negotiation'.
429
+This allows the client and server to negotiate and enable new capabilities
430
+that are mutually supported.
431
+
432
+The capabilities state contains the following properties:
433
+
434
+.serverState.capabilities.negotiationState (CapabilitiesNegotiationState)
435
+The current state of negotiating with the server. One of:
436
+
437
+* `AWAITING_LIST` - we have requested a list of capabitilies and are awaiting
438
+  a reply
439
+* `AWAITING_ACK` - we have sent the capabilities we want to enable, and are
440
+  waitin for the server to acknowledge them
441
+* `AUTHENTICATING` - we are attempting to authenticate with SASL
442
+* `FINISHED` - we have completed negotiation
443
+
444
+Where a server does not support IRCv3 capability negotiation, the state will
445
+remain at `AWAITING_LIST`.
446
+
447
+.serverState.capabilities.advertisedCapabilities (Map<String, String>)
448
+Contains a map of capability names to values that the server offered. This
449
+should only be required for advance use cases, such as looking up the 
450
+languages offered by a server when providing the user with a choice of
451
+translations.
452
+
453
+.serverState.capabilities.enabledCapabilities (Map<Capability, String>)
454
+Contains a map of capabilities that KtIrc has successfully negotiated with
455
+the server.
456
+
457
+====== Supported capabilities
458
+
459
+* `sasl` - used to perform SASL authentication during connection
460
+* `message-tags` - allows arbitrary tags on messages
461
+* `server-time` - the server adds a timestamp tag to each incoming message
462
+* `account-tag` - the server adds an account tag to incoming user messages
463
+* `userhost-in-names` - the NAMES reply includes users hosts not just nicknames
464
+* `multi-prefix` - all modes are included in nick prefixes (e.g. `@+nick`)
465
+* `extended-join` - more information is sent when a user joins a channel
466
+* `batch` - allows multi-line responses to be batched together
467
+* `echo-message` - echos the client's own messages back to it
468
+* `draft/labeled-responses` - responses are labeled so the client knows which
469
+  incoming message corresponds to which command it sent
470
+* `account-notify` - the server sends a message when a user's account changes
471
+* `away-notify` - the server sends a message when a user's away state changes
472
+* `chghost` - the server sends a message when a user's host changes
473
+
474
+===== Features
475
+
476
+TODO
477
+
478
+==== UserState
479
+
480
+TODO
481
+
482
+==== ChannelState
483
+
484
+TODO
485
+
486
+=== Events
487
+
488
+TODO
489
+
490
+=== Messages
491
+
492
+TODO
493
+
494
+=== Utility methods
495
+
496
+TODO
497
+
498
+=== IRCv3 support
499
+
500
+TODO

Loading…
Cancel
Save