Превод:
-
Иван Пешић (<ivan.pesic@gmail.com>), 2021.
1. Увод
Овај документ је спецификација WeeChat Релеј протокола: протокола који се користи за прослеђивање WeeChat података клојентима, који су углавном удаљени интерфејси.
1.1. Терминологија
У документу се користе следећи изрази:
-
релеј: то је програм WeeChat са релеј додатком, који се понаша као „сервер” и дозвољава клијентима да успоставе везу са њим
-
клијент: оно је неки други софтвер, повезан са релејем преком мрежне везе; у већини случајева, овај клијент је удаљени интерфејс.
1.2. Мрежни дијаграм
клијенти су повезани са релејем као што је приказано на следећем дијаграму:
┌───────────┐ Радна станица ┌────────┐ ┌───┤ клијент 1 │ (Linux, Windows, │ irc │◄──┐ ╔═══════════╤═══════╗ │ └───────────┘ BSD, macOS...) └────────┘ └──╢ │ ║◄───┘ ┌───────────┐ ...... ║ WeeChat │ Релеј ║◄───────┤ клијент 2 │ Мобилни уређај ┌────────┐ ┌──╢ │ ║◄───┐ └───────────┘ (Android, iPhone...) │ jabber │◄──┘ ╚═══════════╧═══════╝ │ ...... └────────┘ │ ┌───────────┐ ...... └───┤ клијент N │ Остали уређаји └───────────┘ └────────────┘ └───────────────────┘╘══════╛└────────────────────────────────┘ мрежни сервери ncurses интерфејс релеј удаљени интерфејси протокол
Сви клијенти овде су клијенти који користе weechat протокол у релеј додатку. релеј додатак такође дозвољава IRC клијенте, па се онда релеј додатак понаша као IRC прокси (није описан у овом документу). |
2. Уопштено о протоколу
-
Везе од клијента ка релеју се успостављају преко TCP сокета на IP/порту који користи релеј додатак који ослушкује нове везе.
-
Број клијената је ограничен опцијом relay.network.max_clients.
-
Сваки клијент је независан у односу на остале клијенте.
-
Поруке од клијента ка релеју се називају команде, а шаљу се као текст (то јест стринг).
-
Поруке од релеја ка клијенту се називају поруке, а шаљу се као бинарни подаци.
3. Команде (клијент → релеј)
Команде имају следећи формат:
(id) команда аргументи\n
Поља су следећа:
-
id: необавезни идентификатор поруке који ће се послати уз одговор релеја; мора да се постави унутар заграда и не сме да почне доњом цртом (идентификатори који почињу доњом цртом су резервисани за WeeChat event поруке)
-
команда: команда (погледајте табелу испод)
-
аргументи: необавезни аргументи команде (више аргумената може да се раздвоји размацима).
Листа доступних команди (детаљи су у наредним поглављима):
Команда | Опис |
---|---|
|
Руковање: припрема за аутентификацију клијента и постављање опција, пре init команде. |
|
Аутентификација са релејем. |
|
Захтев за hdata. |
|
Захтев за инфо. |
|
Захтев за инфолисту. |
|
Захтев за листу надимака. |
|
Слање података у бафер (текст или команда). |
|
Захтев за довршавање стринга. |
|
Синхронизација бафера: преузимање ажурирања бафера. |
|
Десинхронизација бафера: прекид ажурирања бафера. |
|
Раскидање везе са релејем. |
3.1. handshake
WeeChat ≥ 2.9, ажурирано у верзијама 3.5, 4.0.0.
Извршава руковање између клијента и програма WeeChat: ово је у већини случајева неопходно како би се сазнале поставке сесије и припремила аутентификација командом init.
Пре init команде је дозвољено само једно руковање.
Синтакса:
(id) handshake [<опција>=<вредност>,[<опција>=<вредност>,...]]
Аргументи:
-
опција: једна од следећих опција:
-
password_hash_algo: листа хеш алгоритама које подржава клијент (раздвојене са две тачке), дозвољене су следеће вредности:
-
plain: чиста текст лозинка (без хеша)
-
sha256: лозинка засољена и хеширана SHA256 алгоритмом
-
sha512: лозинка засољена и хеширана SHA512 алгоритмом
-
pbkdf2+sha256: лозинка засољена и хеширана PBKDF2 алгоритмом (користећи SHA256 хеш)
-
pbkdf2+sha512: лозинка засољена и хеширана PBKDF2 алгоритмом (користећи SHA512 хеш)
-
-
compression: листа типова компресије које клијент подржава (раздвојених двотачкама и сортираних од најважнијег до вредности у крајњој нужди); ако је компресија укључена, поруке од релеја ка клијетну се компресују у циљу штедње пропусног опсега; дозвољене су следеће вредности:
-
off: без компресије (подразумевано ако се опција не наведе)
-
zlib: компресија са zlib ↗ (WeeChat ≥ 0.3.7)
-
zstd: компресија са Zstandard ↗: боља компресија, као и много бржа компресија и декомпресија у односу на zlib (WeeChat ≥ 3.5)
-
-
escape_commands: команде које клијент шаље релеју морају да се означе: све обрнуте косе црте се интерпретирају и једна обрнута коса црта мора да се означи (
\\
); на овај начин клијент, на пример, може да шаље вишелинијске поруке (карактери\n
се претварају у преломе редова, погледајте input команду) (WeeChat ≥ 4.0.0)
-
Напомене у вези опције password_hash_algo:
-
Ако се опција не наведе (или ако клијент није послао handshake команду), релеј аутоматски користи plain аутентификацију (ако је дозвољена на релеј страни).
-
Релеј бира најсигурнији алгоритам који је доступан и на клијенту и на релеју, према редоследу приоритета од првог (најсигурнијег) до последње коришћеног:
-
pbkdf2+sha512
-
pbkdf2+sha256
-
sha512
-
sha256
-
plain
-
Програм WeeChat одговара са хеш табелом која садржи следеће кључеве и вредности:
-
password_hash_algo: договорена аутентификација лозинком: подржавају је и клијент_both и _релеј:
-
(празна вредност): договор није успео, НИЈЕ могућа аутентификација лозинком; у овом случају се веза са клијентом тренутно прекида.
-
plain
-
sha256
-
sha512
-
pbkdf2+sha256
-
pbkdf2+sha512
-
-
password_hash_iterations: број итерација за (само за PBKDF2 алгоритам)
-
totp:
-
on: Time-based One-Time Password (TOTP) је конфигурисана и очекује се у init команди
-
off: Time-based One-Time Password (TOTP) је искључена и није потребна у init команди
-
-
nonce: бафер бајтова који не могу да се предвиде, послат као хексадецимална вредност, којом се спречавају replay напади; ако је password_hash_algo хеш алгоритам, клијент мора да израчуна хеш лозинке над овим нонсом, спојено са клијентовим нонсом и корисничком лозинком (релеј нонс + клијент нонс је со која се користи у алгоритму хеширања лозинке)
-
compression: тип компресије:
-
off: поруке се не компресују
-
zlib: поруке су компресоване са zlib ↗
-
zstd: поруке су компресоване са Zstandard ↗
-
-
escape_commands:
-
on: све обрнуте косе црте у порукама клијента се интерпретирају
-
off: обрнуте косе црте у порукама клијента се НЕ интерпретирају и користе се онакве какве су
-
У програму WeeChat верзије ≤ 2.8, команда handshake није имплементирана, програм WeeChat једноставно игнорише ову команду, чак и ако се пошаље пре init команде. Тако да је безбедно послати ову поруку програму WeeChat било које верзије. |
Примери:
-
Клијент није ништа понудио, користиће се "plain" аутентификација лозинком ако је то дозвољено на релеј страни:
(handshake) handshake
Одговор:
id: 'handshake'
htb: {
'password_hash_algo': 'plain',
'password_hash_iterations': '100000',
'totp': 'on',
'nonce': '85B1EE00695A5B254E14F4885538DF0D',
'compression': 'off',
'escape_commands': 'off',
}
-
Escape of commands enabled by the client (WeeChat ≥ 4.0.0):
(handshake) handshake escape_commands=on
Response:
id: 'handshake'
htb: {
'password_hash_algo': 'plain',
'password_hash_iterations': '100000',
'totp': 'on',
'nonce': '85B1EE00695A5B254E14F4885538DF0D',
'compression': 'off',
'escape_commands': 'on',
}
-
Клијент подржава само „plain”:
(handshake) handshake password_hash_algo=plain
Одговор:
id: 'handshake'
htb: {
'password_hash_algo': 'plain',
'password_hash_iterations': '100000',
'totp': 'on',
'nonce': '85B1EE00695A5B254E14F4885538DF0D',
'compression': 'off',
'escape_commands': 'off',
}
-
Клијент подржава само „plain”, „sha256” и „pbkdf2+sha256”:
(handshake) handshake password_hash_algo=plain:sha256:pbkdf2+sha256
Одговор:
id: 'handshake'
htb: {
'password_hash_algo': 'pbkdf2+sha256',
'password_hash_iterations': '100000',
'totp': 'on',
'nonce': '85B1EE00695A5B254E14F4885538DF0D',
'compression': 'off',
'escape_commands': 'off',
}
Клијент може да се аутентификује следећом командом (погледајте init команду), со је relay нонс + client нонс („A4B73207F5AAE4” хексадецимално), лозинка је „test” у овом примеру:
init password_hash=pbkdf2+sha256:85b1ee00695a5b254e14f4885538df0da4b73207f5aae4:100000:ba7facc3edb89cd06ae810e29ced85980ff36de2bb596fcf513aaab626876440
-
Клијент подржава само „sha256” и „sha512”, укључује се zstd (пожељније) или zlib компресија:
(handshake) handshake password_hash_algo=sha256:sha512,compression=zstd:zlib
Одговор:
id: 'handshake'
htb: {
'password_hash_algo': 'sha512',
'password_hash_iterations': '100000',
'totp': 'on',
'nonce': '85B1EE00695A5B254E14F4885538DF0D',
'compression': 'zstd',
'escape_commands': 'off',
}
3.2. init
Ажурирано у верзијама 2.4, 2.8, 2.9, 3.5.
Аутентификација са релејем.
Ово мора бити прва команда која се шаље релеју (пре init сме да се пошаље једино команда handshake).
Ако се не пошаље, релеј ће без упозорења да раскине везу чим прими прву следећу команду (осим handshake).
Синтакса:
(id) init [<опција>=<вредност>,[<опција>=<вредност>,...]]
Аргументи:
-
опција: једна од следећих опција:
-
password: лозинка која се користи за аутентификацију са релејем (опција relay.network.password у програму WeeChat)
-
password_hash: хеш лозинке која се користи за аутентификацију са релејем (опција relay.network.password у програму WeeChat), погледајте испод за формат (WeeChat ≥ 2.8)
-
totp: Time-based One-Time Password (TOTP) која се користи као секундарни фактор аутентификације, уз лозинку (опција relay.network.totp_secret у програму WeeChat) (WeeChat ≥ 2.4)
-
У програму WeeChat верзије ≥ 1.6, у вредности могу да се означе запете, на пример init password=foo\,bar када желите да пошаљете лозинку „foo,bar”.
|
Формат хеширане лозинке је једно од следећег, где је хеш хеширана лозинка као хексадецимална вредност:
-
sha256:со:хеш
где је :-
со: со (хексадецимално), која мора да почиње са северовим нонсом, на који је надовезан клијентов нонс
-
хеш: хеширана со + лозинка (хексадецимално)
-
-
sha512:со:хеш
где је:-
со: со (хексадецимално), која мора да почиње са северовим нонсом, на који је надовезан клијентов нонс
-
хеш: хеширана со + лозинка (хексадецимално)
-
-
pbkdf2+sha256:со:итерација:хеш
где је:-
со: со (хексадецимално), која мора да почиње са северовим нонсом, на који је надовезан клијентов нонс
-
iterations: број итерација
-
хеш: со + лозинка хеширана SHA256 алгоритмом (хексадецимално)
-
-
pbkdf2+sha512:со:итерација:хеш
где је:-
со: со (хексадецимално), која мора да почиње са северовим нонсом, на који је надовезан клијентов нонс
-
iterations: број итерација
-
хеш: со + лозинка хеширана SHA512 алгоритмом (хексадецимално)
-
Хексадецимални стрингови могу бити исписани малим или великим словима, релеј може да декодира оба. |
Примери:
-
Иницијализација лозинком:
init password=мојалозинка
-
Иницијализација са запетама у лозинки (WeeChat ≥ 1.6):
init password=мојалозинка\,са\,запетама
-
Иницијализација са лозинком и TOTP (WeeChat ≥ 2.4):
init password=мојалозинка,totp=123456
-
Иницијализација са хешираном лозинком „test” (SHA256: со=релеј нонс + клијент нонс) (WeeChat ≥ 2.9):
init password_hash=sha256:85b1ee00695a5b254e14f4885538df0da4b73207f5aae4:2c6ed12eb0109fca3aedc03bf03d9b6e804cd60a23e1731fd17794da423e21db
-
Иницијализација са хешираном лозинком „test” (SHA512: со=релеј нонс + клијент нонс) (WeeChat ≥ 2.9):
init password_hash=sha512:85b1ee00695a5b254e14f4885538df0da4b73207f5aae4:0a1f0172a542916bd86e0cbceebc1c38ed791f6be246120452825f0d74ef1078c79e9812de8b0ab3dfaf598b6ca14522374ec6a8653a46df3f96a6b54ac1f0f8
-
Иницијализација са хешираном лозинком „test” (PBKDF2: SHA256, со=релеј нонс + клијент нонс, 100000 итерација) (WeeChat ≥ 2.9):
init password_hash=pbkdf2+sha256:85b1ee00695a5b254e14f4885538df0da4b73207f5aae4:100000:ba7facc3edb89cd06ae810e29ced85980ff36de2bb596fcf513aaab626876440
3.3. hdata
Захтев за hdata.
Синтакса:
(id) hdata <путања> [<кључеви>]
Аргументи:
-
путања: путања до hdata, у формату: „hdata:показивач/пром/пром/…/пром”, последња пром је враћени hdata:
-
hdata: име hdata
-
показивач: показивач (нпр.: „0x1234abcd”) или име листе (на пример: „gui_buffers”) (дозвољен је број понављања, погледајте испод)
-
пром: име променљиве у родитељском hdata (претходно име на путањи) (дозвољен је број понављања, погледајте испод)
-
-
кључеви: листа кључева раздвојених запетама у које се враћају hdata (ако се не наведе, враћају се сви кључеви, што се не препоручује код великих hdata структура)
Број понављања се дозвољава након показивача и променљивих, у формату „(N)”. Могуће су следеће вредности:
-
позитивни број: итерира се користећи следећи елемент, N пута
-
негативни број: итерира се користећи претходни елемент, N пута
-
*: итерира се користећи наредни елемент, све до краја листе
У програму WeeChat верзије ≥ 1.6, у случају да је hdata путања неисправна или ако се наиђе на NULL показивач, враћа се празан hdata (погледајте пример у hdata објекат). У старијим верзијама, не враћа се ништа. |
Примери:
-
Захтев за „number” и „full_name” свих бафера:
(hdata_buffers) hdata buffer:gui_buffers(*) number,full_name
Одговор:
id: 'hdata_buffers'
hda:
keys: {
'number': 'int',
'full_name': 'str',
}
path: ['buffer']
item 1:
__path: ['0x558d61ea3e60']
number: 1
full_name: 'core.weechat'
item 2:
__path: ['0x558d62840ea0']
number: 1
full_name: 'irc.server.libera'
item 3:
__path: ['0x558d62a9cea0']
number: 2
full_name: 'irc.libera.#weechat'
-
Захтев за свим линијама првог бафера:
(hdata_lines) hdata buffer:gui_buffers/own_lines/first_line(*)/data
Одговор:
id: 'hdata_lines'
hda:
keys: {
'buffer': 'ptr',
'y': 'int',
'date': 'tim',
'date_usec': 'int',
'date_printed': 'tim',
'date_usec_printed': 'int',
'str_time': 'str',
'tags_count': 'int',
'tags_array': 'arr',
'displayed': 'chr',
'notify_level': 'chr',
'highlight': 'chr',
'refresh_needed': 'chr',
'prefix': 'str',
'prefix_length': 'int',
'message': 'str',
}
path: ['buffer', 'lines', 'line', 'line_data']
item 1:
__path: ['0x558d61ea3e60', '0x558d61ea40e0', '0x558d62920d80', '0x558d62abf040']
buffer: '0x558d61ea3e60'
y: -1
date: 1588404926
date_usec: 118712
date_printed: 1588404926
date_usec_printed: 118712
str_time: 'F@0025209F@0024535F@0024026'
tags_count: 0
tags_array: []
displayed: 1
notify_level: 0
highlight: 0
refresh_needed: 0
prefix: ''
prefix_length: 0
message: 'ово је прва линија'
item 2:
__path: ['0x558d61ea3e60', '0x558d61ea40e0', '0x558d626779f0', '0x558d62af9700']
buffer: '0x558d61ea3e60'
y: -1
date: 1588404930
date_usec: 25
date_printed: 1588404930
date_usec_printed: 25
str_time: 'F@0025209F@0024535F@0024030'
tags_count: 0
tags_array: []
displayed: 1
notify_level: 0
highlight: 0
refresh_needed: 0
prefix: ''
prefix_length: 0
message: 'ово је друга линија'
-
Захтев за садржај вруће листе:
(hdata_hotlist) hdata hotlist:gui_hotlist(*)
Одговор:
id: 'hdata_hotlist'
hda:
keys: {
'priority': 'int',
'creation_time.tv_sec': 'tim',
'creation_time.tv_usec': 'lon',
'buffer': 'ptr',
'count': 'arr',
'prev_hotlist': 'ptr',
'next_hotlist': 'ptr',
}
path: ['hotlist']
item 1:
__path: ['0x558d629601b0']
priority: 3
creation_time.tv_sec: 1588405398
creation_time.tv_usec: 355383
buffer: '0x558d62a9cea0'
count: [1, 1, 0, 1]
prev_hotlist: '0x0'
next_hotlist: '0x0'
3.4. info
Захтев за инфо.
Синтакса:
(id) info <име> [<аргументи>]
Аргументи:
-
име: име информације која се захтева
-
аргументи: аргументи (није обавезно)
Примери:
-
Захтев за верзију програма WeeChat:
(info_version) info version
Одговор:
id: 'info_version'
inf: ('version', '2.9-dev')
-
Захтев за верзију програма WeeChat као број:
(info_version_number) info version_number
Одговор:
id: 'info_version_number'
inf: ('version_number', '34144256')
-
Захтев за WeeChat директоријум:
(info_weechat_config_dir) info weechat_config_dir
Одговор:
id: 'info_weechat_config_dir'
inf: ('weechat_config_dir', '/home/user/.config/weechat')
3.5. infolist
Захтев инфолисте.
Садржај инфолисте је дупликат стварних података. Кадгод је то могуће, употребите команду hdata, која обезбеђује директан приступ подацима (бржа је, користи мање меморије и враћа мање објекте у поруци). |
Синтакса:
(id) infolist <име> [<показивач> [<аргументи>]]
Аргументи:
-
име: име жељене инфолисте
-
показивач: показивач (није обавезан)
-
аргументи: аргументи (није обавезно)
Примери:
-
Захтев за „buffer” инфолисту:
(infolist_buffer) infolist buffer
Одговор:
id: 'infolist_buffer'
inl:
name: buffer
item 1:
pointer: '0x558d61ea3e60'
current_buffer: 1
plugin: '0x0'
plugin_name: 'core'
number: 1
layout_number: 1
layout_number_merge_order: 0
name: 'weechat'
full_name: 'core.weechat'
old_full_name: None
short_name: 'weechat'
type: 0
notify: 3
num_displayed: 1
active: 1
hidden: 0
zoomed: 0
print_hooks_enabled: 1
day_change: 1
clear: 1
filter: 1
closing: 0
first_line_not_read: 0
lines_hidden: 0
prefix_max_length: 0
time_for_each_line: 1
nicklist_case_sensitive: 0
nicklist_display_groups: 1
nicklist_max_length: 0
nicklist_count: 0
nicklist_groups_count: 0
nicklist_nicks_count: 0
nicklist_visible_count: 0
title: 'WeeChat 2.9-dev (C) 2003-2020 - https://weechat.org/'
input: 1
input_get_unknown_commands: 0
input_get_empty: 0
input_multiline: 0
input_buffer: ''
input_buffer_alloc: 256
input_buffer_size: 0
input_buffer_length: 0
input_buffer_pos: 0
input_buffer_1st_display: 0
num_history: 0
text_search: 0
text_search_direction: 0
text_search_exact: 0
text_search_regex: 0
text_search_regex_compiled: '0x0'
text_search_where: 0
text_search_history: 0
text_search_found: 0
text_search_ptr_history: '0x0'
text_search_input: None
highlight_words: None
highlight_disable_regex: None
highlight_disable_regex_compiled: '0x0'
highlight_regex: None
highlight_regex_compiled: '0x0'
highlight_tags_restrict: None
highlight_tags: None
hotlist_max_level_nicks: None
keys_count: 0
localvar_name_00000: 'plugin'
localvar_value_00000: 'core'
localvar_name_00001: 'name'
localvar_value_00001: 'weechat'
-
Захтев за „window” инфолисту:
(infolist_window) infolist window
Одговор:
id: 'infolist_window'
inl:
name: window
item 1:
pointer: '0x558d61ddc800'
current_window: 1
number: 1
x: 14
y: 0
width: 259
height: 71
width_pct: 100
height_pct: 100
chat_x: 14
chat_y: 1
chat_width: 259
chat_height: 68
buffer: '0x558d61ea3e60'
start_line_y: 0
3.6. nicklist
Захтев листе надимака, за један или за све бафере.
Синтакса:
(id) nicklist [<бафер>]
Аргументи:
-
бафер: показивач (нпр.: „0x1234abcd”) или пуно име бафера (на пример: core.weechat или irc.libera.#weechat)
Примери:
-
Захтев листе бафера за све бафере:
(nicklist_all) nicklist
Одговор:
id: 'nicklist_all'
hda:
keys: {
'group': 'chr',
'visible': 'chr',
'level': 'int',
'name': 'str',
'color': 'str',
'prefix': 'str',
'prefix_color': 'str',
}
path: ['buffer', 'nicklist_item']
item 1:
__path: ['0x558d61ea3e60', '0x558d61ea4120']
group: 1
visible: 0
level: 0
name: 'root'
color: None
prefix: None
prefix_color: None
item 2:
__path: ['0x558d62840ea0', '0x558d61e75f90']
group: 1
visible: 0
level: 0
name: 'root'
color: None
prefix: None
prefix_color: None
item 3:
__path: ['0x558d62a9cea0', '0x558d62abf2e0']
group: 1
visible: 0
level: 0
name: 'root'
color: None
prefix: None
prefix_color: None
item 4:
__path: ['0x558d62a9cea0', '0x558d62afb9d0']
group: 1
visible: 1
level: 1
name: '000|o'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 5:
__path: ['0x558d62a9cea0', '0x558d62aff930']
group: 0
visible: 1
level: 0
name: 'FlashCode'
color: 'weechat.color.chat_nick_self'
prefix: '@'
prefix_color: 'lightgreen'
item 6:
__path: ['0x558d62a9cea0', '0x558d62af9930']
group: 1
visible: 1
level: 1
name: '001|v'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 7:
__path: ['0x558d62a9cea0', '0x558d62afc510']
group: 1
visible: 1
level: 1
name: '999|...'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 8:
__path: ['0x558d62a9cea0', '0x558d6292c290']
group: 0
visible: 1
level: 0
name: 'flashy'
color: '142'
prefix: ' '
prefix_color: 'lightblue'
item 9:
__path: ['0x558d62914680', '0x558d62afc4b0']
group: 1
visible: 0
level: 0
name: 'root'
color: None
prefix: None
prefix_color: None
-
Захтев листе надимака за бафер „irc.libera.#weechat”:
(nicklist_weechat) nicklist irc.libera.#weechat
Одговор:
id: 'nicklist_weechat'
hda:
keys: {
'group': 'chr',
'visible': 'chr',
'level': 'int',
'name': 'str',
'color': 'str',
'prefix': 'str',
'prefix_color': 'str',
}
path: ['buffer', 'nicklist_item']
item 1:
__path: ['0x558d62a9cea0', '0x558d62abf2e0']
group: 1
visible: 0
level: 0
name: 'root'
color: None
prefix: None
prefix_color: None
item 2:
__path: ['0x558d62a9cea0', '0x558d62afb9d0']
group: 1
visible: 1
level: 1
name: '000|o'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 3:
__path: ['0x558d62a9cea0', '0x558d62aff930']
group: 0
visible: 1
level: 0
name: 'FlashCode'
color: 'weechat.color.chat_nick_self'
prefix: '@'
prefix_color: 'lightgreen'
item 4:
__path: ['0x558d62a9cea0', '0x558d62af9930']
group: 1
visible: 1
level: 1
name: '001|v'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 5:
__path: ['0x558d62a9cea0', '0x558d62afc510']
group: 1
visible: 1
level: 1
name: '999|...'
color: 'weechat.color.nicklist_group'
prefix: None
prefix_color: None
item 6:
__path: ['0x558d62a9cea0', '0x558d6292c290']
group: 0
visible: 1
level: 0
name: 'flashy'
color: '142'
prefix: ' '
prefix_color: 'lightblue'
3.7. input
Слање података у бафер.
Синтакса:
(id) input <бафер> <подаци>
Аргументи:
-
бафер: показивач (нпр.: „0x1234abcd”) или пуно име бафера (на пример: core.weechat или irc.libera.#weechat)
-
подаци: подаци који се шаљу у бафер: ако почињу са
/
, онда ће се извршити као команда у баферу, у супротном се текст шаље као унос у бафер
Примери:
-
Слање команде „/help filter” у WeeChat бафер језгра:
input core.weechat /help filter
-
Слање поруке „здраво!” на #weechat канал:
input irc.libera.#weechat здраво!
-
Шаље вишелинијску поруку на #test канал (опција escape_commands мора да буде укључена у handshake команди и потребан је WeeChat ≥ 4.0.0):
input irc.ergo.#test this message has\n2 lines
3.8. completion
WeeChat ≥ 2.9.
Захтев за довршавање стринга: листа могућих речи на датој позицији у стрингу за дати бафер.
Синтакса:
(id) completion <бафер> <позиција> [<подаци>]
Аргументи:
-
бафер: показивач (нпр.: „0x1234abcd”) или пуно име бафера (на пример: core.weechat или irc.libera.#weechat)
-
позиција: позиција за довршавање у стрингу (почиње од 0); ако је вредност -1, позиција представља дужину подаци (тако да се довршавање ради на крају подаци)
-
подаци: улазни стринг; ако се не наведе, довршавање се ради за празан стринг
Програм WeeChat одговара са hdata:
Име | Тип | Опис |
---|---|---|
|
стринг |
Контекст довршавања: „null” (без довршавања), „command”, „command_arg”, „auto”. |
|
стринг |
Базна реч која се користи за довршавање. |
|
цео број |
Индекс првог карактера који се замењује (почиње од 0). |
|
цео број |
Индекс последњег карактера који се замењује (почиње од 0). |
|
цео број |
1 ако након речи треба додати размак, 0 у супротном. |
|
низ стрингова |
Листа речи; празна ако ништа није пронађено за довршавање на траженој позицији. |
У случају грешке, на пример за неважећи бафер или интерну грешку на страни програма WeeChat, враћа се празан hdata. |
Примери:
-
Довршавање аргумента команде:
(completion_help) completion core.weechat -1 /help fi
Одговор:
id: 'completion_help'
hda:
keys: {
'context': 'str',
'base_word': 'str',
'pos_start': 'int',
'pos_end': 'int',
'add_space': 'int',
'list': 'arr',
}
path: ['completion']
item 1:
__path: ['0x55d0ccc842c0']
context: 'command_arg'
base_word: 'fi'
pos_start: 6
pos_end: 7
add_space: 0
list: [
'fifo',
'fifo.file.enabled',
'fifo.file.path',
'filter',
]
-
Довршавање команде у средини речи:
(completion_query) completion core.weechat 5 /quernick
Одговор:
id: 'completion_query'
hda:
keys: {
'context': 'str',
'base_word': 'str',
'pos_start': 'int',
'pos_end': 'int',
'add_space': 'int',
'list': 'arr',
}
path: ['completion']
item 1:
__path: ['0x55d0ccc88470']
context: 'command'
base_word: 'quer'
pos_start: 1
pos_end: 4
add_space: 1
list: ['query']
-
Ништа за довршавање:
(completion_abcdefghijkl) completion core.weechat -1 abcdefghijkl
Одговор:
id: 'completion_abcdefghijkl'
hda:
keys: {
'context': 'str',
'base_word': 'str',
'pos_start': 'int',
'pos_end': 'int',
'add_space': 'int',
'list': 'arr',
}
path: ['completion']
item 1:
__path: ['0x55d0ccc88470']
context: 'auto'
base_word: 'abcdefghijkl'
pos_start: 0
pos_end: 11
add_space: 1
list: []
-
Довршавање у неважећем баферу:
(completion_help) completion buffer.does.not.exist -1 /help fi
Одговор:
id: 'completion_help'
hda:
keys: {}
path: ['completion']
3.9. sync
Ажурирано у верзији 0.4.1.
Синхронизација једног или више бафера, да би се примиле измене у баферу.
Препоручује се да се ова команда пошаље непосредно након што потражите податке из бафера (линије, …). Може да се пошаље и у истој поруци (након карактера за прелом реда: „\n”). |
Синтакса:
(id) sync [<бафер>[,<бафер>...] <опција>[,<опција>...]]
Аргументи:
-
бафер: показивач (нпр: „0x1234abcd”) или пуно име бафера (на пример: core.weechat или irc.libera.#weechat); за навођење свих бафера може да се употреби име „*”
-
опције: једна од следећих кључних речи, раздвојених запетама (подразумевано је buffers,upgrade,buffer,nicklist за „*” и buffer,nicklist за бафер):
-
buffers: пријем сигнала о баферима (отворен/затворен, премештен, преименован, спојен/раздвојен, скривен/откривен); ово може да се користи само уз име „*” (WeeChat ≥ 0.4.1)
-
upgrade: пријем сигнала о ажурирању програма WeeChat (ажурирање, ажурирање завршено); ово може да се користи само уз име „*” (WeeChat ≥ 0.4.1)
-
buffer: пријем сигнала о баферу (нове линије, промењен тип, промењен наслов, додата/уклоњена локална променљива и исти сигнали као код buffers за бафер) (ажурирано у верзији 0.4.1)
-
nicklist: пријем листе надимака након промена
-
Примери:
-
Синхронизација свих бафера са листом надимака (3 команде су еквивалентне, али се препоручује употреба прве из разлога компатибилности са будућим верзијама):
sync sync * sync * buffers,upgrade,buffer,nicklist
-
Синхронизација WeeChat бафера језгра:
sync core.buffer
-
Синхронизација #weechat канала, без листе надимака:
sync irc.libera.#weechat buffer
-
Пријем општих сигнала + свих сигнала за канал #weechat:
sync * buffers,upgrade sync irc.libera.#weechat
3.10. desync
Ажурирано у верзији 0.4.1.
Десинхронизација једног или више бафера, како би се прекинуло праћење измена.
Ово ће уклонити опције за бафере. Ако су неке опције још увек активне за бафере, клијент ће за те бафере наставити да прима ажурирања. |
Синтакса:
(id) desync [<бафер>[,<бафер>...] <опција>[,<опција>...]]
Аргументи:
-
бафер: показивач (нпр: „0x1234abcd”) или пуно име бафера (на пример: core.weechat или irc.libera.#weechat); за навођење свих бафера може да се употреби име „*”
-
опције: једна од следећих кључних речи, раздвојене запетама (подразумевано је buffers,upgrade,buffer,nicklist за „*” и buffer,nicklist за бафер); погледајте команду sync за вредности
Када се користи бафер „*”, остали синхронизовани бафери се задржавају (употребом имена). Тако да ако пошаљете: „sync *”, па затим „sync irc.libera.#weechat”, па затим „desync *”, програм WeeChat ће наставити да шаље измене канала #weechat (морате експлицитно да га уклоните ако желите да зауставите слања ажурирања). |
Примери:
-
Десинхронизација свих бафера (3 команде су еквивалентне, али се препоручује употреба прве из разлога компатибилности са будућим верзијама):
desync desync * desync * buffers,upgrade,buffer,nicklist
-
Десинхронизација листе надимака за канал #weechat (остају ажурирања бафера):
desync irc.freenode.#weechat nicklist
-
Десинхронизација #weechat канала:
desync irc.libera.#weechat
3.11. test
Тест команда: програм WeeChat ће вратити одговор са различитим објектима.
Ова команда је корисна за тестирање декодирања бинарних објеката које враћа програм WeeChat.
Синтакса:
(id) test
Враћају се следећи објекти (у наведеном редоследу):
Тип | Опис | Вредност |
---|---|---|
|
карактер |
|
|
целобројни |
|
|
целобројни |
|
|
дугачки |
|
|
дугачки |
|
|
стринг |
|
|
стринг |
|
|
стринг |
|
|
бафер |
|
|
бафер |
|
|
показивач |
|
|
показивач |
|
|
време |
|
|
низ стрингова |
|
|
низ целобројних |
|
Не смете да користите вредности показивача које врати ова команда, оне нису исправне. Ова команда сме да се користи само за тестирање декодирања поруке коју шаље програм WeeChat. |
Пример:
(test) test
Одговор:
id: 'test' chr: 65 int: 123456 int: -123456 lon: 1234567890 lon: -1234567890 str: 'a string' str: '' str: None buf: 'buffer' buf: None ptr: '0x1234abcd' ptr: '0x0' tim: 1321993456 arr: ['abc', 'de'] arr: [123, 456, 789]
3.12. ping
WeeChat ≥ 0.4.2.
Шаље пинг програму WeeChat који ће одговорити поруком „_pong” и истим аргументима.
Ова команда је корисна за проверу да ли је веза са програмом WeeChat и даље успостављена и за мерење времена одговора.
Синтакса:
(id) ping [<аргументи>]
Пример:
ping 1370802127000
Одговор:
id:'_pong' str: '1370802127000'
4. Поруке (релеј → клијент)
Поруке се шаљу као бинарни подаци, употребом следећег формата (са величином у бајтовима):
┌────────╥─────────────╥─────────╥────────┬──────────╥───────╥────────┬──────────┐ │ дужина ║ компресија ║ id ║ тип 1 │ објект 1 ║ ... ║ тип N │ објект N │ └────────╨─────────────╨─────────╨────────┴──────────╨───────╨────────┴──────────┘ └──────┘ └───────────┘ └───────┘ └──────┘ └────────┘ └──────┘ └────────┘ 4 1 4 + str 3 ?? 3 ?? └────────────────────┘ └───────────────────────────────────────────────────────┘ заглавље (5) компесовани подаци (??) └──────────────────────────────────────────────────────────────────────────────┘ 'length' bytes
-
дужина (неозначени цео број, 4 бајта): број бајтова у целој поруци (заједно са овим пољем)
-
компресија (бајт): заставица:
-
0x00: подаци који следе нису компресовани
-
0x01: подаци који следе су компресовани са zlib ↗
-
0x02: подаци који следе су компресовани са Zstandard ↗
-
-
id (стринг, 4 бајта + садржај): идентификатор који послао клијент (пре имена команде); може бити и празан (стринг дужине нула и без садржаја) ако у команди није био наведен идентификатор
-
тип (3 карактера): тип: 3 слова (погледајте табелу испод)
-
објект: објекат (погледајте табелу испод)
4.1. Компресија
Ако заставица compression има вредност 0x01 или 0x02, онда се сви подаци након ње компресују са zlib ↗ или Zstandard ↗, па стога морају бити некомпресовани пре обраде.
4.2. Идентификатор
Постоје два типа идентификатора (id):
-
id који је послао клијент: релеј ће у свој одговор поставити овај исти id
-
id догађаја: приликом неких догађаја, релеј ће клијенту послати поруку користећи одређени id који почиње са доњом цртом (погледајте табелу испод)
WeeChat резервисани идентификатори:
Идентификатор | Примљен са sync | Послати подаци | Опис | Препоручена акција у клијенту |
---|---|---|---|---|
|
buffers / buffer |
hdata: buffer |
Бафер је отворен. |
Отварање бафера. |
|
buffers / buffer |
hdata: buffer |
Промењен је тип бафера. |
Измена типа бафера. |
|
buffers / buffer |
hdata: buffer |
Buffer је премештен. |
Премештање бафера. |
|
buffers / buffer |
hdata: buffer |
Buffer је спојен. |
Спајање бафера. |
|
buffers / buffer |
hdata: buffer |
Бафер је раздвојен. |
Раздвајање бафера. |
|
buffers / buffer |
hdata: buffer |
Бафер је сакривен. |
Скривање бафера. |
|
buffers / buffer |
hdata: buffer |
Бафер је откривен. |
Откривање бафера. |
|
buffers / buffer |
hdata: buffer |
Баферу је промењено име. |
Промена имена бафера. |
|
buffers / buffer |
hdata: buffer |
Промењен је наслов бафера. |
Промена наслова бафера. |
|
buffers / buffer |
hdata: buffer |
Додата је локална променљива. |
Додавање локалне променљиве. |
|
buffers / buffer |
hdata: buffer |
Локална променљива је измењена. |
Измена локалне променљиве у баферу. |
|
buffers / buffer |
hdata: buffer |
Уклоњена је локална променљива. |
Уклањање локалне променљиве из бафера. |
|
buffers / buffer |
hdata: buffer |
Бафер је затворен. |
Затварање бафера. |
|
buffer |
hdata: buffer |
Бафер је очишћен. |
Чишћење бафера. |
|
buffer |
hdata: line |
У бафер је додата линија. |
Приказ линије у баферу. |
|
nicklist |
hdata: nicklist_item |
Листа надимака за бафер. |
Замена листе надимака. |
|
nicklist |
hdata: nicklist_item |
Разлике листе надимака за бафер. |
Ажурирање листе надимака. |
|
(always) |
стринг: ping аргументи |
Одговор на „ping”. |
Мерење времена одговора. |
|
upgrade |
(празно) |
Програм WeeChat се ажурира. |
Десинхронизација са програмом WeeChat (или прекид везе). |
|
upgrade |
(празно) |
Завршено је ажурирање програма WeeChat. |
Синхро/ресинхро са програмом WeeChat. |
_buffer_opened
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_opened”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
стринг |
Кратко име (пример: #weechat). |
|
целобројни |
1 ако бафер има листу надимака, у супротном 0. |
|
стринг |
Наслов бафера. |
|
хештабела |
Локалне променљиве. |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: приступљено каналу #weechat на libera, нови бафер irc.libera.#weechat:
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.libera.#weechat'
short_name: None
nicklist: 0
title: None
local_variables: {
'plugin': 'irc',
'name': 'libera.#weechat',
}
prev_buffer: '0x34e7400'
next_buffer: '0x0'
_buffer_moved
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_moved”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: бафер irc.libera.#weechat је померен на број 2:
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.libera.#weechat'
prev_buffer: '0x347b9f0'
next_buffer: '0x3471bc0'
_buffer_merged
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_merged”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: бафер irc.libera.#weechat је спојен са бафером #2:
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.libera.#weechat'
prev_buffer: '0x4cef9b0'
next_buffer: '0x0'
_buffer_unmerged
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_unmerged”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: бафер irc.libera.#weechat је раздвојен:
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.libera.#weechat'
prev_buffer: '0x4cef9b0'
next_buffer: '0x0'
_buffer_hidden
WeeChat ≥ 1.0.
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_hidden”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: бафер irc.libera.#weechat је скривен:
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.libera.#weechat'
prev_buffer: '0x4cef9b0'
next_buffer: '0x0'
_buffer_unhidden
WeeChat ≥ 1.0.
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_unhidden”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
показивач |
Показивач на претходни бафер. |
|
показивач |
Показивач на наредни бафер. |
Пример: бафер irc.libera.#weechat је откривен:
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.libera.#weechat'
prev_buffer: '0x4cef9b0'
next_buffer: '0x0'
_buffer_renamed
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_renamed”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера(≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
стринг |
Кратко име (пример: #weechat). |
|
хештабела |
Локалне променљиве. |
Пример: име приватног бафера је промењено са FlashCode у Flash2:
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.libera.Flash2'
short_name: 'Flash2'
local_variables: {
'server': 'libera',
'plugin': 'irc',
'type': 'private',
'channel': 'FlashCode',
'nick': 'test',
'name': 'libera.Flash2',
}
_buffer_title_changed
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_title_changed”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
стринг |
Наслов бафера. |
Пример: измењена је тема на каналу #weechat:
id: '_buffer_title_changed'
hda:
keys: {
'number': 'int',
'full_name': 'str',
'title': 'str',
}
path: ['buffer']
item 1:
__path: ['0x4a715d0']
number: 3
full_name: 'irc.libera.#weechat'
title: 'Welcome on #weechat! https://weechat.org/'
_buffer_cleared
WeeChat ≥ 1.0.
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_cleared”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
Пример: очишћен је бафер irc.libera.#weechat:
id: '_buffer_cleared'
hda:
keys: {
'number': 'int',
'full_name': 'str',
}
path: ['buffer']
item 1:
__path: ['0x4a715d0']
number: 3
full_name: 'irc.libera.#weechat'
_buffer_type_changed
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_type_changed”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
целобројни |
Тип бафера: 0 = форматирани (подраз.), 1 = слободни садржај. |
Пример: промењен је тип бафера script.scripts са форматирани (0) на слободни садржај (1):
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
_buffer_localvar_added
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_localvar_added”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
хештабела |
Локалне променљиве. |
Пример: локална променљива test је додата у бафер irc.libera.#weechat:
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.libera.#weechat'
local_variables: {
'server': 'libera',
'test': 'value',
'plugin': 'irc',
'type': 'channel',
'channel': '#weechat',
'nick': 'test',
'name': 'libera.#weechat',
}
_buffer_localvar_changed
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_localvar_changed”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
хештабела |
Локалне променљиве. |
Пример: ажурирана је локална променљива test у баферу irc.libera.#weechat:
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.libera.#weechat'
local_variables: {
'server': 'local',
'test': 'value2',
'plugin': 'irc',
'type': 'channel',
'channel': '#weechat',
'nick': 'test',
'name': 'libera.#weechat',
}
_buffer_localvar_removed
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_localvar_removed”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
|
хештабела |
Локалне променљиве. |
Пример: локална променљива test је уклоњена из бафера irc.libera.#weechat:
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.libera.#prout'
local_variables: {
'server': 'local',
'plugin': 'irc',
'type': 'channel',
'channel': '#weechat',
'nick': 'test',
'name': 'libera.#weechat',
}
_buffer_line_added
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_line_added”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
показивач |
Показивач на бафер. |
|
време |
Датум поруке. |
|
цео број |
Микросекунде датума. |
|
време |
Датум када је програм WeeChat приказао поруку. |
|
цео број |
Микросекунде датума када је WeeChat приказао поруку. |
|
карактер |
1 ако је порука приказана, 0 ако је порука филтрирана (скривена). |
|
карактер |
Ниво обавештења: -1 = обавештење искључено, 0 = ниски, 1 = порука, 2 = приватно, 3 = истицање. |
|
карактер |
1 ако се у линији налази истицање, у супротном 0. |
|
низ стрингова |
Листа ознака за линију. |
|
стринг |
Префикс. |
|
стринг |
Порука. |
Пример: нова порука здраво! од надимка FlashCode у баферу irc.libera.#weechat:
id: '_buffer_line_added'
hda:
keys: {
'buffer': 'ptr',
'date': 'tim',
'date_usec': 'int',
'date_printed': 'tim',
'date_usec_printed': 'int',
'displayed': 'chr',
'notify_level': 'chr',
'highlight': 'chr',
'tags_array': 'arr',
'prefix': 'str',
'message': 'str',
}
path: ['line_data']
item 1:
__path: ['0x4a49600']
buffer: '0x4a715d0'
date: 1362728993
date_usec: 902765
date_printed: 1362728993
date_usec_printed: 902765
displayed: 1
notify_level: 1
highlight: 0
tags_array: [
'irc_privmsg',
'notify_message',
'prefix_nick_142',
'nick_FlashCode',
'log1',
]
prefix: 'F06@F@00142FlashCode'
message: 'здраво!'
_buffer_closing
Ова порука се шаље клијенту када програм WeeChat пошаље сигнал „buffer_closing”.
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
целобројни |
Број бафера (≥ 1). |
|
стринг |
Пуно име (пример: irc.libera.#weechat). |
Пример: програм WeeChat затвара бафер irc.libera.#weechat:
id: '_buffer_closing'
hda:
keys: {
'number': 'int',
'full_name': 'str',
}
path: ['buffer']
item 1:
__path: ['0x4a715d0']
number: 3
full_name: 'irc.libera.#weechat'
_nicklist
Ова порука се шаље клијенту када се над листом надимака догађају велика ажурирања (групе/надимци се додају/уклањају/мењају). Порука садржи комплетну листу надимака.
Када се над листом надимака обављају мала ажурирања (додаје се, на пример, само један нови надимак), шаље се још једна порука са идентификатором _nicklist_diff (погледајте испод).
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
карактер |
1 за групу, 0 за надимак. |
|
карактер |
1 ако се група/надимак приказује, у супротном 0. |
|
целобројни |
Ниво групе (0 за надимак). |
|
стринг |
Име групе/надимка. |
|
стринг |
Боја имена. |
|
стринг |
Префикс (само за надимак). |
|
стринг |
Боја префикса (само за надимак). |
Пример: листа надимака за бафер irc.libera.#weechat:
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: ''
_nicklist_diff
WeeChat ≥ 0.4.1.
Ова порука се шаље клијенту када се над листом надимака врши мало ажурирање (групе/надимци се додају/уклањају/мењају). Порука садржи разлику листе надимака (између старе и текуће листе надимака).
Подаци се шаљу као hdata:
Име | Тип | Опис |
---|---|---|
|
карактер |
Тип diff-а (погледајте испод). |
|
карактер |
1 за групу, 0 за надимак. |
|
карактер |
1 ако се група/надимак приказује, у супротном 0. |
|
целобројни |
Ниво групе (0 за надимак). |
|
стринг |
Име групе/надимка. |
|
стринг |
Боја имена. |
|
стринг |
Префикс (само за надимак). |
|
стринг |
Боја префикса (само за надимак). |
Вредност _diff може бити:
-
^
: родитељска група: груп(а/е) или надим(ак/ци) након овог су у вези са овом групом -
+
: група/надимак се додаје у родитељску групу -
-
: група/надимак се уклања из родитељске групе -
*
: група/надимак је ажуриран у родитељској групи
Примр: надимак master је додат у групу 000|o (опови неког IRC канала) надимци nick1 и nick2 су додати у групу 999|… (стандардни корисници IRC канала):
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: ''
_pong
WeeChat ≥ 0.4.2.
Ова порука се шаље клијенту када релеј прими „ping” поруку.
Подаци који се шаљу као стринг: аргументи примљени у „ping” поруци.
Препоручена акција у клијенту је да измери време одговора и да прекине везу ако је оно сувише велико.
_upgrade
WeeChat ≥ 0.3.8.
Ова порука се шаље клијенту када програм WeeChat покрене процес ажурирања.
У овој поруци нема података.
Препоручена акција у клијенту је да се десинхронизује са програмом WeeChat (да пошаље команду desync), или да прекине везу са програмом WeeChat (јер ће се након ажурирања променити вредности свих показивача).
Током ажурирања програма WeeChat, сокет остаје отворен (осим у случају када веза користи TLS). |
4.3. Објекти
Објекти се идентификују са 3 слова, која се зову тип. Користе се следећи типови:
Тип | Вредност | Дужина |
---|---|---|
|
Означени карактер |
1 бајт |
|
Означени целобројни |
4 бајта |
|
Означени дугачки целобројни |
1 бајт + дужина целобројног као стринг |
|
Стринг |
4 бајта + дужина стринга (без завршног |
|
Бафер бајтова |
4 бајта + дужина података |
|
Показивач |
1 бајт + дужина показивача као стринг |
|
Време |
1 бајт + дужина времена као стринг |
|
Хештабела |
Променљива |
|
Садржај Hdata |
Променљива |
|
Инфо: име + садржај |
Променљива |
|
Садржај Инфолисте |
Променљива |
|
Низ објеката |
3 бајта (тип) + број објеката + подаци |
Целобројни
Означена целобројна вредност се чува као 4 бајта, кодираних у big-endian формату (најпре долази бајт највеће тежине).
Опсег: -2147483648 до 2147483647.
Примери:
┌────┬────┬────┬────┐ │ 00 │ 01 │ E2 │ 40 │ ────► 123456 └────┴────┴────┴────┘ ┌────┬────┬────┬────┐ │ FF │ FE │ 1D │ C0 │ ────► -123456 └────┴────┴────┴────┘
Дугачки целобројни
Означена дугачка целобројна вредност се кодира као стринг, са дужином у једном бајту.
Опсег: -9223372036854775808 до 9223372036854775807.
Примери:
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0A ║ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► 1234567890 └────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ └──┘ └───────────────────────────────────────────────┘ дужина '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' ┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0B ║ 2D │ 31 │ 32 │ 33 │ 34 │ 35 │ 36 │ 37 │ 38 │ 39 │ 30 │ ────► -1234567890 └────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ └──┘ └────────────────────────────────────────────────────┘ дужина '-' '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'
Стринг
Стринг је дужина (цео број дужине 4 бајтова) + садржај стринга (без завршног \0
).
Пример:
┌────┬────┬────┬────╥────┬────┬────┬────┬────┐ │ 00 │ 00 │ 00 │ 05 ║ 68 │ 65 │ 6C │ 6C │ 6F │ ────► "hello" └────┴────┴────┴────╨────┴────┴────┴────┴────┘ └─────────────────┘ └──────────────────────┘ дужина 'h' 'e' 'l' 'l' 'o'
Празан стринг има дужину нула:
┌────┬────┬────┬────┐ │ 00 │ 00 │ 00 │ 00 │ ────► "" └────┴────┴────┴────┘ └─────────────────┘ дужина
NULL стринг (NULL показивач у C) има дужину -1:
┌────┬────┬────┬────┐ │ FF │ FF │ FF │ FF │ ────► NULL └────┴────┴────┴────┘ └─────────────────┘ дужина
Бафер
Исти формат као и стринг; садржај је прости низ бајтова.
Показивач
Показивач је кодиран као стринг (хекс), са дужином у једном бајту.
Пример:
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 09 ║ 31 │ 61 │ 32 │ 62 │ 33 │ 63 │ 34 │ 64 │ 35 │ ────► 0x1a2b3c4d5 └────╨────┴────┴────┴────┴────┴────┴────┴────┴────┘ └──┘ └──────────────────────────────────────────┘ дужина '1' 'a' '2' 'b' '3' 'c' '4' 'd' '5'
NULL показивач има дужину 1 и вредност 0:
┌────╥────┐ │ 01 ║ 30 │ ────► NULL (0x0) └────╨────┘ └──┘ └──┘ дужина '0'
Време
Време (број секунди) се кодира као стринг, са дужином у једном бајту.
Пример:
┌────╥────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0A ║ 31 │ 33 │ 32 │ 31 │ 39 │ 39 │ 33 │ 34 │ 35 │ 36 │ ────► 1321993456 └────╨────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ └──┘ └───────────────────────────────────────────────┘ дужина '1' '3' '2' '1' '9' '9' '3' '4' '5' '6'
Хештабела
Хештабела садржи тип кључева, вип вредности, број ставки у хеш табели ( целобројна вредност дужине 4 бајта), па затим ставке кључева и вредности.
┌───────────┬───────────────┬───────╥───────┬────────╥─────╥───────┬────────┐ │ тип_кључа │ тип_вредности │ број ║ кључ1 │ вредн1 ║ ... ║ кључN │ вреднN │ └───────────┴───────────────┴───────╨───────┴────────╨─────╨───────┴────────┘
Пример:
┌─────┬─────┬───╥──────┬─────╥──────┬─────┐ │ str │ str │ 2 ║ key1 │ abc ║ key2 │ def │ ────► { 'key1' => 'abc', └─────┴─────┴───╨──────┴─────╨──────┴─────┘ 'key2' => 'def' } └───┘ └───┘ └─┘ └──────────┘ └──────────┘ тип тип број ставка 1 ставка 2 кључа вредн
Hdata
hdata садржи путању са hdata именима, листу кључева, број скупа објеката, па затим скуп објеката (путања са показивачима, затим објекти).
┌────────┬──────┬───────╥────────┬─────────────────────╥─────╥────────┬─────────────────────╥─────┐ │ h-пут │ кључ │ број ║ p-пут │ вредн 1 ... вредн N ║ ... ║ p-пут │ вредн 1 ... вредн N ║ ... │ └────────┴──────┴───────╨────────┴─────────────────────╨─────╨────────┴─────────────────────╨─────┘
-
h-пут (стринг): путања која се користи за приступ подацима (пример: buffer/lines/line/line_data); враћа се hdata последњег елемента у путањи
-
кључ (стринг): стринг са листом кључ:тип (раздвојених запетама), пример: number:int,name:str
-
број (целобројни): број скупа објеката
-
p-пут: путања са показивачима на објекте (овде је број показивача број елемената у путањи)
-
вредн: листа вредности (број вредности је број кључева који се врати за hdata)
Пример за hdata са два бафера (weechat бафер језгра и libera серверски бафер) и два кључа (number и full_name):
# команда hdata buffer:gui_buffers(*) number,full_name # одговор ┌────────┬──────────────────────────┬───╥─────────┬───┬──────────────╥─────────┬───┬─────────────────────┐ │ buffer │ number:int,full_name:str │ 2 ║ 0x12345 │ 1 │ core.weechat ║ 0x6789a │ 2 │ irc.server.libera │ └────────┴──────────────────────────┴───╨─────────┴───┴──────────────╨─────────┴───┴─────────────────────┘ └──────┘ └────────────────────────┘ └─┘ └──────────────────────────┘ └─────────────────────────────────┘ h-пут кључеви број бафер 1 бафер 2
Пример за hdata са линијама бафера језгра:
# команда hdata buffer:gui_buffers(*)/lines/first_line(*)/data # одговор ┌─────────────────────────────┬─────┬────╥── │ buffer/lines/line/line_data │ ... │ 50 ║ ... └─────────────────────────────┴─────┴────╨── └───────────────────────────┘ └───┘ └──┘ h-пут (hdata имена) кључ број ──╥───────────┬───────────┬───────────┬───────────┬───────╥── ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d5f40 │ 0x23d8a10 │ ..... ║ ... ──╨───────────┴───────────┴───────────┴───────────┴───────╨── └─────────────────────────────────────────────┘ └─────┘ p-пут (показивачи) објекти └─────────────────────────────────────────────────────┘ линија 1 ──╥───────────┬───────────┬───────────┬───────────┬───────╥──────────────┐ ... ║ 0x23cf970 │ 0x23cfb60 │ 0x23d6110 │ 0x23d9420 │ ..... ║ ............ │ ──╨───────────┴───────────┴───────────┴───────────┴───────╨──────────────┘ └─────────────────────────────────────────────┘ └─────┘ p-пут (показивачи) објекти └─────────────────────────────────────────────────────┘ └────────────┘ линија 2 линије 3-50
Пример за hdata са листом надимака:
# команда nicklist # одговор ┌───────────────────┬── │ buffer/nick_group │ ... └───────────────────┴── └─────────────────┘ h-пут ──╥───────────────────────────────────────────────────────────┬────╥── ... ║ group:chr,visible:chr,name:str,color:str,prefix:str,(...) │ 12 ║ ... ──╨───────────────────────────────────────────────────────────┴────╨── └─────────────────────────────────────────────────────────┘ └──┘ кључеви број ──╥─────────┬─────────┬───┬───┬──────┬─┬─┬─┬───╥── ... ║ 0x12345 │ 0x6789a │ 1 │ 0 │ root │ │ │ │ 0 ║ ... ──╨─────────┴─────────┴───┴───┴──────┴─┴─┴─┴───╨── └─────────────────┘ └──────────────────────┘ p-пут објекти └──────────────────────────────────────────┘ група (корен листе надимака) ──╥─────────┬─────────┬───┬───┬───────┬─┬─┬─┬───╥── ... ║ 0x123cf │ 0x678d4 │ 1 │ 0 │ 000|o │ │ │ │ 1 ║ ... ──╨─────────┴─────────┴───┴───┴───────┴─┴─┴─┴───╨── └─────────────────┘ └───────────────────────┘ p-пут објекти └───────────────────────────────────────────┘ група (опови канала) ──╥─────────┬─────────┬───┬───┬──────────┬──────┬───┬────────────┬───╥── ... ║ 0x128a7 │ 0x67ab2 │ 0 │ 1 │ ChanServ │ blue │ @ │ lightgreen │ 0 ║ ... ──╨─────────┴─────────┴───┴───┴──────────┴──────┴───┴────────────┴───╨── └─────────────────┘ └────────────────────────────────────────────┘ p-пут објекти └────────────────────────────────────────────────────────────────┘ надимак (@ChanServ)
Пример за празан hdata (врућа листа у програму WeeChat је празна):
# команда hdata hotlist:gui_hotlist(*) # одговор ┌────────┬────────┬───┐ │ (NULL) │ (NULL) │ 0 │ └────────┴────────┴───┘ └──────┘ └──────┘ └─┘ h-пут кључеви број
Инфо
инфо садржи име и вредност (оба су стрингови).
┌─────┬──────────┐ │ име │ вредност │ └─────┴──────────┘
-
име (стринг): име инфо
-
вредност (стринг): вредност
Пример за version инфо:
┌─────────┬───────────────────┐ │ верзија │ WeeChat 0.3.7-dev │ └─────────┴───────────────────┘
Инфолиста
инфолиста садржи име, број ставки, па затим ставке (скуп променљивих).
┌─────┬──────╥──────────╥─────╥──────────┐ │ име │ број ║ ставка 1 ║ ... ║ ставка N │ └─────┴──────╨──────────╨─────╨──────────┘
Ставка је:
┌──────╥───────┬───────┬────────────╥─────╥───────┬───────┬────────────┐ │ број ║ име 1 │ тип 1 │ вредност 1 ║ ... ║ име N │ тип N │ вредност N │ └──────╨───────┴───────┴────────────╨─────╨───────┴───────┴────────────┘
-
име (стринг): име инфолисте (buffer, window, bar, …)
-
број (целобројни): број ставки
-
ставка:
-
број: број променљивих у ставки
-
име: име променљиве
-
тип: тип променљиве (int, str, …)
-
вредност: вредност променљиве
-
Пример инфолисте са два бафера (weechat бафер језгра и libera серверски бафер):
# команда infolist buffer # одговор ┌────────┬───╥────┬─────────┬─────┬─────────┬─────╥────┬─────────┬─────┬─────────┬─────┐ │ buffer │ 2 ║ 42 │ pointer │ ptr │ 0x12345 │ ... ║ 42 │ pointer │ ptr │ 0x6789a │ ... │ └────────┴───╨────┴─────────┴─────┴─────────┴─────╨────┴─────────┴─────┴─────────┴─────┘ └──────┘ └─┘ └──────────────────────────────────┘ └──────────────────────────────────┘ име број ставка 1 ставка 2
Низ
Низ је тип (3 бајта) + број објеката (целобројна вредност дужине 4 бајта) + подаци.
Пример низа са сва стринга:
┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥────┬────┬────╥────┬────┬────┬────╥────┬────┐ │ str ║ 00 │ 00 │ 00 │ 02 ║ 00 │ 00 │ 00 │ 03 ║ 61 │ 62 │ 63 ║ 00 │ 00 │ 00 │ 02 ║ 64 │ 65 │ ────► [ "abc", "de" ] └─────╨────┴────┴────┴────╨────┴────┴────┴────╨────┴────┴────╨────┴────┴────┴────╨────┴────┘ └───┘ └─────────────────┘ └─────────────────┘ └────────────┘ └─────────────────┘ └───────┘ тип број стрингова дужина 'a' 'b' 'c' дужина 'd' 'e'
Пример низа са три целобројне вредности:
┌─────╥────┬────┬────┬────╥────┬────┬────┬────╥────┬────┬────┬────╥────┬────┬────┬────┐ │ int ║ 00 │ 00 │ 00 │ 03 ║ 00 │ 00 │ 00 │ 7B ║ 00 │ 00 │ 01 │ C8 ║ 00 │ 00 │ 03 │ 15 │ ────► [ 123, 456, 789 ] └─────╨────┴────┴────┴────╨────┴────┴────┴────╨────┴────┴────┴────╨────┴────┴────┴────┘ └───┘ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘ тип број целобројних 123 (0x7B) 456 (0x1C8) 789 (0x315)
NULL низ:
┌─────╥────┬────┬────┬────┐ │ str ║ 00 │ 00 │ 00 │ 00 │ ────► NULL └─────╨────┴────┴────┴────┘ └───┘ └─────────────────┘ тип број стрингова
5. Типична сесија
┌─────────┐ ┌───────┐ ┌─────────┐ │ Клијент ├ ─ ─ ─ ─ (мрежа) ─ ─ ─ ─┤ Релеј ├────────────────┤ WeeChat │ └─────────┘ └───────┘ └─────────┘ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ отварање сокета ║ додавање клијента ║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: handshake ... ║ договор алгоритама ║ ║ ║ и опција ║ ║ ◄───────────────────────────────╢ ║ ║ пор: id: "handshake" ... ║ ║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: init password=xxx,... ║ аутентификација клијента║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: hdata buffer ... ╟───────────────────────► ║ ║ sync ... ║ захтев за hdata ║ читање hdata ║ ║ ║ вредности ║ ║ ◄───────────────────────╢ ║ ◄───────────────────────────────╢ hdata ║ креирање ║ пор: hda buffer ║ ║ бафера ║ ║ ║ ║ ........ ║ ........ ║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: input ... ╟───────────────────────► ║ ║ ║ слање података у бафер ║ слање података ║ ║ ║ у бафер ║ ........ ║ ........ ║ ║ ║ ║ примљен је ║ ║ ◄───────────────────────╢ сигнал ║ ◄───────────────────────────────╢ signal XXX ║ (закачио ажурир. ║ пор: id: "_buffer_..." ║ ║ релеј) бафера ║ ║ ║ ║ ........ ║ ........ ║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: ping ... ║ ║ ║ ║ ║ ║ ◄───────────────────────────────╢ ║ мерење ║ пор: id: "_pong" ... ║ ║ времена ║ ║ ║ одговора ║ ........ ║ ........ ║ ║ ║ ║ ╟───────────────────────────────► ║ ║ ║ ком: quit ║ прекид везе са клијентом║ ║ ║ ║