Материал из Tkabber Wiki
Статья ещё не дописана, см. TODO: дописать статью.
Содержание
- 1 Общая информация
- 2 Встроенные команды
- 2.1 /admin nickname ['\n' reason]
- 2.2 /ban nickname ['\n' reason]
- 2.3 /banjid jid ['\n' reason]
- 2.4 /deadmin nickname ['\n' reason]
- 2.5 /demember nickname ['\n' reason]
- 2.6 /demoderator nickname ['\n' reason]
- 2.7 /devoice nickname ['\n' reason]
- 2.8 /disco [jid]
- 2.9 /exec command
- 2.10 /invite jid ['\n' reason]
- 2.11 /join [room [password]]
- 2.12 /kick nickname ['\n' reason]
- 2.13 /last [user]
- 2.14 /leave [status]
- 2.15 /me text
- 2.16 /member nickname ['\n' reason]
- 2.17 /moderator nickname ['\n' reason]
- 2.18 /msg nickname '\n' body
- 2.19 /nick nickname
- 2.20 /open user_a
- 2.21 /part [status]
- 2.22 /ping [user]
- 2.23 /rejoin
- 2.24 /subject [text]
- 2.25 /time [user]
- 2.26 /topic [text]
- 2.27 /unban jid
- 2.28 /vcard [user_b]
- 2.29 /version [user]
- 2.30 /voice nickname ['\n' reason]
- 2.31 /whois nickname
- 3 Ссылки
- 4 TODO: дописать статью
- 5 Немного мыслей о развитии механизма команд
Общая информация
Не все команды имеют «защиту от дурака». В данном списке указаны только разумные наборы параметров. В случае использования другого набора параметров команда может быть отправлена собеседнику (как обычное сообщение), может возникнуть исключение (на уровне интерпретатора tcl), может быть выведено сообщение об ошибке под сообщениями активного окна, может не случиться ничего. Эти ситуации никак не оговариваются в данном списке, поскольку недостатки лучше исправлять, а не документировать.
Аргументы-слова не должны содержать пробельных символов (например, пробела или перевода строки) и должны разделяться строго одним пробелом. В некоторых случаях аргумент представляет собой произвольный текст или текст, не содержащий символа перевода строки. Типы аргументов указаны в описаниях к командам.
Аргументы команд, записанные в квадратных скобках, являются необязательными (т. е. могут присутствовать или не присутствовать в записи команды). Иногда наличие или отсутствие аргумента влияет на семантику команды, например на то, отображается некоторое свойство командой или изменяется.
В окне чата работает автодополнение по клавише Tab. Его можно использовать для дополнения псевдонима участника конференции, команды, аргумента команды и, иногда, чего-нибудь другого (см., например, плагин Juick).
Для формалистов. Текст команд можно воспринимать как запись шаблона команды в форме расширенной БНФ, причём слова, начинающиеся с символа '/', а также '\n' являются терминалами, остальные — нетерминалами, формат нетерминалов определяется типом нетерминала как аргумента. Разделителем между командой и аргументом, а также между аргументами-словами является пробел. Если между идентификаторами (терминалами или нетерминалами) присутствует терминал '\n', то других разделитей не подразумевается.
Встроенные команды
/admin nickname ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
участника активной конференции с псевдонимом
nickname
на “Admin” (если у него менее привилегированный тип членства). Обычно это также подразумевает назначение роли “Moderator”. В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/ban nickname ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
участника активной конференции с псевдонимом
nickname
на “Outcast”, т. е. забанить его (выгнать без возможности вернуться). Бан осуществляется по real JID пользователя, значит последний должен быть известен осуществляющему бан. Участник должен присутствовать в конференции. В запрос включается, если указан, текстreason
. Согласно XEP-0045, передача забаненному участнику и остальным участникам информации о псевдониме или bare JID осуществляющего бан, а также причиныreason
является опциональной. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/banjid jid ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
пользователя с bare JID
jid
на “Outcast”, т. е. внести его в список забаненных и, если он присутствует в конференции, выгнать. В запрос включается, если указан, текстreason
. Согласно XEP-0045, передача забаненному участнику и остальным участникам информации о псевдониме или bare JID осущестляющего бан, а также причиныreason
является опциональной. jid
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/deadmin nickname ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
участника активной конференции с псевдонимом
nickname
на “Member” (если у него более привилегированный тип членства). Обычно это также подразумевает назначение роли “Participant”. В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/demember nickname ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
участника активной конференции с псевдонимом
nickname
на “None” (если у него более привилегированный тип членства). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/demoderator nickname ['\n' reason]
- Активное окно — окно конференции. Сменить роль участника
активной конференции с псевдонимом
nickname
на “Participant” (если у него более привилегированная роль). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.
/devoice nickname ['\n' reason]
- Активное окно — окно конференции. Сменить роль участника
активной конференции с псевдонимом
nickname
на “Visitor” (если у него более привилегированная роль). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.
/disco [jid]
- Открывает окно обзора сервисов для
jid
или, еслиjid
не указан, для собеседника из активного окна. jid
— произвольный текст, справа удаляются пробельные символы.- plugins/chat/disco.tcl
/exec command
Выполнить команду
command
и подставить её вывод или сообщение об ошибке в поле ввода в форме:$
command
output/error message
Синтаксис, вообще говоря, отличается от привычного по совместимым с Bourne Shell командным интерпретаторам. Например, несколько слов, разделённых пробелами или символами перевода строки, объединяются в один аргумент с помощью фигурных скобок, а не кавычек. Подробнее см. в “man n exec”. Можно использовать синтаксис системного командного интерпретатора с помощью такого приёма: “/exec sh -c {some command}”
command
— произвольный текст.- plugins/chat/exec_command.tcl
/invite jid ['\n' reason]
- Пригласить пользователя в конференцию. Текст
reason
, если указан, будет передан вместе с приглашением. - В окне конференции
jid
— это JID приглашаемого. - В окне 1-vs-1 разговора (в том числе приватного разговора через конференцию)
jid
— это JID комнаты, с него приходит приглашение. jid
— произвольный текст, не содержащий символов перевода строки,reason
— произвольный текст, справа удаляются пробельные символы.- plugins/chat/irc_commands.tcl
/join [room [password]]
- Присоединиться к конференции
room
с паролемpassword
или без пароля, если он не указан. - Если активное окно не является окном конференции, то аргумент
room
трактуется как JID конференции. - В случае когда активное окно является окном конференции (на некотором
сервере server), действуют следующие правила. Если аргумент
room
отсутствует, то производится попытка присоединиться к конференции в активном окне. Если аргументroom
присутствует, но не является JID'ом, то производится попытка присоединиться к конференцииroom
@server. В противном случае производится попытка присоединиться к конференции с JID'омroom
. room
— слово,password
— произвольный текст, справа удаляются пробельные символы.- plugins/chat/irc_commands.tcl
/kick nickname ['\n' reason]
- Активное окно — окно конференции. Сменить роль
участника активной конференции с псевдонимом
nickname
на “None”, т. е. выгнать из конференции (участник может вернуться). Участник должен присутствовать в конференции. В запрос включается, если указан, текстreason
. Согласно XEP-0045, передача выгнанному участнику и остальным участникам информации о псевдониме или bare JID выгоняющего, а также причиныreason
является опциональной. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/last [user]
- Запросить информацию о времени с момента последнего подключения, времени бездействия или времени с последнего рестарта сервиса (uptime) в соответствии с XEP-0012. Согласно этому стандарту, если запрос адресован bare JID (localpart@domain.tld), то возвращённый интервал — это время с момента последнего подключения. Если запрос адресован full JID (localpart@domain.tld/resource), то интервал означает время бездействия пользователя. Если запрос адресован серверу или сервису с JID'ом вида domain.tld, то возвращается время с последнего рестарта сервера или сервиса (uptime). Ответ выводится под последним сообщением активного на момент отправки запроса окна.
- Ракрытие аргумента — см. далее.
- Поскольку закладки на конференции в Ткаббере с точки зрения интерфейса пользователя относятся к ростеру, псевдоним или JID конференции обрабатывается так же, как ростерный псевдоним или JID пользователя. При этом конференция, участником которой мы не являемся, обрабатывается как отключённый пользователь. А если мы являемся участником конференции, пользователи конференции обрабатываются как подключённые ресурсы.
user
— произвольный текст.- plugins/chat/info_commands.tcl
Раскрытие аргумента [user]
Для краткости изложения будем указывать bare JID и full JID собеседника (или конференции) как chat_jid и chat_jid/resource соответственно.
Команда /last
в конференции:
- запрос к chat_jid.
Команда /last user
в конференции:
- запрос к chat_jid/user.
Команда /last
в обычном чате:
- chat_jid/resource подключён => запрос к нему (т. е. к chat_jid/resource);
- не подключён, но подключены другие ресурсы => запрос к ним (т. е. к chat_jid/*);
- нет подключённых ресурсов => запрос к chat_jid/resource.
Команда /last user
в обычном чате:
- Есть контакты с псевдонимом
user
; для каждого контакта: запрос ко всем подключённым full JID или если таких нет, то запрос по bare JID. - Если таких контактов нет, то запрос к
user
(подразумевается, чтоuser
должен быть валидным JID'ом).
Сделать: Было бы неплохо проверять, совпадает
ли user
с псевдонимом одного из участников конференции и, если нет, то
попытаться отождествить user
с псевдонимом пользователя из ростера или, если
и это не удалось, делать запрос по JID'у user
. Да и команду было бы неплохо
разбить на две или три более осмысленных, при этом для каждой команды
осуществлять приведению JID'а к необходимому виду, а для uptime — принимать
только обращения по JID'ам вида domain.tld.
/leave [status]
- Закрыть активное окно разговора, если это окно конференции — покинуть её.
Если активным окном является окно конференции, то в информацию об изменении
характера присутствия в конференции в качестве статуса добавляется текст
status
. status
— произвольный текст.- plugins/chat/irc_commands.tcl
/me text
Не является командой в смысле Ткаббера, т. е. не обрабатывается специальным образом при отправке. Но в соответствии с XEP-0245 обрабатывается особым образом при получении. Сообщение, начинающееся с "/me " отобразится в клиентах, соответствующих данному стандарту, будет включать ник отправителя и выглядеть, например, так:
- your_nickname
text
- your_nickname
text
— произвольный текст.
/member nickname ['\n' reason]
- Активное окно — окно конференции. Сменить тип членства
участника активной конференции с псевдонимом
nickname
на “Member” (если у него менее привилегированный тип членства). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.- plugins/chat/muc_commands.tcl
/moderator nickname ['\n' reason]
- Активное окно — окно конференции. Сменить роль участника
активной конференции с псевдонимом
nickname
на “Moderator” (если у него менее привилегированная роль). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.
/msg nickname '\n' body
- Активное окно — окно конференции. Отправить посетителю данной конференции с
псевдонимом
nickname
сообщениеbody
. nickname
— текст без символов перевода строки,body
— произвольный текст.- plugins/chat/irc_commands.tcl
/nick nickname
- Если активное окно является окном конференции, то сменить псевдоним в данной
конференции на
nickname
. nickname
— произвольный текст.- plugins/chat/irc_commands.tcl
/open user_a
- Если аргумент содержит символ '@', то открывается окно разговора с JID'ом
user_a
. - Иначе предпологается, что активное окно является окном конференции, и
открывается окно разговора с участником
user_a
этой конференции. - Сделать: Комментарий "What if conference nickname contains "@"?", кто-нибудь хочет исправить? Думаю, нужно сделать проверку [string equal $type groupchat] как в некоторый командах в irc_commands.tcl.
user_a
— произвольный текст.- plugins/chat/open_chat.tcl
/part [status]
- Полный синоним /leave [status].
status
— произвольный текст.- plugins/chat/irc_commands.tcl
/ping [user]
- Пинг-запрос на прикладном уровне ISO OSI в соответствии с XEP-0199. Запрос адресованный по full JID направляется к клиенту, на запрос по bare JID или по JID'у вида server.tld отвечает соответствующий сервер или сервис. Ответ выводится под последним сообщением активного на момент отправки запроса окна.
- Семантика
user
или его отсутствия — см. /last [user]. user
— произвольный текст.- plugins/chat/info_commands.tcl
/rejoin
- Если активное окно является окном конференции, то покинуть конференцию и присоединиться к ней снова (похоже, что без пароля).
- plugins/chat/irc_commands.tcl
/subject [text]
- Активное окно — окно конференции. Установить в качестве темы конференции
текст
text
. Если аргументtext
не указан — отобразить тему конференции под последним сообщением. text
— произвольный текст.- plugins/chat/irc_commands.tcl
/time [user]
- Запросить информацию о локальном времени и часовом поясе пользователя (см. XEP-0090). В соответствии со стандартом, ответ должен содержать время по UTC, может содержать часовой пояс и время в читаемом формате (видимо, подразумевается локальное время). Ответ выводится под последним сообщением активного на момент отправки запроса окна.
- Семантика
user
или его отсутствия — см. /last [user]. user
— произвольный текст.- plugins/chat/info_commands.tcl
/topic [text]
- Полный синоним /subject [text].
text
— произвольный текст.- plugins/chat/irc_commands.tcl
/unban jid
- Активное окно — окно конференции. Если пользователь с bare JID
jid
присутствует в списке забаненных (т. е. пользователей с типом членства “Outcast”), то сменить тип членства пользователя на “None”. Иначе говоря, разбанить пользователя с bare JIDjid
. jid
— текст без символов перевода строки.- plugins/chat/muc_commands.tcl
/vcard [user_b]
- Запросить VCard пользователя, см. XEP-0054. Ответ выводится под последним сообщением активного на момент отправки запроса окна.
- Раскрытие аргумента — см. далее.
user_b
— произвольный текст.- plugins/chat/info_commands.tcl
Раскрытие аргумента [user_b]
Порядок раскрытия аргумента user_b
(буква b от bare JID) и интерпретации его
отсутствия несколько отличнен от подобного для команды /last [user].
Команда /vcard [user_b]
в конференции: отличий от [user] нет, т. е. запрос к
chat_jid или chat_jid/user_b.
Команда /vcard
в обычном чате:
- запрос к chat_jid.
Команда /vcard user_b
:
- Если
user_b
является псевдонимом одного или нескольких пользователей/конференций из ростера, то запрос будет адресован каждому из них по bare JID. - Если это отождествление не удалось, то запрос будет адресован JID'у
user_b
(даже если это full JID, каким должен быть ответ на такого рода запрос не определяется XEP-0054).
/version [user]
- Запросить информацию о названии и версии клиента пользователя, а также информацию об операционной системе (см. XEP-0092). Согласно этому стандарту, ответ должен содержать название и версию клиента и может содержать информацию об ОС. Ответ выводится под последним сообщением активного на момент отправки запроса окна.
- Семантика
user
или его отсутствия — см. /last [user]. user
— произвольный текст.- plugins/chat/info_commands.tcl
/voice nickname ['\n' reason]
- Активное окно — окно конференции. Сменить роль участника
активной конференции с псевдонимом
nickname
на “Participant” (если у него менее привилегированная роль). В запрос включается, если указан, текстreason
. nickname
— текст без символов перевода строки,reason
— произвольный текст.
/whois nickname
- Активное окно — окно конференции. Вывести информацию о real JID пользователя или сообщение об отсутствии информации о real JID.
nickname
— текст без символов перевода строки.- plugins/chat/muc_commands.tcl
Ссылки
- Про роли и типы членства можно почитать тут (по-русски) или XEP-0045 (с понятными простым смертным таблицами).
TODO: дописать статью
$ ls -1
tkabber
tkabber-contrib
tkabber-plugins
$ for dir in `ls -1`; do (cd $dir; fossil info | grep check-ins:); done
check-ins: 1936
check-ins: 565
check-ins: 632
$ grep -Rin chat_send_message_hook
...skip processed...
tkabber/README:2415: chat_send_message_hook $chatid $user $body $type
tkabber/doc/tkabber.xml:2337:chat_send_message_hook $chatid $user $body $type
tkabber/doc/tkabber.html:1692:chat_send_message_hook $chatid $user $body $type
tkabber/chats.tcl:927: hook::run chat_send_message_hook $chatid $user $body $type
tkabber/chats.tcl:1031: hook::run chat_send_message_hook $chatid [connection_user $xlib] \
tkabber/plugins/chat/muc_ignore.tcl:94: hook::add chat_send_message_hook \
tkabber/plugins/chat/events.tcl:268:hook::add chat_send_message_hook \
tkabber/plugins/chat/history.tcl:45:hook::add chat_send_message_hook [namespace current]::add_body_to_history 12
tkabber/plugins/chat/send_message.tcl:12: if {[hook::is_flag chat_send_message_hook send]} {
tkabber/plugins/chat/send_message.tcl:40: hook::unset_flag chat_send_message_hook send
tkabber/plugins/chat/send_message.tcl:43:hook::add chat_send_message_hook [namespace current]::send_message 90
tkabber/plugins/chat/chatstate.tcl:64:hook::add chat_send_message_hook \
tkabber/plugins/chat/chatstate.tcl:282:hook::add chat_send_message_hook \
tkabber/plugins/chat/shuffle.tcl:112:hook::add chat_send_message_hook \
tkabber/plugins/chat/draw_message.tcl:7: if {$type ne "groupchat" && [hook::is_flag chat_send_message_hook draw]} {
tkabber/plugins/chat/draw_message.tcl:11: hook::unset_flag chat_send_message_hook draw
tkabber/plugins/chat/draw_message.tcl:14:hook::add chat_send_message_hook [namespace current]::draw_message 91
tkabber/plugins/chat/abbrev.tcl:79:hook::add chat_send_message_hook \
tkabber/plugins/chat/empty_body.tcl:14:hook::add chat_send_message_hook [namespace current]::check_send_empty_body 10
tkabber/plugins/chat/clear.tcl:26:hook::add chat_send_message_hook \
tkabber-contrib/openhistory/openhistory.tcl:8: hook::add chat_send_message_hook [namespace current]::handle_command 15
tkabber-contrib/autoanswer/autoanswer.tcl:232: hook::add chat_send_message_hook \
tkabber-contrib/juick/juick.tcl:108: hook::add chat_send_message_hook \
tkabber-contrib/juick/juick.tcl:151: hook::remove chat_send_message_hook \
tkabber-contrib/bldjid2/bldjid2.tcl:186: hook::add chat_send_message_hook \
tkabber-contrib/bldjid2/bldjid2.tcl:208: hook::remove chat_send_message_hook \
tkabber-contrib/reminder/reminder.tcl:71: hook::add chat_send_message_hook \
tkabber-contrib/reminder/reminder.tcl:85: hook::remove chat_send_message_hook \
tkabber-contrib/urlcmd/urlcmd.tcl:25: hook::add chat_send_message_hook \
tkabber-contrib/bldjid/bldjid.tcl:138: hook::add chat_send_message_hook \
tkabber-contrib/bldjid/bldjid.tcl:162: hook::remove chat_send_message_hook \
tkabber-contrib/ibuddy/ibuddy.tcl:35:hook::add chat_send_message_hook [list [namespace current]::ibuddy::udp_puts "MACRO_GREEN"]
tkabber-contrib/tastebin/tastebin.tcl:48: hook::add chat_send_message_hook ${NS}::handle_command
tkabber-plugins/tclchat/tclchat_commands.tcl:12: hook::add chat_send_message_hook \
tkabber-plugins/tclchat/tclchat_commands.tcl:19: hook::remove chat_send_message_hook \
tkabber-plugins/otr/otr.tcl:1283: hook::unset_flag chat_send_message_hook draw
tkabber-plugins/socials/socials.tcl:42: hook::add chat_send_message_hook \
tkabber-plugins/socials/socials.tcl:52: hook::remove chat_send_message_hook \
tkabber-plugins/socials/socials.tcl:179: #hook::run chat_send_message_hook $chatid $user $s $type
tkabber-plugins/bc/bc.tcl:62: hook::add chat_send_message_hook \
tkabber-plugins/bc/bc.tcl:77: hook::remove chat_send_message_hook \
tkabber-plugins/presencecmd/presencecmd.tcl:31: hook::add chat_send_message_hook [namespace current]::handle_command 15
tkabber-plugins/presencecmd/presencecmd.tcl:36: hook::remove chat_send_message_hook [namespace current]::handle_command 15
tkabber-plugins/quiz/quiz.tcl:68: hook::add chat_send_message_hook \
tkabber-plugins/quiz/quiz.tcl:87: hook::remove chat_send_message_hook \
Немного мыслей о развитии механизма команд
Проверку синтаксиса, лучше делать не для каждой команды индивидуально, а централизованно. Регистрируем набор команд со специфицированным форматом аргументов. При отправке сообщения проверяем ввод на соответствие данному формату, осуществляя в сущности ту же работу, которую делает парсер команд shell'а. Остаётся вопрос, что делать, если пользователем набрана существующая команда с неправильным форматом аргументов или несуществующая команда. Я думаю, все сообщения, начинающиеся с символа '/', нужно либо обрабатывать как команды, либо выдавать сообщение о невозможности выполнить команду. А для возможности отправки сообщения с первым символом '/' предусмотреть специальный хак, например команду //.
Ещё в тему единого парсера команд: тип аргумента user
, раскрывается как в
команде /last [user], и тип user_b
, раскрывается как
в команде /vcard [user_b].