summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-04-26 20:42:03 -0300
committerEuAndreh <eu@euandre.org>2026-04-26 20:42:03 -0300
commit6114c3bdd233486a4a766bab6df83efb697a683a (patch)
tree625877b83ed1f074e3cb3fa296d8025ef22f0d71 /src
parentImplement +b channel ban mode with glob mask matching (diff)
downloadpapod-6114c3bdd233486a4a766bab6df83efb697a683a.tar.gz
papod-6114c3bdd233486a4a766bab6df83efb697a683a.tar.xz
Support STATUSMSG (@#chan and +#chan) PRIVMSG targets
Recognize @ and + prefixes on channel targets to filter delivery to ops or ops/voiced respectively. The prefixed target is preserved in the relayed PRIVMSG so clients can render it appropriately.
Diffstat (limited to 'src')
-rw-r--r--src/papod.clj38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/papod.clj b/src/papod.clj
index 8e1851c..05a7b93 100644
--- a/src/papod.clj
+++ b/src/papod.clj
@@ -854,6 +854,14 @@
(or (string/starts-with? s "#")
(string/starts-with? s "&")))
+(defn- statusmsg-prefix
+ [s]
+ (when (and (seq s)
+ (#{\@ \+} (first s))
+ (or (string/starts-with? (subs s 1) "#")
+ (string/starts-with? (subs s 1) "&")))
+ (str (first s))))
+
(defn- resolve-channel
[db handle]
(cond
@@ -2058,7 +2066,11 @@
(handle-memoserv (string/join " " (rest params)) client components)
:else
- (let [target (first params)
+ (let [raw-target (first params)
+ status-prefix (statusmsg-prefix raw-target)
+ target (if status-prefix
+ (subs raw-target 1)
+ raw-target)
content (string/join " " (rest params))
msg-id (java.util.UUID/randomUUID)
msg-at (java.util.Date.)
@@ -2150,9 +2162,28 @@
(into (map (fn [[k v]]
(str k "=" v))
client-tag-pairs)))
+ delivery-target (or raw-target target)
raw (str ":" nick " PRIVMSG "
- target " " content)
+ delivery-target " " content)
tagged (tag-line-at msg-id msg-at out-tags raw)
+ status-ok? (fn [mn]
+ (case status-prefix
+ "@" (and (:ops components)
+ (contains?
+ (get @(:ops components)
+ target)
+ mn))
+ "+" (or (and (:ops components)
+ (contains?
+ (get @(:ops components)
+ target)
+ mn))
+ (and (:voiced components)
+ (contains?
+ (get @(:voiced components)
+ target)
+ mn)))
+ true))
text (cond-> content
(string/starts-with? content ":")
(subs 1))
@@ -2175,7 +2206,8 @@
(:w m) line))))]
(if chan?
(doseq [mn (get @channels target)
- :when (not= mn nick)
+ :when (and (not= mn nick)
+ (status-ok? mn))
:let [m (when clients
(get @clients mn))]
:when m]