diff options
| author | EuAndreh <eu@euandre.org> | 2026-04-27 22:36:47 -0300 |
|---|---|---|
| committer | EuAndreh <eu@euandre.org> | 2026-04-27 22:36:47 -0300 |
| commit | 6553488e7341091feecea01f5f926bdfb285f446 (patch) | |
| tree | 8fe3cd7bfd4b8750fe47c8fdb43153689cfe35b3 /src | |
| parent | account-notify and account-tag (diff) | |
| download | papod-6553488e7341091feecea01f5f926bdfb285f446.tar.gz papod-6553488e7341091feecea01f5f926bdfb285f446.tar.xz | |
chghost, setname, invite-notify capabilities
chghost: advertise the cap. We never rewrite hostnames currently
(everything is "localhost"), so this is a passive declaration that
clients negotiating the cap will see CHGHOST messages if/when host
rewriting lands.
setname: SETNAME :<realname> updates the client's stored realname and,
for every shared-channel member that negotiated the cap, emits the
":nick\!user@host SETNAME :<realname>" notification. Length cap matches
the existing TOPICLEN bound (390); empty/over-length names get
FAIL SETNAME INVALID_REALNAME.
invite-notify: INVITE delivery now also sends the INVITE line to every
channel op (other than inviter/invitee) that negotiated the cap, so
mod tooling can track invites without polling. Uses the same
account-tag-aware delivery as the recipient path.
Diffstat (limited to 'src')
| -rw-r--r-- | src/papod.clj | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/src/papod.clj b/src/papod.clj index c7dec26..d155b27 100644 --- a/src/papod.clj +++ b/src/papod.clj @@ -1388,7 +1388,8 @@ " batch labeled-response multi-prefix" " userhost-in-names extended-join" " away-notify utf8only" - " account-notify account-tag" + " account-notify account-tag chghost" + " setname invite-notify" " draft/multiline=max-bytes=4096" ",max-lines=32" " draft/read-marker" @@ -1402,7 +1403,8 @@ " labeled-response multi-prefix" " userhost-in-names extended-join" " away-notify utf8only" - " account-notify account-tag" + " account-notify account-tag chghost" + " setname invite-notify" " draft/multiline draft/read-marker" " draft/message-redaction" " draft/message-editing" @@ -1419,6 +1421,7 @@ "userhost-in-names" "extended-join" "away-notify" "utf8only" "account-notify" "account-tag" + "chghost" "setname" "invite-notify" "draft/multiline" "draft/read-marker" "draft/message-redaction" "draft/message-editing" @@ -3775,6 +3778,38 @@ [(numeric-reply client "306" ":You have been marked as being away")])))) +(defn- handle-setname + [params client components] + (let [{:keys [clients channels]} components + nick (client-target client) + src (client-prefix client) + raw (when (seq params) (string/join " " params)) + new-name (when raw + (cond-> raw + (string/starts-with? raw ":") (subs 1)))] + (cond + (or (string/blank? new-name) + (> (count new-name) 390)) + [(str "FAIL SETNAME INVALID_REALNAME :Invalid realname")] + + :else + (let [line (str ":" src " SETNAME :" new-name)] + (swap! client assoc-in [:user :realname] new-name) + (when (and clients channels) + (let [seen (atom #{nick})] + (doseq [[ch members] @channels + :when (contains? members nick) + mn members + :when (not (contains? @seen mn)) + :let [m (get @clients mn) + ca (:client-atom m) + caps (or (when ca (:caps @ca)) + #{})] + :when (and m (caps "setname"))] + (deliver-to-client! (:w m) line) + (swap! seen conj mn)))) + [line])))) + (defn- handle-batch-open! [message client components] (let [params (clean-params (:params message)) @@ -4136,6 +4171,9 @@ (= command "AWAY") (handle-away params client components) + (= command "SETNAME") + (handle-setname params client components) + (= command "NOTICE") (handle-notice params client components) @@ -4969,6 +5007,28 @@ tagged-base base)] (deliver-to-client! (:w m) line))) + ;; invite-notify: also send the INVITE line + ;; to channel ops who negotiated the cap + ;; (excluding the inviter and the invitee). + (when (and chan-exists? clients + (:ops components)) + (let [op-set (or (get @(:ops components) + handle) #{})] + (doseq [op-nick op-set + :when (and (not= op-nick nick) + (not= op-nick + target)) + :let [m (get @clients op-nick) + ca (:client-atom m) + caps (when ca + (or (:caps @ca) + #{}))] + :when (and m + (caps "invite-notify"))] + (deliver-to-client! (:w m) + (if (and tagged-base + (caps "account-tag")) + tagged-base base))))) ;; When the channel does not exist, also ;; echo the INVITE back to the inviter ;; (RFC1459 behavior). When it exists, |
