diff options
Diffstat (limited to 'doc/en/weechat_relay_protocol.en.adoc')
-rw-r--r-- | doc/en/weechat_relay_protocol.en.adoc | 1780 |
1 files changed, 1780 insertions, 0 deletions
diff --git a/doc/en/weechat_relay_protocol.en.adoc b/doc/en/weechat_relay_protocol.en.adoc new file mode 100644 index 000000000..7db6bbf80 --- /dev/null +++ b/doc/en/weechat_relay_protocol.en.adoc @@ -0,0 +1,1780 @@ += WeeChat Relay protocol +:author: Sébastien Helleu +:email: flashcode@flashtux.org +:lang: en +:toc: left +:toclevels: 3 +:sectnums: +:docinfo1: + + +[[introduction]] +== Introduction + +This document is the specification of WeeChat Relay protocol: the protocol used +to relay WeeChat data to clients, which are mostly remote interfaces. + +[[terminology]] +=== Terminology + +The following terms are used in this document: + +* _relay_: this is the WeeChat with relay plugin, which acts as "server" and + allows _clients_ to connect +* _client_: this is another software, connected to _relay_ via a network + connection; in most cases, this _client_ is a remote interface. + +[[network_diagram]] +=== Network diagram + +The _clients_ are connected to _relay_ like shown in this diagram: + +.... + ┌──────────┐ Workstation + ┌────────┐ ┌───┤ client 1 │ (Linux, Windows, + │ irc │◄──┐ ╔═══════════╤═══════╗ │ └──────────┘ BSD, Mac OS X ...) + └────────┘ └──╢ │ ║◄───┘ ┌──────────┐ + ...... ║ WeeChat │ Relay ║◄───────┤ client 2 │ Mobile device + ┌────────┐ ┌──╢ │ ║◄───┐ └──────────┘ (Android, iPhone ...) + │ jabber │◄──┘ ╚═══════════╧═══════╝ │ ...... + └────────┘ │ ┌──────────┐ + ...... └───┤ client N │ Other devices + └──────────┘ + + +└────────────┘ └───────────────────┘╘══════╛└────────────────────────────────┘ +network servers ncurses interface relay remote interfaces + protocol +.... + +[NOTE] +All clients here are clients using _weechat_ protocol in _relay_ plugin. The +_relay_ plugin also allows IRC clients, then _relay_ plugin acts as an +_IRC proxy_ (not described in this document). + +[[protocol_generalities]] +== Protocol generalities + +* Connections from _client_ to _relay_ are made using TCP sockets on IP/port + used by _relay_ plugin to listen to new connections. +* Number of _clients_ is limited by the option _relay.network.max_clients_. +* Each _client_ is independent from other clients. +* Messages from _client_ to _relay_ are called _commands_, they are sent as text + (a string). +* Messages from _relay_ to _client_ are called _messages_, they are sent as + binary data. + +[[commands]] +== Commands (client → relay) + +Commands have format: "(id) command arguments\n". + +Fields are: + +* _id_: optional message identifier that will be sent in answer from _relay_; + it must be enclosed in parentheses, and must not start with an underscore + ("_") (ids starting with underscore are reserved for WeeChat _event_ messages) +* _command_: a command (see table below) +* _arguments_: optional arguments for command (many arguments are separated by + spaces). + +List of available commands (detail in next chapters): + +[width="80%",cols="^3m,14",options="header"] +|=== +| Command | Description +| init | Initialize connection with _relay_ +| hdata | Request a _hdata_ +| info | Request an _info_ +| infolist | Request an _infolist_ +| nicklist | Request a _nicklist_ +| input | Send data to a buffer (text or command) +| sync | Synchronize buffer(s) (get updates for buffer(s)) +| desync | Desynchronize buffer(s) (stop updates for buffer(s)) +| quit | Disconnect from _relay_ +|=== + +[[command_init]] +=== init + +Initialize connection with _relay_. This must be first command sent to _relay_. +If not sent, _relay_ will close connection on first command received, without +warning. + +Syntax: + +---- +init [<option>=<value>,[<option>=<value>,...]] +---- + +Arguments: + +* _option_: one of following options: +** _password_: password used to authenticate on _relay_ (option + _relay.network.password_ in WeeChat) +** _compression_: compression type: +*** _zlib_: enable _zlib_ compression for messages sent by _relay_ +*** _off_: disable compression + +[NOTE] +Compression _zlib_ is enabled by default if _relay_ supports _zlib_ compression. + +Examples: + +---- +# initialize and use zlib compression by default (if WeeChat supports it) +init password=mypass + +# initialize and disable compression +init password=mypass,compression=off +---- + +[[command_hdata]] +=== hdata + +Request a _hdata_. + +Syntax: + +---- +(id) hdata <path> [<keys>] +---- + +Arguments: + +* _path_: path to a hdata, with format: "hdata:pointer/var/var/.../var", the + last var is the hdata returned: +** _hdata_: name of hdata +** _pointer_: pointer ("0x12345") or list name (for example: "gui_buffers") + (count allowed, see below) +** _var_: a variable name in parent hdata (previous name in path) + (count allowed, see below) +* _keys_: comma-separated list of keys to return in hdata (if not specified, all + keys are returned, which is not recommended on large hdata structures) + +A count is allowed after pointer and variables, with format "(N)". Possible +values are: + +* positive number: iterate using next element, N times +* negative number: iterate using previous element, N times +* _*_: iterate using next element, until end of list + +Examples: + +---- +# request all buffers, hdata of type "buffer" is returned +# keys "number" and "name" are returned for each buffer +hdata buffer:gui_buffers(*) number,name + +# request all lines of all buffers, hdata of type "line_data" is returned +# all keys are returned +hdata buffer:gui_buffers(*)/lines/first_line(*)/data + +# request full name of first buffer +hdata buffer:gui_buffers full_name +---- + +[[command_info]] +=== info + +Request an _info_. + +Syntax: + +---- +(id) info <name> +---- + +Arguments: + +* _name_: name of info to retrieve + +Example: + +---- +info version +---- + +[[command_infolist]] +=== infolist + +Request an _infolist_. + +[IMPORTANT] +Content of infolist is a duplication of actual data. Wherever possible, use +command <<command_hdata,hdata>>, which is direct access to data (it is +faster, uses less memory and returns smaller objects in message). + +Syntax: + +---- +(id) infolist <name> [<pointer> [<arguments>]] +---- + +Arguments: + +* _name_: name of infolist to retrieve +* _pointer_: pointer (optional) +* _arguments_: arguments (optional) + +Example: + +---- +infolist buffer +---- + +[[command_nicklist]] +=== nicklist + +Request a _nicklist_, for one or all buffers. + +Syntax: + +---- +(id) nicklist [<buffer>] +---- + +Arguments: + +* _buffer_: pointer (_0x12345_) or full name of buffer (for example: + _core.weechat_ or _irc.freenode.#weechat_) + +Examples: + +---- +# request nicklist for all buffers +nicklist + +# request nicklist for irc.freenode.#weechat +nicklist irc.freenode.#weechat +---- + +[[command_input]] +=== input + +Send data to a buffer. + +Syntax: + +---- +input <buffer> <data> +---- + +Arguments: + +* _buffer_: pointer (_0x12345_) or full name of buffer (for example: + _core.weechat_ or _irc.freenode.#weechat_) +* _data_: data to send to buffer: if beginning by `/`, this will be executed as + a command on buffer, otherwise text is sent as input of buffer + +Examples: + +---- +input core.weechat /help filter +input irc.freenode.#weechat hello! +---- + +[[command_sync]] +=== sync + +_Updated in version 0.4.1._ + +Synchronize one or more buffers, to get updates. + +[IMPORTANT] +It is recommended to send this command immediately after you asked +data for buffers (lines, ...). It can be send in same message (after a new +line char: "\n"). + +Syntax: + +---- +sync [<buffer>[,<buffer>...] <option>[,<option>...]] +---- + +Arguments: + +* _buffer_: pointer (_0x12345_) or full name of buffer (for example: + _core.weechat_ or _irc.freenode.#weechat_); name "*" can be used to + specify all buffers +* _options_: one of following keywords, separated by commas (default is + _buffers,upgrade,buffer,nicklist_ for "*" and _buffer,nicklist_ for a buffer): +** _buffers_: receive signals about buffers (opened/closed, moved, renamed, + merged/unmerged, hidden/unhidden); this can be used only with name "*" + _(WeeChat ≥ 0.4.1)_ +** _upgrade_: receive signals about WeeChat upgrade (upgrade, upgrade ended); + this can be used only with name "*" + _(WeeChat ≥ 0.4.1)_ +** _buffer_: receive signals about buffer (new lines, type changed, title + changed, local variable added/removed, and same signals as _buffers_ for the + buffer) _(updated in version 0.4.1)_ +** _nicklist_: receive nicklist after changes + +Examples: + +---- +# synchronize all buffers with nicklist +# (the 3 commands are equivalent, but the first one is recommended +# for compatibility with future versions) +sync +sync * +sync * buffers,upgrade,buffer,nicklist + +# synchronize core buffer +sync core.buffer + +# synchronize #weechat channel, without nicklist +sync irc.freenode.#weechat buffer + +# get general signals + all signals for #weechat channel +sync * buffers,upgrade +sync irc.freenode.#weechat +---- + +[[command_desync]] +=== desync + +_Updated in version 0.4.1._ + +Desynchronize one or more buffers, to stop updates. + +[NOTE] +This will remove _options_ for buffers. If some options are still active for +buffers, the client will still receive updates for these buffers. + +Syntax: + +---- +desync [<buffer>[,<buffer>...] <option>[,<option>...]] +---- + +Arguments: + +* _buffer_: pointer (_0x12345_) or full name of buffer (for example: + _core.weechat_ or _irc.freenode.#weechat_); name "*" can be used to + specify all buffers +* _options_: one of following keywords, separated by commas (default is + _buffers,upgrade,buffer,nicklist_ for "*" and _buffer,nicklist_ for a buffer); + see <<command_sync,command sync>> for values + +[NOTE] +When using buffer "*", the other buffers synchronized (using a name) are kept. + +So if you send: "sync *", then "sync irc.freenode.#weechat", then "desync *", +the updates on #weechat channel will still be sent by WeeChat (you must remove +it explicitly to stop updates). + +Examples: + +---- +# desynchronize all buffers +# (the 3 commands are equivalent, but the first one is recommended +# for compatibility with future versions) +desync +desync * +desync * buffers,upgrade,buffer,nicklist + +# desynchronize nicklist for #weechat channel (keep buffer updates) +desync irc.freenode.#weechat nicklist + +# desynchronize #weechat channel +desync irc.freenode.#weechat +---- + +[[command_test]] +=== test + +Test command: WeeChat will reply with various different objects. + +This command is useful to test the decoding of binary objects returned by +WeeChat. + +[IMPORTANT] +You must not use the pointer values returned by this command, they are not +valid. This command must be used only to test decoding of a message sent by +WeeChat. + +Syntax: + +---- +test +---- + +Example: + +---- +test +---- + +Returned objects (in this order): + +[width="80%",cols="^3,3m,5m",options="header"] +|=== +| Type | Type (in message) | Value +| char | chr | 65 ("A") +| integer | int | 123456 +| integer | int | -123456 +| long | lon | 1234567890 +| long | lon | -1234567890 +| string | str | "a string" +| string | str | "" +| string | str | NULL +| buffer | buf | "buffer" +| buffer | buf | NULL +| pointer | ptr | 0x1234abcd +| pointer | ptr | NULL +| time | tim | 1321993456 +| array of strings | arr str | [ "abc", "de" ] +| array of integers | arr int | [ 123, 456, 789 ] +|=== + +[[command_ping]] +=== ping + +_WeeChat ≥ 0.4.2._ + +Send a ping to WeeChat which will reply with a message "_pong" and same arguments. + +This command is useful to test that connection with WeeChat is still alive and +measure the response time. + +Syntax: + +---- +ping [<arguments>] +---- + +Example: + +---- +ping 1370802127000 +---- + +[[command_quit]] +=== quit + +Disconnect from _relay_. + +Syntax: + +---- +quit +---- + +Example: + +---- +quit +---- + +[[messages]] +== Messages (relay → client) + +Messages are sent as binary data, using following format (with size in bytes): + +.... +┌────────╥─────────────╥────╥────────┬──────────╥───────╥────────┬──────────┐ +│ length ║ compression ║ id ║ type 1 │ object 1 ║ ... ║ type N │ object N │ +└────────╨─────────────╨────╨────────┴──────────╨───────╨────────┴──────────┘ + └──────┘ └───────────┘ └──┘ └──────┘ └────────┘ └──────┘ └────────┘ + 4 1 ?? 3 ?? 3 ?? + └────────────────────┘ └──────────────────────────────────────────────────┘ + header (5) compressed data (??) + └─────────────────────────────────────────────────────────────────────────┘ + _length_ bytes +.... + +* _length_ (unsigned integer): number of bytes of whole message (including + this field) +* _compression_ (byte): flag: +** _0x00_: following data is not compressed +** _0x01_: following data is compressed with _zlib_ +* _id_ (string): identifier sent by client (before command name); it can be + empty (string with zero length and no content) if no identifier was given in + command +* _type_ (3 chars): a type: 3 letters (see table below) +* _object_: an object (see table below) + +[[message_compression]] +=== Compression + +If flag _compression_ is equal to 0x01, then *all* data after is compressed +with _zlib_, and therefore must be uncompressed before being processed. + +[[message_identifier]] +=== Identifier + +There are two types of identifiers (_id_): + +* _id_ sent by _client_: _relay_ will answer with same _id_ in its answer +* _id_ of an event: on some events, _relay_ will send message to _client_ using + a specific _id_, beginning with underscore (see table below) + +WeeChat reserved identifiers: + +[width="100%",cols="5,5,3,4,7",options="header"] +|=== +| Identifier | Received with _sync_ | Data sent | + Description | Recommended action in client + +| _buffer_opened | buffers / buffer | hdata: buffer | + Buffer opened | Open buffer + +| _buffer_type_changed | buffers / buffer | hdata: buffer | + Type of buffer changed | Change type of buffer + +| _buffer_moved | buffers / buffer | hdata: buffer | + Buffer moved | Move buffer + +| _buffer_merged | buffers / buffer | hdata: buffer | + Buffer merged | Merge buffer + +| _buffer_unmerged | buffers / buffer | hdata: buffer | + Buffer unmerged | Unmerge buffer + +| _buffer_hidden | buffers / buffer | hdata: buffer | + Buffer hidden | Hide buffer + +| _buffer_unhidden | buffers / buffer | hdata: buffer | + Buffer unhidden | Unhide buffer + +| _buffer_renamed | buffers / buffer | hdata: buffer | + Buffer renamed | Rename buffer + +| _buffer_title_changed | buffers / buffer | hdata: buffer | + Title of buffer changed | Change title of buffer + +| _buffer_localvar_added | buffers / buffer | hdata: buffer | + Local variable added | Add local variable in buffer + +| _buffer_localvar_changed | buffers / buffer | hdata: buffer | + Local variable changed | Change local variable in buffer + +| _buffer_localvar_removed | buffers / buffer | hdata: buffer | + Local variable removed | Remove local variable from buffer + +| _buffer_closing | buffers / buffer | hdata: buffer | + Buffer closing | Close buffer + +| _buffer_cleared | buffer | hdata: buffer | + Buffer cleared | Clear buffer + +| _buffer_line_added | buffer | hdata: line | + Line added in buffer | Display line in buffer + +| _nicklist | nicklist | hdata: nicklist_item | + Nicklist for a buffer | Replace nicklist + +| _nicklist_diff | nicklist | hdata: nicklist_item | + Nicklist diffs for a buffer | Update nicklist + +| _pong | (always) | string: ping arguments | + Answer to a "ping" | Measure response time + +| _upgrade | upgrade | (empty) | + WeeChat is upgrading | Desync from WeeChat (or disconnect) + +| _upgrade_ended | upgrade | (empty) | + Upgrade of WeeChat done | Sync/resync with WeeChat +|=== + +[[message_buffer_opened]] +==== _buffer_opened + +This message is sent to the client when the signal "buffer_opened" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| short_name | string | Short name (example: _#weechat_) +| nicklist | integer | 1 if buffer has a nicklist, otherwise 0 +| title | string | Buffer title +| local_variables | hashtable | Local variables +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: channel _#weechat_ joined on freenode, new buffer +_irc.freenode.#weechat_: + +[source,python] +---- +id: '_buffer_opened' +hda: + keys: {'number': 'int', 'full_name': 'str', 'short_name': 'str', 'nicklist': 'int', + 'title': 'str', 'local_variables': 'htb', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x35a8a60'] + number: 3 + full_name: 'irc.freenode.#weechat' + short_name: None + nicklist: 0 + title: None + local_variables: {'plugin': 'irc', 'name': 'freenode.#weechat'} + prev_buffer: '0x34e7400' + next_buffer: '0x0' +---- + +[[message_buffer_moved]] +==== _buffer_moved + +This message is sent to the client when the signal "buffer_moved" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: buffer _irc.freenode.#weechat_ moved to number 2: + +[source,python] +---- +id: '_buffer_moved' +hda: + keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x34588c0'] + number: 2 + full_name: 'irc.freenode.#weechat' + prev_buffer: '0x347b9f0' + next_buffer: '0x3471bc0' +---- + +[[message_buffer_merged]] +==== _buffer_merged + +This message is sent to the client when the signal "buffer_merged" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: buffer _irc.freenode.#weechat_ merged with buffer #2: + +[source,python] +---- +id: '_buffer_merged' +hda: + keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x4db4c00'] + number: 2 + full_name: 'irc.freenode.#weechat' + prev_buffer: '0x4cef9b0' + next_buffer: '0x0' +---- + +[[message_buffer_unmerged]] +==== _buffer_unmerged + +This message is sent to the client when the signal "buffer_unmerged" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: buffer _irc.freenode.#weechat_ unmerged: + +[source,python] +---- +id: '_buffer_unmerged' +hda: + keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x4db4c00'] + number: 3 + full_name: 'irc.freenode.#weechat' + prev_buffer: '0x4cef9b0' + next_buffer: '0x0' +---- + +[[message_buffer_hidden]] +==== _buffer_hidden + +_WeeChat ≥ 1.0._ + +This message is sent to the client when the signal "buffer_hidden" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: buffer _irc.freenode.#weechat_ hidden: + +[source,python] +---- +id: '_buffer_hidden' +hda: + keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x4db4c00'] + number: 2 + full_name: 'irc.freenode.#weechat' + prev_buffer: '0x4cef9b0' + next_buffer: '0x0' +---- + +[[message_buffer_unhidden]] +==== _buffer_unhidden + +_WeeChat ≥ 1.0._ + +This message is sent to the client when the signal "buffer_unhidden" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| prev_buffer | pointer | Pointer to previous buffer +| next_buffer | pointer | Pointer to next buffer +|=== + +Example: buffer _irc.freenode.#weechat_ unhidden: + +[source,python] +---- +id: '_buffer_unhidden' +hda: + keys: {'number': 'int', 'full_name': 'str', 'prev_buffer': 'ptr', 'next_buffer': 'ptr'} + path: ['buffer'] + item 1: + __path: ['0x4db4c00'] + number: 3 + full_name: 'irc.freenode.#weechat' + prev_buffer: '0x4cef9b0' + next_buffer: '0x0' +---- + +[[message_buffer_renamed]] +==== _buffer_renamed + +This message is sent to the client when the signal "buffer_renamed" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| short_name | string | Short name (example: _#weechat_) +| local_variables | hashtable | Local variables +|=== + +Example: private buffer renamed from _FlashCode_ to _Flash2_: + +[source,python] +---- +id: '_buffer_renamed' +hda: + keys: {'number': 'int', 'full_name': 'str', 'short_name': 'str', 'local_variables': 'htb'} + path: ['buffer'] + item 1: + __path: ['0x4df7b80'] + number: 5 + full_name: 'irc.freenode.Flash2' + short_name: 'Flash2' + local_variables: {'server': 'freenode', 'plugin': 'irc', 'type': 'private', + 'channel': 'FlashCode', 'nick': 'test', 'name': 'local.Flash2'} +---- + +[[message_buffer_title_changed]] +==== _buffer_title_changed + +This message is sent to the client when the signal "buffer_title_changed" is +sent by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| title | string | Buffer title +|=== + +Example: topic changed on channel _#weechat_: + +[source,python] +---- +id: '_buffer_title_changed' +hda: + keys: {'number': 'int', 'full_name': 'str', 'title': 'str'} + path: ['buffer'] + item 1: + __path: ['0x4a715d0'] + number: 3 + full_name: 'irc.freenode.#weechat' + title: 'Welcome on #weechat! https://weechat.org/' +---- + +[[message_buffer_cleared]] +==== _buffer_cleared + +_WeeChat ≥ 1.0._ + +This message is sent to the client when the signal "buffer_cleared" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +|=== + +Example: buffer _irc.freenode.#weechat_ has been cleared: + +[source,python] +---- +id: '_buffer_cleared' +hda: + keys: {'number': 'int', 'full_name': 'str'} + path: ['buffer'] + item 1: + __path: ['0x4a715d0'] + number: 3 + full_name: 'irc.freenode.#weechat' +---- + +[[message_buffer_type_changed]] +==== _buffer_type_changed + +This message is sent to the client when the signal "buffer_type_changed" is sent +by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| type | integer | Buffer type: 0 = formatted (default), 1 = free content +|=== + +Example: type of buffer _script.scripts_ changed from formatted (0) to free +content (1): + +[source,python] +---- +id: '_buffer_type_changed' +hda: + keys: {'number': 'int', 'full_name': 'str', 'type': 'int'} + path: ['buffer'] + item 1: + __path: ['0x27c9a70'] + number: 4 + full_name: 'script.scripts' + type: 1 +---- + +[[message_buffer_localvar_added]] +==== _buffer_localvar_added + +This message is sent to the client when the signal "buffer_localvar_added" is +sent by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| local_variables | hashtable | Local variables +|=== + +Example: local variable _test_ added in buffer _irc.freenode.#weechat_: + +[source,python] +---- +id='_buffer_localvar_added', objects: +hda: + keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'} + path: ['buffer'] + item 1: + __path: ['0x4a73de0'] + number: 3 + full_name: 'irc.freenode.#weechat' + local_variables: {'server': 'freenode', 'test': 'value', 'plugin': 'irc', + 'type': 'channel', 'channel': '#weechat', 'nick': 'test', + 'name': 'freenode.#weechat'} +---- + +[[message_buffer_localvar_changed]] +==== _buffer_localvar_changed + +This message is sent to the client when the signal "buffer_localvar_changed" is +sent by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| local_variables | hashtable | Local variables +|=== + +Example: local variable _test_ updated in buffer _irc.freenode.#weechat_: + +[source,python] +---- +id='_buffer_localvar_changed', objects: +hda: + keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'} + path: ['buffer'] + item 1: + __path: ['0x4a73de0'] + number: 3 + full_name: 'irc.freenode.#weechat' + local_variables: {'server': 'local', 'test': 'value2', 'plugin': 'irc', + 'type': 'channel', 'channel': '#weechat', 'nick': 'test', + 'name': 'freenode.#weechat'} +---- + +[[message_buffer_localvar_removed]] +==== _buffer_localvar_removed + +This message is sent to the client when the signal "buffer_localvar_removed" is +sent by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +| local_variables | hashtable | Local variables +|=== + +Example: local variable _test_ removed from buffer _irc.freenode.#weechat_: + +[source,python] +---- +id: '_buffer_localvar_removed' +hda: + keys: {'number': 'int', 'full_name': 'str', 'local_variables': 'htb'} + path: ['buffer'] + item 1: + __path: ['0x4a73de0'] + number: 3 + full_name: 'irc.freenode.#prout' + local_variables: {'server': 'local', 'plugin': 'irc', 'type': 'channel', + 'channel': '#weechat', 'nick': 'test', 'name': 'freenode.#weechat'} +---- + +[[message_buffer_line_added]] +==== _buffer_line_added + +This message is sent to the client when the signal "buffer_line_added" is sent +by WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| buffer | pointer | Buffer pointer +| date | time | Date of message +| date_printed | time | Date when WeeChat displayed message +| displayed | char | 1 if message is displayed, 0 if message is filtered (hidden) +| highlight | char | 1 if line has a highlight, otherwise 0 +| tags_array | array of strings | List of tags for line +| prefix | string | Prefix +| message | string | Message +|=== + +Example: new message _hello!_ from nick _FlashCode_ on buffer _irc.freenode.#weechat_: + +[source,python] +---- +id: '_buffer_line_added' +hda: + keys: {'buffer': 'ptr', 'date': 'tim', 'date_printed': 'tim', 'displayed': 'chr', + 'highlight': 'chr', 'tags_array': 'arr', 'prefix': 'str', 'message': 'str'} + path: ['line_data'] + item 1: + __path: ['0x4a49600'] + buffer: '0x4a715d0' + date: 1362728993 + date_printed: 1362728993 + displayed: 1 + highlight: 0 + tags_array: ['irc_privmsg', 'notify_message', 'prefix_nick_142', 'nick_FlashCode', 'log1'] + prefix: 'F06@F@00142FlashCode' + message: 'hello!' +---- + +[[message_buffer_closing]] +==== _buffer_closing + +This message is sent to the client when the signal "buffer_closing" is sent by +WeeChat. + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| number | integer | Buffer number (≥ 1) +| full_name | string | Full name (example: _irc.freenode.#weechat_) +|=== + +Example: buffer _irc.freenode.#weechat_ is being closed by WeeChat: + +[source,python] +---- +id: '_buffer_closing' +hda: + keys: {'number': 'int', 'full_name': 'str'} + path: ['buffer'] + item 1: + __path: ['0x4a715d0'] + number: 3 + full_name: 'irc.freenode.#weechat' +---- + +[[message_nicklist]] +==== _nicklist + +This message is sent to the client when large updates are made on a nicklist +(groups/nicks added/removed/changed). The message contains full nicklist. + +When small updates are made on a nicklist (for example just add one nick), +another message with identifier __nicklist_diff_ is sent (see below). + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| group | char | 1 for a group, 0 for a nick +| visible | char | 1 if group/nick is displayed, otherwise 0 +| level | integer | Level of group (0 for a nick) +| name | string | Name of group/nick +| color | string | Name color +| prefix | string | Prefix (only for a nick) +| prefix_color | string | Prefix color (only for a nick) +|=== + +Example: nicklist for buffer _irc.freenode.#weechat_: + +[source,python] +---- +id: '_nicklist' +hda: + keys: {'group': 'chr', 'visible': 'chr', 'level': 'int', 'name': 'str', 'color': 'str', + 'prefix': 'str', 'prefix_color': 'str'} + path: ['buffer', 'nicklist_item'] + item 1: + __path: ['0x4a75cd0', '0x31e95d0'] + group: 1 + visible: 0 + level: 0 + name: 'root' + color: None + prefix: None + prefix_color: None + item 2: + __path: ['0x4a75cd0', '0x41247b0'] + group: 1 + visible: 1 + level: 1 + name: '000|o' + color: 'weechat.color.nicklist_group' + prefix: None + prefix_color: None + item 3: + __path: ['0x4a75cd0', '0x4a60d20'] + group: 0 + visible: 1 + level: 0 + name: 'FlashCode' + color: '142' + prefix: '@' + prefix_color: 'lightgreen' + item 4: + __path: ['0x4a75cd0', '0x4aafaf0'] + group: 1 + visible: 1 + level: 1 + name: '001|v' + color: 'weechat.color.nicklist_group' + prefix: None + prefix_color: None + item 5: + __path: ['0x4a75cd0', '0x4a48d80'] + group: 1 + visible: 1 + level: 1 + name: '999|...' + color: 'weechat.color.nicklist_group' + prefix: None + prefix_color: None + item 6: + __path: ['0x4a75cd0', '0x4a5f560'] + group: 0 + visible: 1 + level: 0 + name: 'test' + color: 'weechat.color.chat_nick_self' + prefix: ' ' + prefix_color: '' +---- + +[[message_nicklist_diff]] +==== _nicklist_diff + +_WeeChat ≥ 0.4.1._ + +This message is sent to the client when small updates are made on a nicklist +(groups/nicks added/removed/changed). The message contains nicklist differences +(between old nicklist and current one). + +Data sent as hdata: + +[width="100%",cols="3m,2,10",options="header"] +|=== +| Name | Type | Description +| _diff | char | Type of diff (see below) +| group | char | 1 for a group, 0 for a nick +| visible | char | 1 if group/nick is displayed, otherwise 0 +| level | integer | Level of group (0 for a nick) +| name | string | Name of group/nick +| color | string | Name color +| prefix | string | Prefix (only for a nick) +| prefix_color | string | Prefix color (only for a nick) +|=== + +The value of __diff_ can be: + +* `^`: the parent group: group(s) or nick(s) after this one are related to this + group +* `+`: group/nick added in the parent group +* `-`: group/nick removed from the parent group +* `*`: group/nick updated in the parent group + +Example: nick _master_ added in group _000|o_ (channel ops on an IRC channel), +nicks _nick1_ and _nick2_ added in group _999|..._ (standard users on an IRC +channel): + +[source,python] +---- +id: '_nicklist_diff' +hda: + keys: {'_diff': 'chr', 'group': 'chr', 'visible': 'chr', 'level': 'int', 'name': 'str', + 'color': 'str', 'prefix': 'str', 'prefix_color': 'str'} + path: ['buffer', 'nicklist_item'] + item 1: + __path: ['0x46f2ee0', '0x343c9b0'] + _diff: 94 ('^') + group: 1 + visible: 1 + level: 1 + name: '000|o' + color: 'weechat.color.nicklist_group' + prefix: None + prefix_color: None + item 2: + __path: ['0x46f2ee0', '0x47e7f60'] + _diff: 43 ('+') + group: 0 + visible: 1 + level: 0 + name: 'master' + color: 'magenta' + prefix: '@' + prefix_color: 'lightgreen' + item 3: + __path: ['0x46f2ee0', '0x46b8e70'] + _diff: 94 ('^') + group: 1 + visible: 1 + level: 1 + name: '999|...' + color: 'weechat.color.nicklist_group' + prefix: None + prefix_color: None + item 4: + __path: ['0x46f2ee0', '0x3dba240'] + _diff: 43 ('+') + group: 0 + visible: 1 + level: 0 + name: 'nick1' + color: 'green' + prefix: ' ' + prefix_color: '' + item 5: + __path: ['0x46f2ee0', '0x3c379d0'] + _diff: 43 ('+') + group: 0 + visible: 1 + level: 0 + name: 'nick2' + color: 'lightblue' + prefix: ' ' + prefix_color: '' +---- + +[[message_pong]] +==== _pong + +_WeeChat ≥ 0.4.2._ + +This message is sent to the client when _relay_ receives a "ping" message. + +Data sent as string: arguments received in the "ping" message. + +The recommended action in client is to measure the response time and disconnect +if it is high. + +[[message_upgrade]] +==== _upgrade + +_WeeChat ≥ 0.3.8._ + +This message is sent to the client when WeeChat is starting upgrade process. + +There is no data in the message. + +The recommended action in client is to desynchronize from WeeChat (send command +_desync_), or to disconnect from WeeChat (because after upgrade, all pointers +will change). + +[NOTE] +During WeeChat upgrade, the socket remains opened (except if connection uses +SSL). + +[[message_upgrade_ended]] +==== _upgrade_ended + +_WeeChat ≥ 0.3.8._ + +This message is sent to the client when WeeChat has finished the upgrade +process. + +There is no data in the message. + +The recommended action in client is to resynchronize with WeeChat: resend all +commands sent on startup after the _init_. + +[[objects]] +=== Objects + +Objects are identified by 3 letters, called _type_. Following types are used: + +[width="100%",cols="^2m,5,10",options="header"] +|=== +| Type | Value | Length +| chr | Signed char | 1 byte +| int | Signed integer | 4 bytes +| lon | Signed long integer | 1 byte + length of integer as string +| str | String | 4 bytes + length of string (without final _\0_) +| buf | Buffer of bytes | 4 bytes + length of data +| ptr | Pointer | 1 byte + length of pointer as string +| tim | Time | 1 byte + length of time as string +| htb | Hashtable | Variable +| hda | Hdata content | Variable +| inf | Info: name + content | Variable +| inl | Infolist content | Variable +| arr | Array of objects | 3 bytes (type) + number of objects + data +|=== + +[[object_char]] +==== Char + +A signed char is stored as 1 byte. + +Example: + +.... +┌────┐ +│ 41 │ ────► 65 (0x41: "A") +└────┘ +.... + +[[object_integer]] +==== Integer + +A signed integer is stored as 4 bytes, encoded as big-endian format (most +significant byte first). + +Range: -2147483648 to 2147483647. + +Examples: + +.... +┌────┬────┬────┬────┐ +│ 00 │ 01 │ E2 │ 40 │ ────► 123456 +└────┴────┴────┴────┘ + +┌────┬────┬────┬────┐ +│ FF │ FE │ 1D │ C0 │ ────► -123456 +└────┴────┴────┴────┘ +.... + +[[object_long_integer]] +==== Long integer + +A signed long integer is encoded as a string, with length on one byte. + +Range: -9223372036854775808 to 9223372036854775807. + +Examples: + +.... +┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ +│ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► 1234567890 +└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ + └──┘ └───────────────────────────────────────────────┘ +length '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' + +┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ +│ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► -1234567890 +└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ + └──┘ └────────────────────────────────────────────────────┘ +length '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' +.... + +[[object_string]] +==== String + +A string is a length (integer on 4 bytes) + content of string (without final _\0_). + +Example: + +.... +┌────┬────┬────┬────╥────┬────┬────┬────┬────┐ +│ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ────► "hello" +└────┴────┴────┴────╨────┴────┴────┴────┴────┘ + └─────────────────┘ └──────────────────────┘ + length 'h' 'e' 'l' 'l' 'o' +.... + +An empty string has a length of zero: + +.... +┌────┬────┬────┬────┐ +│ 00 │ 00 │ 00 │ 00 │ ────► "" +└────┴────┴────┴────┘ + └─────────────────┘ + length +.... + +A _NULL_ string (NULL pointer in C) has a length of -1: + +.... +┌────┬────┬────┬────┐ +│ FF │ FF │ FF │ FF │ ────► NULL +└────┴────┴────┴────┘ + └─────────────────┘ + length +.... + +[[object_buffer]] +==== Buffer + +Same format as <<object_string,string>>; content is just an array of bytes. + +[[object_pointer]] +==== Pointer + +A pointer is encoded as string (hex), with length on one byte. + +Example: + +.... +┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐ +│ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ────► 0x1a2b3c4d5 +└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘ + └──┘ └──────────────────────────────────────────┘ +length '1' 'a' '2' 'b' '3' 'c' '4' 'd' '5' +.... + +A _NULL_ pointer has a length of 1 with value 0: + +.... +┌────╥────┐ +│ 01 ║ 00 │ ────► NULL (0x0) +└────╨────┘ + └──┘ └──┘ +length 0 +.... + +[[object_time]] +==== Time + +A time (number of seconds) is encoded as a string, with length on one byte. + +Example: + +.... +┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ +│ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ────► 1321993456 +└────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ + └──┘ └───────────────────────────────────────────────┘ +length '1' '3' '2' '1' '9' '9' '3' '4' '5' '6' +.... + +[[object_hashtable]] +==== Hashtable + +A hashtable contains type for keys, type for values, number of items in +hashtable (integer on 4 bytes), and then keys and values of items. + +.... +┌───────────┬─────────────┬───────╥───────┬─────────╥─────╥───────┬─────────┐ +│ type_keys │ type_values │ count ║ key 1 │ value 1 ║ ... ║ key N │ value N │ +└───────────┴─────────────┴───────╨───────┴─────────╨─────╨───────┴─────────┘ +.... + +Example: + +.... +┌─────┬─────┬───╥──────┬─────╥──────┬─────┐ +│ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ────► { 'key1' => 'abc', +└─────┴─────┴───╨──────┴─────╨──────┴─────┘ 'key2' => 'def' } + └───┘ └───┘ └─┘ └──────────┘ └──────────┘ + type type count item 1 item 2 + keys values +.... + +[[object_hdata]] +==== Hdata + +A _hdata_ contains a path with hdata names, list of keys, number of set of +objects, and then set of objects (path with pointers, then objects). + +.... +┌────────┬──────┬───────╥────────┬─────────────────────╥── +│ h-path │ keys │ count ║ p-path │ value 1 ... value N ║ ... +└────────┴──────┴───────╨────────┴─────────────────────╨── + + ──╥────────┬─────────────────────╥─────┐ + ... ║ p-path │ value 1 ... value N ║ ... │ + ──╨────────┴─────────────────────╨─────┘ +.... + +* _h-path_ (string): path used to reach hdata (example: + _buffer/lines/line/line_data_); the last element in path is the hdata returned +* _keys_ (string): string with list of _key:type_ (separated by commas), + example: _number:int,name:str_ +* _count_ (integer): number of set of objects +* _p-path_: path with pointers to objects (number of pointers here is number of + elements in path) +* _values_: list of values (number of values is number of keys returned for + hdata) + +Example of hdata with two buffers (weechat core and freenode server) and two +keys (_number_ and _full_name_): + +.... +# command +hdata buffer:gui_buffers(*) number,full_name + +# response +┌────────┬──────────────────────────┬───╥── +│ buffer │ number:int,full_name:str │ 2 ║ ... +└────────┴──────────────────────────┴───╨── + └──────┘ └────────────────────────┘ └─┘ + h-path keys count + + ──╥─────────┬───┬──────────────╥─────────┬───┬────────────────────┐ + ... ║ 0x12345 │ 1 │ core.weechat ║ 0x6789a │ 2 │irc.server.freenode │ + ──╨─────────┴───┴──────────────╨─────────┴───┴────────────────────┘ + └──────────────────────────┘ └────────────────────────────────┘ + buffer 1 buffer 2 +.... + +Example of hdata with lines of core buffer: + +.... +# command +hdata buffer:gui_buffers(*)/lines/first_line(*)/data + +# response +┌─────────────────────────────┬─────┬────╥── +│ buffer/lines/line/line_data │ ... │ 50 ║ ... +└─────────────────────────────┴─────┴────╨── + └───────────────────────────┘ └───┘ └──┘ + h-path (hdata names) keys count + + ──╥───────────┬───────────┬───────────┬───────╥── + ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d5f40 │ ..... ║ ... + ──╨───────────┴───────────┴───────────┴───────╨── + └─────────────────────────────────┘ └─────┘ + p-path (pointers) objects + └─────────────────────────────────────────┘ + line 1 + + ──╥───────────┬───────────┬───────────┬───────╥──────────────┐ + ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d6110 │ ..... ║ ............ │ + ──╨───────────┴───────────┴───────────┴───────╨──────────────┘ + └─────────────────────────────────┘ └─────┘ + p-path (pointers) objects + └─────────────────────────────────────────┘ └────────────┘ + line 2 lines 3-50 +.... + +Example of hdata with nicklist: + +.... +# command +nicklist + +# response +┌───────────────────┬── +│ buffer/nick_group │ ... +└───────────────────┴── + └─────────────────┘ + h-path + + ──╥───────────────────────────────────────────────────────────┬────╥── + ... ║ group:chr,visible:chr,name:str,color:str,prefix:str,(...) │ 12 ║ ... + ──╨───────────────────────────────────────────────────────────┴────╨── + └─────────────────────────────────────────────────────────┘ └──┘ + keys count + + ──╥─────────┬─────────┬───┬───┬──────┬─┬─┬─┬───╥── + ... ║ 0x12345 │ 0x6789a │ 1 │ 0 │ root │ │ │ │ 0 ║ ... + ──╨─────────┴─────────┴───┴───┴──────┴─┴─┴─┴───╨── + └─────────────────┘ └──────────────────────┘ + p-path objects + └──────────────────────────────────────────┘ + group (nicklist root) + + ──╥─────────┬─────────┬───┬───┬───────┬─┬─┬─┬───╥── + ... ║ 0x123cf │ 0x678d4 │ 1 │ 0 │ 000|o │ │ │ │ 1 ║ ... + ──╨─────────┴─────────┴───┴───┴───────┴─┴─┴─┴───╨── + └─────────────────┘ └───────────────────────┘ + p-path objects + └───────────────────────────────────────────┘ + group (channel ops) + + ──╥─────────┬─────────┬───┬───┬──────────┬──────┬───┬────────────┬───╥── + ... ║ 0x128a7 │ 0x67ab2 │ 0 │ 1 │ ChanServ │ blue │ @ │ lightgreen │ 0 ║ ... + ──╨─────────┴─────────┴───┴───┴──────────┴──────┴───┴────────────┴───╨── + └─────────────────┘ └────────────────────────────────────────────┘ + p-path objects + └────────────────────────────────────────────────────────────────┘ + nick (@ChanServ) +.... + +[[object_info]] +==== Info + +A _info_ contains a name and a value (both are strings). + +.... +┌──────┬───────┐ +│ name │ value │ +└──────┴───────┘ +.... + +* _name_ (string): name of info +* _value_ (string): value + +Example of info _version_: + +.... +┌─────────┬───────────────────┐ +│ version │ WeeChat 0.3.7-dev │ +└─────────┴───────────────────┘ +.... + +[[object_infolist]] +==== Infolist + +A _infolist_ contains a name, number of items, and then items (set of +variables). + +.... +┌──────┬───────╥────────╥─────╥────────┐ +│ name │ count ║ item 1 ║ ... ║ item N │ +└──────┴───────╨────────╨─────╨────────┘ +.... + +An item is: + +.... +┌───────╥────────┬────────┬─────────╥─────╥────────┬────────┬─────────┐ +│ count ║ name 1 │ type 1 │ value 1 ║ ... ║ name N │ type N │ value N │ +└───────╨────────┴────────┴─────────╨─────╨────────┴────────┴─────────┘ +.... + +* _name_ (string): name of infolist (_buffer_, _window_, _bar_, ...) +* _count_ (integer): number of items +* _item_: +** _count_: number of variables in item +** _name_: name of variable +** _type_: type of variable (_int_, _str_, ...) +** _value_: value of variable + +Example of infolist with two buffers (weechat core and freenode server): + +.... +# command +infolist buffer + +# response +┌────────┬───╥────┬─────────┬─────┬─────────┬─────╥── +│ buffer │ 2 ║ 42 │ pointer │ ptr │ 0x12345 │ ... ║ ... +└────────┴───╨────┴─────────┴─────┴─────────┴─────╨── + └──────┘ └─┘ └──────────────────────────────────┘ + name count item 1 + + ──╥────┬─────────┬─────┬─────────┬─────┐ + ... ║ 42 │ pointer │ ptr │ 0x6789a │ ... │ + ──╨────┴─────────┴─────┴─────────┴─────┘ + └──────────────────────────────────┘ + item 2 +.... + +[[object_array]] +==== Array + +An array is a type (3 bytes) + number of objects (integer on 4 bytes) + data. + +Example of array with two strings: + +.... +┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥── +│ str ║ 00 │ 00 │ 00 │ 02 ║ 00 │ 00 │ 00 │ 03 ║ ... +└─────╨────┴────┴────┴────╨────┴────┴────┴────╨── + └───┘ └─────────────────┘ └─────────────────┘ + type number of strings length + + ──╥────┬────┬────╥────┬────┬────┬────╥────┬────┐ + ... ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ────► [ "abc", "de" ] + ──╨────┴────┴────╨────┴────┴────┴────╨────┴────┘ + └────────────┘ └─────────────────┘ └───────┘ + 'a' 'b' 'c' length 'd' 'e' +.... + +Example of array with three integers: + +.... +┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥── +│ int ║ 00 │ 00 │ 00 │ 03 ║ 00 │ 00 │ 00 │ 7B ║ ... +└─────╨────┴────┴────┴────╨────┴────┴────┴────╨── + └───┘ └─────────────────┘ └─────────────────┘ + type number of integers 123 (0x7B) + + ──╥────┬────┬────┬────╥────┬────┬────┬────┐ + ... ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ────► [ 123, 456, 789 ] + ──╨────┴────┴────┴────╨────┴────┴────┴────┘ + └─────────────────┘ └─────────────────┘ + 456 (0x1C8) 789 (0x315) +.... + +A _NULL_ array: + +.... +┌─────╥────┬────┬────┬────┐ +│ str ║ 00 │ 00 │ 00 │ 00 │ ────► NULL +└─────╨────┴────┴────┴────┘ + └───┘ └─────────────────┘ + type number of strings +.... + +[[typical_session]] +== Typical session + +.... + ┌────────┐ ┌───────┐ ┌─────────┐ + │ Client ├ ─ ─ ─ ─(network)─ ─ ─ ─ ┤ Relay ├────────────────┤ WeeChat │ + └────────┘ └───────┘ └─────────┘ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ open socket ║ add client ║ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ cmd: init password=xxx,... ║ init/allow client ║ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ cmd: hdata buffer ... ╟───────────────────────► ║ + ║ sync ... ║ request hdata ║ read hdata + ║ ║ ║ values + ║ ║ ◄───────────────────────╢ + ║ ◄───────────────────────────────╢ hdata ║ + create ║ msg: hda buffer ║ ║ + buffers ║ ║ ║ + ║ ........ ║ ........ ║ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ cmd: input ... ╟───────────────────────► ║ + ║ ║ send data to buffer ║ send data + ║ ║ ║ to buffer + ║ ........ ║ ........ ║ + ║ ║ ║ signal + ║ ║ ◄───────────────────────╢ received + ║ ◄───────────────────────────────╢ signal XXX ║ (hooked by + update ║ msg: id: "_buffer_..." ║ ║ relay) + buffers ║ ║ ║ + ║ ........ ║ ........ ║ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ cmd: ping ... ║ ║ + ║ ║ ║ + ║ ◄───────────────────────────────╢ ║ + measure ║ msg: id: "_pong" ... ║ ║ +response ║ ║ ║ + time ║ ........ ║ ........ ║ + ║ ║ ║ + ╟───────────────────────────────► ║ ║ + ║ cmd: quit ║ disconnect client ║ + ║ ║ ║ +.... |