Obsługa IRCv3

Kompleksowy status implementacji funkcji protokołu IRC w repartee, obejmujący podstawowy protokół RFC 2812 i rozszerzenia IRCv3.

Negocjacja możliwości

repartee implementuje pełny framework negocjacji możliwości IRCv3, w tym CAP LS 302 z parsowaniem wieloliniowym, CAP REQ/ACK/NAK oraz CAP NEW/DEL dla zmian możliwości w czasie pracy.

FunkcjaStatusUwagi
CAP LS 302GotoweParsowanie wieloliniowe, obsługa field3/field4
CAP REQ/ACK/NAKGotoweŻądanie + wykrywanie akceptacji
CAP ENDGotowePrawidłowe zamykanie negocjacji
CAP NEW/DELGotoweZmiany możliwości w czasie pracy przez cap-notify

Poziom 1 -- wymagane

MożliwośćStatusSpecyfikacjaUwagi
multi-prefixGotowe3.1Wszystkie prefiksy trybów na użytkownika w NAMES
extended-joinGotowe3.1JOIN zawiera konto + realname
ircnet.com/extended-joinGotowe--Rozszerzenie producenta IRCnet ircd 2.12: JOIN przenosi dodatkowo <uid> <ip> <netjoin>. Ma pierwszeństwo, gdy potwierdzone (ACK) zostaną oba warianty
server-timeGotowe3.2Tag @time używany jako znacznik czasu wiadomości
account-tagGotowe3.2Konto użytkownika w tagach wiadomości
cap-notifyGotowe3.2Powiadomienia o zmianach możliwości po stronie serwera
away-notifyGotowe3.1Zmiany statusu away w czasie rzeczywistym
account-notifyGotowe3.1Powiadomienia o logowaniu/wylogowaniu konta
chghostGotowe3.2Zmiany ident/hostname w czasie rzeczywistym
SASL EXTERNALGotowe3.1Uwierzytelnianie CertFP przez certyfikat TLS klienta (client_cert_path z łańcuchem PEM i kluczem)
SASL ECDSA-NIST256P-CHALLENGEGotowe--Uwierzytelnianie kluczem publicznym NIST P-256 metodą wyzwanie-odpowiedź
SASL SCRAM-SHA-512 / 256 / 1Gotowe3.1RFC 5802/7677 solone challenge-response z weryfikacją podpisu serwera
SASL OAUTHBEARERGotowe--RFC 7628 uwierzytelnianie tokenem bearer OAuth 2.0 (jawny wybór przez sasl_mechanism = "OAUTHBEARER")
SASL mechanism selectionGotowe--Automatyczny wybór najsilniejszego: EXTERNAL > ECDSA-NIST256P-CHALLENGE > SCRAM-SHA-512 > SCRAM-SHA-256 > SCRAM-SHA-1 > PLAIN

Poziom 2 -- wysoka wartość

MożliwośćStatusSpecyfikacjaUwagi
echo-messageGotowe3.2Serwer odsyła własne wiadomości; lokalne echo wyłączone
labeled-responseGotowe3.2Korelacja żądań i odpowiedzi (@label) dla komend oraz batchy (ACK, BATCH)
invite-notifyGotowe3.2Członkowie kanału widzą zaproszenia
batchGotowe3.2Podsumowania NETSPLIT/NETJOIN; przenosi batche multiline, chathistory, search oraz labeled-response
userhost-in-namesGotowe3.2Parsowanie nick!user@host w NAMES
no-implicit-namesGotowe--Wycisza automatyczne NAMES przy JOIN (no-implicit-names, draft/no-implicit-names, soju.im/no-implicit-names)
message-tagsGotowe3.2Tagi wyodrębniane, przechowywane w buforze i bazie danych; przenoszą też tagi klienta w TAGMSG
draft/chathistoryGotowe--Historia z serwera/bouncera: TARGETS, stronicowanie scroll-back, gap-fill po reconnect, BETWEEN, AROUND (patrz niżej)
draft/event-playbackGotowe--Żąda odtworzenia JOIN/PART/trybów wewnątrz batchy CHATHISTORY
draft/multilineGotowe--Długie/wklejane wiadomości ujęte w jeden BATCH; składanie przychodzących (patrz niżej)
draft/read-markerGotowe--Synchronizacja stanu przeczytania między klientami przez MARKREAD (draft/read-marker oraz soju.im/read)
draft/message-redactionGotowe--Usuwanie wiadomości (REDACT) przez /redact <target> <msgid> [reason]
draft/account-registrationGotowe--Rejestracja (REGISTER) i weryfikacja (VERIFY) konta przez /account
draft/metadata-2Gotowe--Metadane konwersacji (pin, mute, block) i subskrypcje przez /bmeta
draft/extended-isupportGotowe--Rozszerzona negocjacja parametrów RPL_ISUPPORT (ISUPPORT)
draft/channel-contextGotowe--Tag klienta kontekstu kanału (+draft/channel-context / channel-context)
tag klienta +typingGotowe--Ratyfikowany wskaźnik pisania na TAGMSG. Wysyłanie + odbieranie, element status line w TUI i interfejsie webowym (patrz niżej)

Poziom 3 i rozszerzenia bouncerów

MożliwośćStatusUwagi
msgidGotoweOdczytywany z message-tags; steruje deduplikacją CHATHISTORY, usuwaniem wiadomości i kotwicami po ponownym połączeniu
monitor / extended-monitorGotoweŚledzenie statusu online/offline nicków przez /monitor (add, remove, clear, list, status, show) oraz powiadomienia away/account/host/realname (extended-monitor / draft/extended-monitor)
setnameGotoweZmiany realname w czasie rzeczywistym (SETNAME przez /setname <real name>)
draft/webpush / soju.im/webpushGotowePobieranie klucza VAPID i zarządzanie subskrypcjami WebPush przez IRC
soju.im/bouncer-networksGotoweWykrywanie sieci bouncera (BOUNCER LISTNETWORKS), aktualizacje na żywo (soju.im/bouncer-networks-notify), zarządzanie sieciami (/bouncer) i BOUNCER BIND
soju.im/searchGotowePełnotekstowe wyszukiwanie wiadomości po stronie serwera (SEARCH przez /bsearch)
soju.im/client-certGotowePrzypinanie i generowanie certyfikatów klienta TLS na kontach Soju (CERTFP przez /bcert)
replyNierozpoczęteWątki wiadomości przez +draft/reply

Historia po stronie serwera (draft/chathistory)

Gdy serwer lub bouncer (soju, lurker, ergo, …) ogłasza draft/chathistory, repartee żąda historii przez sieć — dzięki czemu nie musisz już przełączać się do przeglądarki logów tylko do odczytu, aby czytać starsze wiadomości.

  • Wykrywanie rozmów (CHATHISTORY TARGETS) -- na połączeniach bouncerowych repartee automatycznie wykrywa aktywne kanały i rozmowy prywatne po połączeniu i pobiera ich ostatni backlog (display.backlog_lines). Otwarcie pustego bufora query na bouncerze również pobiera jego ostatnią historię na żądanie.
  • Stronicowanie scroll-back (CHATHISTORY BEFORE) -- przewijanie kanału lub query ku górze stronicuje starsze wiadomości i dodaje je na początek widoku na żywo (w stylu irssi/WeeChat/The Lounge). W interfejsie webowym pozycja przewijania jest zakotwiczona, więc ładowanie starszych stron nigdy nie powoduje przeskoku widoku, a viewport automatycznie wypełnia się przy świeżym połączeniu, dzięki czemu scroll-back jest dostępny nawet zanim okno się przepełni.
  • Gap-fill po ponownym połączeniu (CHATHISTORY AFTER / LATEST) -- po ponownym połączeniu wypełnia lukę od ostatniej widzianej wiadomości, więc nic nie ginie podczas krótkiej przerwy. Wielostronicowe luki są stronicowane aż do nadrobienia zaległości.
  • Zakresy czasowe i kontekst (CHATHISTORY BETWEEN / AROUND) -- /bsearch between pobiera historię z podanego przedziału czasu na serwerach z draft/chathistory, a /bsearch context <row> dociąga otaczający kontekst dla dowolnego wyniku wyszukiwania przez CHATHISTORY AROUND.
  • Model przechowywania -- bezpośrednie połączenia IRC zapisują historię w lokalnym backlogu SQLite, natomiast połączenia bouncerowe utrzymują historię w pamięci jako zarządzaną przez serwer, bez duplikowania wiadomości w lokalnej bazie SQLite.
  • Ciche wczytywanie i deduplikacja -- batche historii są renderowane w miejscu bez ponownego wyzwalania powiadomień ani liczników aktywności, a wiersze są deduplikowane po msgid (z awaryjnym znacznikiem czasu w milisekundach dla serwerów bez msgid). draft/event-playback jest żądane obok, dzięki czemu zmiany JOIN/PART/trybu są odtwarzane wewnątrz batcha.

Wiadomości wieloliniowe (draft/multiline)

draft/multiline pozwala, aby prawdziwie wieloliniowa wiadomość przemieszczała się jako pojedyncza logiczna wiadomość zamiast N osobnych linii.

  • Wychodzące -- wklejona lub złożona wiadomość wieloliniowa jest obudowana w jeden BATCH typu draft/multiline, z poszanowaniem ogłaszanych przez serwer limitów max-bytes/max-lines, oraz scalana przy wklejaniu, dzięki czemu wklejenie jest jedną wiadomością, a nie zalewem. Jest to bezpieczne dla E2E: zaszyfrowana wiadomość wieloliniowa pozostaje jedną jednostką RPE2E.
  • Przychodzące -- przychodzące batche multiline są składane w jedną wiadomość do wyświetlenia i przechowania; zbyt duże lub niespójne batche są odrzucane, a błędy FAIL BATCH MULTILINE_* są ujawniane, a nie pomijane.
  • Kompozycja w TUI -- naciśnij Alt+Enter, aby dodać podział linii w kompozytorze i wysłać cały blok jako jedną wiadomość wieloliniową.
  • Web -- kompozytor webowy wysyła wieloliniowe wejście jako jedną wiadomość zachowującą \n, gdy cap jest aktywny (i nadal wraca do wysyłania linia po linii, gdy nie jest).

Wskaźniki pisania (+typing)

repartee implementuje ratyfikowany tag klienta +typing. Jest przenoszony przez TAGMSG i wymaga jedynie message-tags, więc nie ma osobnej możliwości do wynegocjowania ani niczego do skonfigurowania, aby zaczął działać.

  • Stany -- active (piszesz wiadomość), paused (tekst nadal jest w polu wprowadzania, ale na chwilę przestałeś pisać) oraz done (pole wprowadzania znów jest puste). active i paused renderują się identycznie; rozróżnienie nie jest ujawniane.
  • Czasy -- powiadomienia są ograniczane do jednego na 3 s na cel. Odebrany active wygasa po 6 s, a paused po 30 s, więc rozmówca, którego program padnie w połowie zdania, nigdy nie zostawi zablokowanego wskaźnika. Wysłanie prawdziwej wiadomości niejawnie wycofuje wskaźnik -- po niej nie jest już wysyłany done.
  • Co liczy się jako pisanie -- niepusty tekst, który nie jest poleceniem (/command). Szkic /me (lub /action ) jest wiadomością, więc ogłasza pisanie.
  • Wysyłanie i odbieranie są rozdzielone -- [typing] show steruje tym, czy widzisz innych; send_channels i send_queries niezależnie sterują tym, czy ogłaszasz własne pisanie -- odpowiednio na kanałach i w prywatnych query. Wszystkie trzy są domyślnie włączone.
  • Zgodność -- repartee wysyła zawsze wyłącznie ratyfikowany +typing, ale przy odbiorze nadal akceptuje przedratyfikacyjny +draft/typing. Tag jest tłumiony na serwerach, które blokują go przez ISUPPORT CLIENTTAGDENY, i nigdy nie jest wysyłany na niezarejestrowanym połączeniu.
  • Nigdy nie hałasuje -- TAGMSG nigdy nie otwiera bufora, nigdy nie trafia do logu ani scroll-backu i nigdy nie zwiększa licznika aktywności ani nieprzeczytanych. Odtwarzane batche historii oraz odbicia własnych wiadomości z echo-message są ignorowane, a reguły listy ignorowanych obowiązują. Stan pisania jest porzucany przy PART, QUIT, KICK, zmianie nicka, netsplicie i rozłączeniu.
  • Bezpieczne dla flood-protection -- ramki pisania są wliczane do tego samego budżetu antyfloodowego co wszystko inne i są pomijane, gdy zapas się kończy, więc wskaźnik nigdy nie doprowadzi do wyrzucenia cię za flood.
  • Skrypty -- podepnij api.on("irc.typing", ...), aby obserwować lub tłumić powiadomienia o pisaniu. Zobacz dokumentację Lua API.

Wskaźnik jest renderowany przez element status line typing (obecny na domyślnej liście [statusbar] items) zarówno w TUI, jak i w interfejsie webowym: alice is typing…, alice and bob are typing…, alice, bob and 2 others are typing….

RFC 2812 -- protokół podstawowy

Rejestracja połączenia

FunkcjaStatusUwagi
PASSGotoweHasło serwera wysyłane przed rejestracją
NICKGotoweUstawianie nicka + ponowna próba przy ERR_NICKNAMEINUSE
USERGotoweRejestracja username/realname
OPERGotoweLogowanie operatora IRC
QUITGotoweRozłączenie z wiadomością
USER MODEGotowe+i, +w itp.
SETNAMEGotoweZmiana realname na żywo przez capability setname (/setname)

Operacje na kanałach

FunkcjaStatusUwagi
JOINGotoweWiele kanałów, klucze
PARTGotoweWyjście z powodem
CHANNEL MODEGotowe+beiklmnostRIv i tryby prefiksowe
TOPICGotoweOdczyt/ustawienie, RPL_TOPIC/RPL_TOPICWHOTIME
NAMESGotoweRPL_NAMREPLY z parsowaniem prefiksów, multi-prefix, userhost-in-names
LISTGotoweLista kanałów
INVITEGotoweZaproszenie użytkownika + powiadomienie
KICKGotoweKick z powodem
REDACTGotoweUsuwanie wiadomości przez draft/message-redaction (/redact)

Wiadomości i zapytania

FunkcjaStatusUwagi
PRIVMSGGotoweKanał + prywatne, CTCP ACTION
NOTICEGotoweNotice serwera + użytkownika
TAGMSGGotoweWiadomość zawierająca wyłącznie tagi; przenosi tag klienta +typing. Nigdy nie jest przechowywana ani wyświetlana
WHO / WHOXGotowePodstawowe WHO (352) + WHOX (354) ze śledzeniem kont; świadome SID/UID na ircd z rodziny ircu i na IRCnet (patrz niżej)
WHOISGotowePełne wieloliniowe wyświetlanie WHOIS
WHOWASGotoweWyszukiwanie użytkowników offline
MONITOR / ISONGotoweŚledzenie dostępności nicków przez MONITOR (/monitor) oraz ISON (zdarzenie Lua irc.ison)
AWAYGotoweUstawianie/usuwanie + wyświetlanie RPL_AWAY + ręczne /away per sieć na bouncerach
WALLOPSGotoweWyświetlanie wiadomości wall

CTCP

FunkcjaStatusUwagi
ACTIONGotoweWysyłanie + odbieranie
VERSIONGotoweAutomatyczna odpowiedź
PINGGotoweAutomatyczna odpowiedź
TIMEGotoweAutomatyczna odpowiedź
FINGERGotoweAutomatyczna odpowiedź
SOURCEGotoweAutomatyczna odpowiedź

ISUPPORT (005)

FunkcjaStatusUwagi
Token collectionGotoweSurowe tokeny przechowywane w Connection (wraz z draft/extended-isupport)
Structured parsingGotowePREFIX, CHANMODES, NETWORK, STATUSMSG, WHOX, EXTBAN, CASEMAPPING, MONITOR, SAFERATE, UTF8ONLY, CLIENTTAGDENY, CHATHISTORY, draft/ICON, FILEHOST
Behavior adaptationGotoweAktualizacja przy każdym RPL_ISUPPORT; NETWORK steruje etykietą, SAFERATE dostosowuje kontrolę floodu, draft/ICON udostępnia ikonę sieci (/server icon), FILEHOST zasila /upload

Rozszerzenia niestandardowe

FunkcjaStatusUwagi
WHOXGotoweRozszerzony WHO z selektorami pól, dopasowaniem tokenów, polem konta. Automatyczne wykrywanie przez token ISUPPORT WHOX. Automatyczne WHO przy dołączeniu do kanału wypełnia NickEntry. Pełna zgodność na ircd z rodziny ircu oraz na IRCnet ircd (patrz niżej).
ExtbanGotowe$a:account -- bany/wyjątki/zaproszenia oparte na koncie. Skrót /ban -a account. Świadomość ISUPPORT EXTBAN.

WHOX na ircd z rodziny ircu i na IRCnet

/who -- oraz metadane listy nicków, które zasila automatyczne WHO przy dołączeniu -- rozumieją świadome SID/UID odpowiedzi wysyłane przez te ircd, dzięki czemu stan away, nazwy kont, ident i prawdziwe hostname wypełniają się poprawnie zamiast wracać puste.

  • Selektor pól zależny od linii ircd -- przenośny selektor %tcuihnfar jest używany wszędzie; IRCnet ircd 2.12 (wykrywany po tokenie ISUPPORT IDCHAN) otrzymuje %tcuihnfaUr, dodający pole U (UID użytkownika). Dodatkowe pole nigdy nie jest wysyłane do innych ircd, gdzie po cichu przesunęłoby układ odpowiedzi.
  • Układ odpowiedzi rozróżniany po liczbie argumentów -- 10-argumentowy 354 to układ przenośny, 11-argumentowy to układ IRCnet (z UID). Konto o wartości "0" oznacza, że użytkownik nie jest zalogowany.
  • Zwykłe WHO (352) też aktualizuje teraz stan -- wcześniej jedynie wypisywało linię, więc na serwerach bez WHOX zapytanie WHO przy dołączeniu było zmarnowane, a away/host/ident nigdy nie trafiały na listę nicków.
  • Poprawka parametru końcowego -- IRCnet wysyła :<hop> <sid> <realname>, podczas gdy RFC mówi :<hop> <realname>, przez co zbłąkany 4-znakowy SID renderował się sklejony z realname. Hopcount jest teraz usuwany wszędzie, a SID tylko na serwerach z linii IRCnet -- oba defensywnie.

Pominięte

MożliwośćPowód
stsStrict Transport Security -- poza zakresem na razie
zcryptNiszowe, rzadko używane
Note: Cała nowa obsługa protokołu zawiera testy. Tagi wiadomości propagują do API skryptów i warstwy przechowywania. Framework negocjacji możliwości jest rozszerzalny o przyszłe dodatki.