From 75aefe6514854bfdbe2a398cf1b7265012c9a88b Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Wed, 8 May 2024 19:04:13 -0700 Subject: [PATCH] Reuse old query buffers for reassumed nicks in ERC * lisp/erc/erc-backend.el (erc--wrangle-query-buffers-on-nick-change): New function for handling buffer renaming and message routing triggered by a nick change. Such twiddling used to reside in `erc-server-NICK' but has been separated out for use by built-in modules overriding `erc-server-NICK'. The behavior has also changed to favor always reusing an existing query buffer whenever possible instead of creating a new, -suffixed buffer. This addresses some arguably unfinished business from bug#48598. (erc-server-NICK): Fix erroneous call to `erc-update-user-nick' that passed the sender's login as the function's INFO argument. Move buffer renaming logic to `erc--wrangle-query-buffers-on-nick-change' for use by "NICK" handlers managed by modules. Also, print the notice in all query buffers when the client changes its own nick. (erc-server-QUIT): Show messages in all query buffers when the client itself quits, but prevent `track' from updating the mode line with redundant noise. * lisp/erc/erc.el (erc-generate-new-buffer-name): Fix typo in doc. (erc--query-list): New function. * test/lisp/erc/erc-scenarios-base-query-participants.el: New file. * test/lisp/erc/erc-scenarios-base-renick.el (erc-scenarios-base-renick-queries-solo): Revise slightly to use modern helper API. (erc-scenarios-base-renick-queries/reassume): New test. (erc-scenarios-base-renick-self/merge-query): New test. * test/lisp/erc/resources/base/query-participants/legacy.eld: New file. * test/lisp/erc/resources/base/reconnect/options-again.eld: Adjust timeout. * test/lisp/erc/resources/base/renick/queries/reassume.eld: New file. * test/lisp/erc/resources/base/renick/self/manual.eld: Update timeouts. * test/lisp/erc/resources/base/renick/self/merge-query-a.eld: New file. * test/lisp/erc/resources/base/renick/self/merge-query-b.eld: New file. (Bug#70928) --- lisp/erc/erc-backend.el | 58 ++++-- lisp/erc/erc.el | 6 +- .../erc-scenarios-base-query-participants.el | 117 +++++++++++ test/lisp/erc/erc-scenarios-base-renick.el | 195 ++++++++++++++++-- .../base/query-participants/legacy.eld | 62 ++++++ .../base/reconnect/options-again.eld | 2 +- .../base/renick/queries/reassume.eld | 64 ++++++ .../erc/resources/base/renick/self/manual.eld | 8 +- .../base/renick/self/merge-query-a.eld | 46 +++++ .../base/renick/self/merge-query-b.eld | 48 +++++ 10 files changed, 567 insertions(+), 39 deletions(-) create mode 100644 test/lisp/erc/erc-scenarios-base-query-participants.el create mode 100644 test/lisp/erc/resources/base/query-participants/legacy.eld create mode 100644 test/lisp/erc/resources/base/renick/queries/reassume.eld create mode 100644 test/lisp/erc/resources/base/renick/self/merge-query-a.eld create mode 100644 test/lisp/erc/resources/base/renick/self/merge-query-b.eld diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 90c46eadaf4..97aab0e25c3 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -121,6 +121,7 @@ (declare-function erc--init-channel-modes "erc" (channel raw-args)) (declare-function erc--open-target "erc" (target)) (declare-function erc--parse-nuh "erc" (string)) +(declare-function erc--query-list "erc" ()) (declare-function erc--target-from-string "erc" (string)) (declare-function erc--update-modes "erc" (raw-args)) (declare-function erc-active-buffer "erc" nil) @@ -1839,6 +1840,37 @@ add things to `%s' instead." ?h host ?t tgt ?m mode))) (erc-banlist-update proc parsed)))) +(defun erc--wrangle-query-buffers-on-nick-change (old new) + "Create or reuse a query buffer for NEW nick after considering OLD nick. +Return a list of buffers in which to announce the change." + ;; Note that `new-buffer' may be older than `old-buffer', e.g., if + ;; the query target is switching to a previously used nick. + (let ((new-buffer (erc-get-buffer new erc-server-process)) + (old-buffer (erc-get-buffer old erc-server-process)) + (selfp (erc-current-nick-p old)) ; e.g., for note taking, etc. + buffers) + (when new-buffer + (push new-buffer buffers)) + (when old-buffer + (push old-buffer buffers) + ;; Ensure the new nick is absent from the old query. + (unless selfp + (erc-remove-channel-member old-buffer old)) + (when (or selfp (null new-buffer)) + (let ((target (erc--target-from-string new)) + (id (erc-networks--id-given erc-networks--id))) + (with-current-buffer old-buffer + (setq erc-default-recipients (cons new + (cdr erc-default-recipients)) + erc--target target)) + (setq new-buffer (erc-get-buffer-create erc-session-server + erc-session-port + nil target id))))) + (when new-buffer + (with-current-buffer new-buffer + (erc-update-mode-line))) + buffers)) + (define-erc-response-handler (NICK) "Handle nick change messages." nil (let ((nn (erc-response.contents parsed)) @@ -1853,21 +1885,14 @@ add things to `%s' instead." ;; erc-channel-users won't contain it ;; ;; Possibly still relevant: bug#12002 - (when-let ((buf (erc-get-buffer nick erc-server-process)) - (tgt (erc--target-from-string nn))) - (with-current-buffer buf - (setq erc-default-recipients (cons nn (cdr erc-default-recipients)) - erc--target tgt)) - (with-current-buffer (erc-get-buffer-create erc-session-server - erc-session-port nil tgt - (erc-networks--id-given - erc-networks--id)) - ;; Current buffer is among bufs - (erc-update-mode-line))) - (erc-update-user-nick nick nn host nil nil login) + (dolist (buf (erc--wrangle-query-buffers-on-nick-change nick nn)) + (cl-pushnew buf bufs)) + (erc-update-user-nick nick nn host login) (cond ((string= nick (erc-current-nick)) (cl-pushnew (erc-server-buffer) bufs) + ;; Show message in all query buffers. + (setq bufs (append (erc--query-list) bufs)) (erc-set-current-nick nn) ;; Rename session, possibly rename server buf and all targets (when erc-server-connected @@ -2103,15 +2128,20 @@ like `erc-insert-modify-hook'.") (define-erc-response-handler (QUIT) "Another user has quit IRC." nil (let ((reason (erc-response.contents parsed)) + (erc--msg-prop-overrides erc--msg-prop-overrides) bufs) (pcase-let ((`(,nick ,login ,host) (erc-parse-user (erc-response.sender parsed)))) (setq bufs (erc-buffer-list-with-nick nick proc)) - (erc-remove-user nick) + (when (erc-current-nick-p nick) + (setq bufs (append (erc--query-list) bufs)) + (push '(erc--skip . (track)) erc--msg-prop-overrides)) (setq reason (erc-wash-quit-reason reason nick login host)) (erc-display-message parsed 'notice bufs 'QUIT ?n nick ?u login - ?h host ?r reason)))) + ?h host ?r reason) + (erc-remove-user nick))) + nil) (define-erc-response-handler (TOPIC) "The channel topic has changed." nil diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 3d73c33312a..4de7f089aaf 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1990,7 +1990,7 @@ either SERVER or PORT (but not both) to be nil to accommodate oddball `erc-server-connect-function's. When TGT-INFO is non-nil, expect its string field to match the redundant -param TARGET (retained for compatibility). Whenever possibly, prefer +param TARGET (retained for compatibility). Whenever possible, prefer returning TGT-INFO's string unmodified. But when a case-insensitive collision prevents that, return target@ID when ID is non-nil or target@network otherwise after renaming the conflicting buffer in the @@ -2151,6 +2151,10 @@ all channel buffers on all servers." (erc-server-user-buffers user) nil)))) +(defun erc--query-list () + "Return all query buffers for the current connection." + (erc-buffer-list #'erc-query-buffer-p erc-server-process)) + ;; Some local variables ;; TODO eventually deprecate this variable diff --git a/test/lisp/erc/erc-scenarios-base-query-participants.el b/test/lisp/erc/erc-scenarios-base-query-participants.el new file mode 100644 index 00000000000..9e9109091ac --- /dev/null +++ b/test/lisp/erc/erc-scenarios-base-query-participants.el @@ -0,0 +1,117 @@ +;;; erc-scenarios-base-query-participants.el --- Query user tables -*- lexical-binding: t -*- + +;; Copyright (C) 2024 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert-x) +(eval-and-compile + (let ((load-path (cons (ert-resource-directory) load-path))) + (require 'erc-scenarios-common))) + +(ert-deftest erc-scenarios-base-query-participants () + :tags '(:expensive-test) + + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/query-participants") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'legacy)) + (expect (erc-d-t-make-expecter)) + (port (process-contact dumb-server :service))) + + (ert-info ("Connect to foonet") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :full-name "tester") + (funcall expect 10 "This server is in debug mode") + (erc-scenarios-common-say "/query bob"))) + + (ert-info ("Opening query on untracked user bob doesn't create entry.") + (with-current-buffer "bob" + (should-not (erc-get-channel-member "bob")))) + + (ert-info ("DM from untracked user creates a query entry.") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "dummy")) + (funcall expect 10 " hi") + (should (erc-get-channel-member "dummy")) + (should (erc-get-server-user "dummy")))) + + (with-current-buffer "foonet" + (erc-scenarios-common-say "/join #chan")) + + (ert-info ("Members in new chan not added to existing query buffers") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (funcall expect 10 "bob ")) ; some user bob is present in #chan + (with-current-buffer "bob" + (should-not (erc-get-channel-member "bob")))) + + (ert-info ("Opening query on tracked user doesn't create entry") + ;; And DM'ing them makes no difference. + (with-current-buffer "#chan" + (funcall expect 10 " alice") ;; some user alice is present + (erc-scenarios-common-say "hi channel") + (funcall expect 10 " hi channel") + (erc-scenarios-common-say "/query alice")) + (with-current-buffer "alice" + (should-not (erc-get-channel-member "alice")))) + + (ert-info ("DM from a tracked user creates entry in preexisting buffer") + (with-current-buffer "bob" + (funcall expect 10 " hi") + (should (erc-get-channel-member "bob")))) + + (ert-info ("Query pal parting channel doesn't remove them from query") + ;; Identical result if they're kicked: they're removed from the + ;; server if they have no target buffers remaining, which can't + ;; be true if a query with them remains. + (with-current-buffer "#chan" + (funcall expect 10 "has left") + (should-not (erc-get-channel-member "dummy")) + (should (erc-get-server-user "dummy"))) + (with-current-buffer "dummy" + (should (erc-get-channel-member "dummy")))) + + (ert-info ("Query pal quitting channel removes them everywhere") + (with-current-buffer "#chan" + (funcall expect 10 "has quit") + (should-not (erc-get-channel-member "bob")) + (should-not (erc-get-server-user "bob"))) + (with-current-buffer "bob" + (should-not (erc-get-channel-member "bob")))) + + (ert-info ("Query pal re-joining doesn't repopulate query") + (with-current-buffer "#chan" + (erc-scenarios-common-say "bob gone") + (funcall expect 10 " bob, welcome back!") + (should (erc-get-server-user "bob"))) + (with-current-buffer "bob" + (should-not (erc-get-channel-member "bob")))) + + (ert-info ("Parting removes chan members from server unless in some query") + (with-current-buffer "#chan" + (erc-scenarios-common-say "/part") + (funcall expect 10 "you have left") + (should-not (erc-get-server-user "fsbot")) + (should-not (erc-get-server-user "alice")) ; she never said anything + (should-not (erc-get-server-user "bob")) ; missing from query + (should (erc-get-server-user "dummy")))))) + + +;;; erc-scenarios-base-query-participants.el ends here diff --git a/test/lisp/erc/erc-scenarios-base-renick.el b/test/lisp/erc/erc-scenarios-base-renick.el index 3001fde6da0..19cb1ecde1d 100644 --- a/test/lisp/erc/erc-scenarios-base-renick.el +++ b/test/lisp/erc/erc-scenarios-base-renick.el @@ -160,6 +160,7 @@ (erc-server-flood-penalty 0.1) (erc-server-flood-margin 20) (dumb-server (erc-d-run "localhost" t 'solo)) + (expect (erc-d-t-make-expecter)) (port (process-contact dumb-server :service)) erc-autojoin-channels-alist erc-server-buffer-foo) @@ -175,33 +176,189 @@ (erc-d-t-wait-for 10 (get-buffer "foonet")) - (ert-info ("Joined by bouncer to #foo, pal persent") + (ert-info ("Joined by bouncer to #foo, pal Lal is present") (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo")) - (erc-d-t-search-for 5 "On Thursday") + (funcall expect 10 " alice: On Thursday") (erc-scenarios-common-say "hi"))) - (erc-d-t-wait-for 10 "Query buffer appears with message from pal" - (get-buffer "Lal")) - - (ert-info ("Chat with pal, who changes name") - (with-current-buffer "Lal" - (erc-d-t-search-for 3 "hello") + (ert-info ("Query buffer appears from Lal, who renicks") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "Lal")) + (funcall expect 10 " hello") (erc-scenarios-common-say "hi") - (erc-d-t-search-for 10 "is now known as Linguo") - (should-not (search-forward "is now known as Linguo" nil t)))) - - (erc-d-t-wait-for 1 (get-buffer "Linguo")) - (should-not (get-buffer "Lal")) - - (with-current-buffer "Linguo" (erc-scenarios-common-say "howdy Linguo")) + (funcall expect 10 "is now known as Linguo") + ;; No duplicate message. + (funcall expect -0.1 "is now known as Linguo") + ;; No duplicate buffer. + (erc-d-t-wait-for 1 (equal (buffer-name) "Linguo")) + (should-not (get-buffer "Lal")) + (erc-scenarios-common-say "howdy Linguo"))) (with-current-buffer "#foo" - (erc-d-t-search-for 10 "is now known as Linguo") - (should-not (search-forward "is now known as Linguo" nil t)) - (erc-cmd-PART "")) + (funcall expect 10 "is now known as Linguo") + (funcall expect -0.1 "is now known as Linguo") + (erc-scenarios-common-say "/part")) (with-current-buffer "Linguo" - (erc-d-t-search-for 10 "get along")))) + (funcall expect 10 "get along")))) + +;; Someone you have a query with disconnects and reconnects under a +;; new nick (perhaps due to their client appending a backtick or +;; underscore). They then engage you in another query before +;; renicking to their original nick. Prior to 5.5, ERC would add a +;; uniquifying suffix of the form bob<2> to the new, post-renick +;; query. ERC 5.6+ acts differently. It mimics popular standalone +;; clients in reusing existing query buffers. +(ert-deftest erc-scenarios-base-renick-queries/reassume () + :tags '(:expensive-test) + + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/renick/queries") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'reassume)) + (port (process-contact dumb-server :service)) + (expect (erc-d-t-make-expecter)) + (erc-autojoin-channels-alist '((foonet "#chan")))) + + (ert-info ("Connect to foonet") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester") + (funcall expect 10 "This server is in debug mode"))) + + (ert-info ("User dummy opens a query with you") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "dummy")) + (funcall expect 10 "hi"))) + + (ert-info ("User dummy quits, reconnects as user warwick") + (with-current-buffer "#chan" + (funcall expect 10 "has quit") + (should-not (erc-get-channel-member "dummy")) + (with-current-buffer "dummy" + (should-not (erc-get-channel-member "dummy"))) + (funcall expect 10 " Alas! sir") + (funcall expect 10 " warwick, welcome") + (funcall expect 10 " hola"))) + + (ert-info ("User warwick queries you, creating a new buffer") + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "warwick")) + (should (get-buffer "dummy")) ; not reused + (funcall expect 10 " howdy") + (funcall expect 10 "is now known as dummy") + (should-not (erc-get-channel-member "warwick")) + (should-not (erc-get-channel-member "dummy")))) + + (ert-info ("User warwick renicks as user dummy") + (with-current-buffer "#chan" + (funcall expect 10 "is now known as dummy") + (should-not (erc-get-channel-member "warwick")))) + + (with-current-buffer "dummy" + (should-not (get-buffer "dummy<2>")) + (funcall expect 10 "has quit" (point-min)) + (funcall expect -0.1 "merging buffer") + (funcall expect 10 "is now known as dummy") + (should (erc-get-channel-member "dummy")) + (funcall expect 10 " hey")) + + (with-current-buffer "#chan" + (funcall expect 10 " bob: Than those that")))) + +;; This test asserts behavior for the other side of the conversation +;; described by `erc-scenarios-base-renick-queries/reassume' above. +;; After speaking with someone in a query, you disconnect and +;; reconnect under a new nick. You then open a new query with the +;; same person before changing your nick back to the previous one. +;; The buffers for the two session should then be merged with the help +;; of `erc-networks--transplant-target-buffer-function' and +;; `erc-networks--copy-server-buffer-functions'. +(ert-deftest erc-scenarios-base-renick-self/merge-query () + :tags '(:expensive-test) + + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/renick/self") + (erc-server-flood-penalty 0.1) + (dumb-server (erc-d-run "localhost" t 'merge-query-a 'merge-query-b)) + (port (process-contact dumb-server :service)) + (expect (erc-d-t-make-expecter)) + (erc-autojoin-channels-alist '((foonet "#chan")))) + + (ert-info ("Connect to foonet as tester") + (with-current-buffer (erc :server "127.0.0.1" :port port :nick "tester") + (funcall expect 10 "This server is in debug mode"))) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (funcall expect 10 " bob: Speak to the people") + (erc-scenarios-common-say "/query observer")) + + (with-current-buffer "observer" + (erc-scenarios-common-say "hi") + (funcall expect 10 " hi?")) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (erc-scenarios-common-say "/quit")) + + (with-current-buffer "foonet" + (funcall expect 10 "*** ERC finished ***")) + + (ert-info ("Reconnect to foonet as dummy") + (with-current-buffer (erc :server "127.0.0.1" :port port :nick "dummy") + (funcall expect 10 "This server is in debug mode"))) + + (with-current-buffer + (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/dummy")) + ;; Uniquification has been performed. + (should-not (get-buffer "#chan")) + (should (get-buffer "#chan@foonet/tester")) + (should-not (get-buffer "foonet")) + (should (get-buffer "foonet/tester")) + (should (get-buffer "foonet/dummy")) + (funcall expect 10 " bob: Pray you") + (erc-scenarios-common-say "/query observer")) + + (with-current-buffer "observer@foonet/dummy" + (should-not (get-buffer "observer")) + (should (get-buffer "observer@foonet/tester")) + (erc-scenarios-common-say "hola") + (funcall expect 10 " whodis?")) + + (with-current-buffer + (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/dummy")) + (erc-scenarios-common-say "/nick tester")) + + ;; All buffers have been merged. + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "observer")) + (should-not (get-buffer "observer@foonet/dummy")) + (should-not (get-buffer "observer@foonet/tester")) + ;; Goto last message from previous session. Notice that the + ;; quit message appears in all buffers, including queries. + (funcall expect 10 "has quit" (point-min)) + (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed + (funcall expect 1 (concat "*** Grafting buffer `observer@foonet/dummy'" + " onto `observer@foonet/tester'")) + (funcall expect 1 " hola") + (funcall expect 1 " whodis?") + ;; The nickname change is announced in the query as well so that + ;; the nature of the merge is clear. + (funcall expect 1 "*** Your new nickname is tester")) + + (with-current-buffer "foonet" + (should-not (get-buffer "foonet/dummy")) + (should-not (get-buffer "foonet/tester")) + ;; Goto last assertion. + (funcall expect 10 "*** ERC finished ***" (point-min)) + (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed + (funcall expect 5 "Grafting buffer `foonet/dummy' onto `foonet/tester'")) + + (with-current-buffer "#chan" + (should-not (get-buffer "#chan@foonet/dummy")) + (should-not (get-buffer "#chan@foonet/tester")) + (funcall expect 10 "has quit" (point-min)) + (funcall expect -0.01 "\n\n[") ; duplicate date stamp removed + (funcall expect 1 (concat "*** Grafting buffer `#chan@foonet/dummy'" + " onto `#chan@foonet/tester'")) + (funcall expect 1 "You have joined channel #chan") + (funcall expect 1 " alice: Have here bereft") + (funcall expect 1 "*** Your new nickname is tester")))) ;; You share a channel and a query buffer with a user on two different ;; networks (through a proxy). The user changes their nick on both diff --git a/test/lisp/erc/resources/base/query-participants/legacy.eld b/test/lisp/erc/resources/base/query-participants/legacy.eld new file mode 100644 index 00000000000..6b18023655d --- /dev/null +++ b/test/lisp/erc/resources/base/query-participants/legacy.eld @@ -0,0 +1,62 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK tester")) +((user 10 "USER tester 0 * :tester") + (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1") + (0.01 ":irc.foonet.org 003 tester :This server was created Sun, 26 May 2024 09:32:55 UTC") + (0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server") + (0.02 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)") + (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections") + (0.00 ":irc.foonet.org 254 tester 2 :channels formed") + (0.00 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers") + (0.03 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4") + (0.00 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4") + (0.00 ":irc.foonet.org 422 tester :MOTD File is missing") + (0.00 ":irc.foonet.org 221 tester +Zi") + (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")) + +((mode 10 "MODE tester +i") + (0.00 ":irc.foonet.org 221 tester +Zi") + (0.07 ":dummy!~u@psu3bp52z9f34.irc PRIVMSG tester :hi")) + +((join 10 "JOIN #chan") + (0.02 ":tester!~u@psu3bp52z9f34.irc JOIN #chan") + (0.06 ":irc.foonet.org 353 tester = #chan :bob dummy tester @fsbot alice") + (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list") + (0.00 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :tester, welcome!") + (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :tester, welcome!")) + +((mode-chan 10 "MODE #chan") + (0.02 ":irc.foonet.org 324 tester #chan +Cnt") + (0.01 ":irc.foonet.org 329 tester #chan 1716715981")) + +((privmsg-chan-a 10 "PRIVMSG #chan :hi channel") + (0.06 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :Perchance, Iago, I will ne'er go home.") + + ;; Bob (now known) sends us a DM + (0.07 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG tester :hi") + (0.02 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :alice: He is most in the company of the right noble Claudio.") + (0.05 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob: Such were our faults; or then we thought them none.") + (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :You, sir, I entertain you for one of my hundred; only I do not like the fashion of your garments: you will say, they are Persian attire; but let them be changed.") + + ;; Dummy parts + (0.01 ":dummy!~u@psu3bp52z9f34.irc PART #chan :bye") + (0.08 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :alice: To lay a complot to betray thy foes.") + + ;; Bob quits + (0.02 ":bob!~u@zmmipd3xfii2w.irc QUIT :later") + (0.08 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob: He was famous, sir, in his profession, and it was his great right to be so: Gerard de Narbon.")) + +;; Bob rejoins +((privmsg-chan-b 10 "PRIVMSG #chan :bob gone") + + (0.04 ":bob!~u@zmmipd3xfii2w.irc JOIN #chan") + (0.01 ":alice!~u@zmmipd3xfii2w.irc PRIVMSG #chan :bob, welcome back!") + (0.03 ":bob!~u@zmmipd3xfii2w.irc PRIVMSG #chan :Our states are forfeit: seek not to undo us.")) + +((part 10 "PART #chan :\2ERC\2") + (0.02 ":tester!~u@psu3bp52z9f34.irc PART #chan :\2ERC\2")) diff --git a/test/lisp/erc/resources/base/reconnect/options-again.eld b/test/lisp/erc/resources/base/reconnect/options-again.eld index 8a3264fda9c..a3a86fb7100 100644 --- a/test/lisp/erc/resources/base/reconnect/options-again.eld +++ b/test/lisp/erc/resources/base/reconnect/options-again.eld @@ -18,7 +18,7 @@ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") (0 ":irc.foonet.org 422 tester :MOTD File is missing")) -((mode-user 3.2 "MODE tester +i") +((mode-user 10 "MODE tester +i") (0 ":irc.foonet.org 221 tester +i") (0 ":irc.foonet.org NOTICE tester :This server is still in debug mode.")) diff --git a/test/lisp/erc/resources/base/renick/queries/reassume.eld b/test/lisp/erc/resources/base/renick/queries/reassume.eld new file mode 100644 index 00000000000..50764a143b6 --- /dev/null +++ b/test/lisp/erc/resources/base/renick/queries/reassume.eld @@ -0,0 +1,64 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK tester")) +((user 10 "USER user 0 * :unknown") + (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0.00 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1") + (0.00 ":irc.foonet.org 003 tester :This server was created Thu, 09 May 2024 05:19:24 UTC") + (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") + (0.00 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester :There are 0 users and 6 invisible on 1 server(s)") + (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections") + (0.00 ":irc.foonet.org 254 tester 2 :channels formed") + (0.00 ":irc.foonet.org 255 tester :I have 6 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester 6 6 :Current local users 6, max 6") + (0.00 ":irc.foonet.org 266 tester 6 6 :Current global users 6, max 6") + (0.00 ":irc.foonet.org 422 tester :MOTD File is missing")) + +((mode-user 10 "MODE tester +i") + (0.00 ":irc.foonet.org 221 tester +i") + (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")) + +((join 10 "JOIN #chan") + (0.03 ":irc.foonet.org 221 tester +i") ; dupe + (0.00 ":tester!~u@s8ceryiqkkcxk.irc JOIN #chan") + (0.04 ":irc.foonet.org 353 tester = #chan :@fsbot bob alice dummy tester") + (0.00 ":irc.foonet.org 366 tester #chan :End of NAMES list") + (0.00 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :tester, welcome!") + (0.00 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :tester, welcome!") + (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :That eye that told you so look'd but a-squint.")) + +((mode-chan 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester #chan +Cnt") + (0.01 ":irc.foonet.org 329 tester #chan 1715231970") + + ;; existing query with dummy + (0.05 ":dummy!~u@s8ceryiqkkcxk.irc PRIVMSG tester :hi") + (0.02 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :alice: Villains, forbear! we are the empress' sons.") + (0.01 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: This matter of marrying his king's daughter,wherein he must be weighed rather by her value than his own,words him, I doubt not, a great deal from the matter.") + + ;; dummy quits + (0.07 ":dummy!~u@s8ceryiqkkcxk.irc QUIT :Quit: \2ERC\2 5.5.0.29.1 (IRC client for GNU Emacs 29.3.50)") + (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :We will afflict the emperor in his pride.") + (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Why, then, is my pump well flowered.") + (0.05 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :Alas! sir, I know not Jupiter; I never drank with him in all my life.") + + ;; rejoins as warwick + (0.03 ":warwick!~u@s8ceryiqkkcxk.irc JOIN #chan") + (0.00 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :warwick, welcome!") + (0.00 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :warwick, welcome!") + (0.03 ":warwick!~u@s8ceryiqkkcxk.irc PRIVMSG #chan :hola") + (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: And stint thou too, I pray thee, nurse, say I.") + + ;; Makes contact in a query + (0.02 ":warwick!~u@s8ceryiqkkcxk.irc PRIVMSG tester :howdy") + (0.03 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Nor more willingly leaves winter; such summer-birds are men. Gentlemen, our dinner will not recompense this long stay: feast your ears with the music awhile, if they will fare so harshly o' the trumpet's sound; we shall to 't presently.") + (0.03 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :If it please your honour, I know not well what they are; but precise villains they are, that I am sure of, and void of all profanation in the world that good Christians ought to have.") + + ;; warwick renicks back to dummy + (0.08 ":warwick!~u@s8ceryiqkkcxk.irc NICK dummy") + (0.04 ":bob!~u@68v4mpismdues.irc PRIVMSG #chan :Pleasure and action make the hours seem short.") + (0.01 ":dummy!~u@s8ceryiqkkcxk.irc PRIVMSG tester :hey") + (0.02 ":alice!~u@68v4mpismdues.irc PRIVMSG #chan :bob: Than those that have more cunning to be strange.")) diff --git a/test/lisp/erc/resources/base/renick/self/manual.eld b/test/lisp/erc/resources/base/renick/self/manual.eld index dd107b806d5..a6220ffc2e6 100644 --- a/test/lisp/erc/resources/base/renick/self/manual.eld +++ b/test/lisp/erc/resources/base/renick/self/manual.eld @@ -1,5 +1,5 @@ ;; -*- mode: lisp-data; -*- -((pass 1 "PASS :foonet:changeme")) +((pass 10 "PASS :foonet:changeme")) ((nick 1 "NICK tester")) ((user 1 "USER user 0 * :tester") (0 ":irc.foonet.org 001 tester :Welcome to the FooNet Internet Relay Chat Network tester") @@ -24,7 +24,7 @@ (0 ":irc.foonet.org 372 tester :- Please visit us in #libera for questions and support.") (0 ":irc.foonet.org 376 tester :End of /MOTD command.")) -((mode-user 1.2 "MODE tester +i") +((mode-user 10 "MODE tester +i") (0 ":tester!~u@gq7yjr7gsu7nn.irc MODE tester :+RZi") (0 ":irc.znc.in 306 tester :You have been marked as being away") (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo") @@ -38,13 +38,13 @@ (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.") (0 ":irc.foonet.org 305 tester :You are no longer marked as being away")) -((mode 1 "MODE #foo") +((mode-foo 10 "MODE #foo") (0 ":irc.foonet.org 324 tester #foo +nt") (0 ":irc.foonet.org 329 tester #foo 1622454985") (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.") (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: On Thursday, sir ? the time is very short.")) -((nick 2 "NICK dummy") +((nick 10 "NICK dummy") (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy") (0.1 ":dummy!~u@gq7yjr7gsu7nn.irc MODE dummy :+RZi") (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :dummy: Hi.")) diff --git a/test/lisp/erc/resources/base/renick/self/merge-query-a.eld b/test/lisp/erc/resources/base/renick/self/merge-query-a.eld new file mode 100644 index 00000000000..27ef7ecd2ff --- /dev/null +++ b/test/lisp/erc/resources/base/renick/self/merge-query-a.eld @@ -0,0 +1,46 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK tester")) +((user 10 "USER user 0 * :unknown") + (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1") + (0.00 ":irc.foonet.org 003 tester :This server was created Sun, 12 May 2024 00:41:10 UTC") + (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=25 :are supported by this server") + (0.00 ":irc.foonet.org 251 tester :There are 0 users and 6 invisible on 1 server(s)") + (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0.02 ":irc.foonet.org 253 tester 0 :unregistered connections") + (0.00 ":irc.foonet.org 254 tester 2 :channels formed") + (0.01 ":irc.foonet.org 255 tester :I have 6 clients and 0 servers") + (0.00 ":irc.foonet.org 265 tester 6 6 :Current local users 6, max 6") + (0.00 ":irc.foonet.org 266 tester 6 6 :Current global users 6, max 6") + (0.00 ":irc.foonet.org 422 tester :MOTD File is missing") + (0.00 ":irc.foonet.org 221 tester +i") + (0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")) + +((mode-user 10 "MODE tester +i")) + +((join 10 "JOIN #chan") + (0.00 ":irc.foonet.org 221 tester +i") + (0.00 ":tester!~u@hyyensdmcrjxc.irc JOIN #chan") + (0.02 ":irc.foonet.org 353 tester = #chan :someone tester @fsbot alice bob observer") + (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list") + (0.00 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :tester, welcome!") + (0.01 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :tester, welcome!")) + +((mode-chan 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 tester #chan +Cnt") + (0.02 ":irc.foonet.org 329 tester #chan 1715474476") + (0.09 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: And, uncle, so will I, an if I live.") + (0.03 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: Speak to the people, and they pity her.")) + +((privmsg-observer 10 "PRIVMSG observer :hi") + (0.04 ":observer!~u@hyyensdmcrjxc.irc PRIVMSG tester :hi?") + (0.07 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :To ask of whence you are: report it.")) + +((quit 10 "QUIT :\2ERC\2") + (0.03 ":tester!~u@hyyensdmcrjxc.irc QUIT :Quit: \2ERC\2 5.6-git (IRC client for GNU Emacs 30.0.50)") + (0.03 "ERROR :Quit: \2ERC\2 5.6-git (IRC client for GNU Emacs 30.0.50)")) + +((drop 0 DROP)) diff --git a/test/lisp/erc/resources/base/renick/self/merge-query-b.eld b/test/lisp/erc/resources/base/renick/self/merge-query-b.eld new file mode 100644 index 00000000000..4d7581b3884 --- /dev/null +++ b/test/lisp/erc/resources/base/renick/self/merge-query-b.eld @@ -0,0 +1,48 @@ +;; -*- mode: lisp-data; -*- +((nick 10 "NICK dummy")) +((user 10 "USER user 0 * :unknown") + (0.01 ":irc.foonet.org 001 dummy :Welcome to the foonet IRC Network dummy") + (0.01 ":irc.foonet.org 002 dummy :Your host is irc.foonet.org, running version ergo-v2.11.1") + (0.01 ":irc.foonet.org 003 dummy :This server was created Sun, 12 May 2024 00:41:10 UTC") + (0.00 ":irc.foonet.org 004 dummy irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0.03 ":irc.foonet.org 005 dummy AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=25 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") + (0.03 ":irc.foonet.org 005 dummy KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server") + (0.01 ":irc.foonet.org 005 dummy draft/CHATHISTORY=25 :are supported by this server") + (0.00 ":irc.foonet.org 251 dummy :There are 0 users and 6 invisible on 1 server(s)") + (0.00 ":irc.foonet.org 252 dummy 0 :IRC Operators online") + (0.00 ":irc.foonet.org 253 dummy 0 :unregistered connections") + (0.00 ":irc.foonet.org 254 dummy 2 :channels formed") + (0.00 ":irc.foonet.org 255 dummy :I have 6 clients and 0 servers") + (0.00 ":irc.foonet.org 265 dummy 6 6 :Current local users 6, max 6") + (0.00 ":irc.foonet.org 266 dummy 6 6 :Current global users 6, max 6") + (0.03 ":irc.foonet.org 422 dummy :MOTD File is missing") + (0.00 ":irc.foonet.org 221 dummy +i") + (0.00 ":irc.foonet.org NOTICE dummy :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")) + +((mode-user 10 "MODE dummy +i")) + +((join-chan 10 "JOIN #chan") + (0.01 ":irc.foonet.org 221 dummy +i") + (0.00 ":dummy!~u@hyyensdmcrjxc.irc JOIN #chan") + (0.02 ":irc.foonet.org 353 dummy = #chan :@fsbot alice bob observer someone dummy") + (0.01 ":irc.foonet.org 366 dummy #chan :End of NAMES list") + (0.00 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :dummy, welcome!") + (0.01 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :dummy, welcome!")) + +((mode-chan 10 "MODE #chan") + (0.00 ":irc.foonet.org 324 dummy #chan +Cnt") + (0.02 ":irc.foonet.org 329 dummy #chan 1715474476") + (0.09 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: Indeed, sir, he that sleeps feels not the toothache; but a man that were to sleep your sleep, and a hangman to help him to bed, I think he would change places with his officer; for look you, sir, you know not which way you shall go.") + (0.03 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: Pray you, sir, deliver me this paper.")) + +((privmsg-observer 10 "PRIVMSG observer :hola") + (0.01 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: In manner and form following, sir; all those three: I was seen with her in the manor-house, sitting with her upon the form, and taken following her into the park; which, put together, is, in manner and form following. Now, sir, for the manner,it is the manner of a man to speak to a woman, for the form,in some form.") + (0.05 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :In Isbel's case and mine own. Service is no heritage; and I think I shall never have the blessing of God till I have issue o' my body, for they say barnes are blessings.") + (0.01 ":observer!~u@hyyensdmcrjxc.irc PRIVMSG dummy :whodis?") + (0.02 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: Have here bereft my brother of his life.")) + +((nick-tester 10 "NICK tester") + (0.02 ":dummy!~u@hyyensdmcrjxc.irc NICK tester") + + (0.04 ":alice!~u@zb3s8yrduykma.irc PRIVMSG #chan :bob: You have too courtly a wit for me: I'll rest.") + (0.07 ":bob!~u@zb3s8yrduykma.irc PRIVMSG #chan :alice: And abstinence engenders maladies."))