deploy #189

Birleştirildi
sneak 2026-10-22 18:52:01 +02:00 main içindeki 42 işlemeyi prod ile birleştirdi
3 değiştirilmiş dosya ile 96 ekleme ve 3 silme
Sadece 3cbdac7bda işlemesindeki değişiklikler gösteriliyor - Tüm işlemeleri göster

No files matched your search

+2 -3
Dosyayı Görüntüle
@@ -1019,9 +1019,8 @@ On the IRC listener, `MODE #channel <modes> [values...]` takes several letters
in one string, e.g. `MODE #general +mt-i` or `MODE #general +ov alice bob`. It in one string, e.g. `MODE #general +mt-i` or `MODE #general +ov alice bob`. It
accepts `i`, `m`, `n`, `s`, `t`, `o` and `v` (with a nick) and `H` (with bits accepts `i`, `m`, `n`, `s`, `t`, `o` and `v` (with a nick) and `H` (with bits
from 1 to 40 when setting), but not `b`, `k` or `l`. A letter whose value is from 1 to 40 when setting), but not `b`, `k` or `l`. A letter whose value is
missing is skipped. The changes made are echoed to the operator's connection and missing is skipped. The changes made are sent to every channel member as one
also sent to every channel member, the operator included, as one `MODE` line, `MODE` line, e.g. `+o-v alice bob`; the operator gets that line once.
e.g. `+o-v alice bob`.
**Channel errors:** **Channel errors:**
+27
Dosyayı Görüntüle
@@ -304,6 +304,15 @@ func (c *Conn) deliverTopicChange(
msg *db.IRCMessage, msg *db.IRCMessage,
text string, text string,
) { ) {
c.mu.Lock()
nick := c.nick
c.mu.Unlock()
// handleTopic already echoed our own topic change.
if msg.From == nick {
return
}
prefix := msg.From + "!" + msg.From + "@*" prefix := msg.From + "!" + msg.From + "@*"
channel := msg.To channel := msg.To
@@ -315,6 +324,15 @@ func (c *Conn) deliverKickMsg(
msg *db.IRCMessage, msg *db.IRCMessage,
text string, text string,
) { ) {
c.mu.Lock()
nick := c.nick
c.mu.Unlock()
// handleKick already echoed our own kick.
if msg.From == nick {
return
}
prefix := msg.From + "!" + msg.From + "@*" prefix := msg.From + "!" + msg.From + "@*"
channel := msg.To channel := msg.To
@@ -377,6 +395,15 @@ func (c *Conn) deliverMode(
return return
} }
c.mu.Lock()
nick := c.nick
c.mu.Unlock()
// applyChannelModes already echoed our own mode change.
if msg.From == nick {
return
}
prefix := msg.From + "!" + msg.From + "@*" prefix := msg.From + "!" + msg.From + "@*"
params := slices.Concat( params := slices.Concat(
+67
Dosyayı Görüntüle
@@ -292,3 +292,70 @@ func TestRelayNickDiffersOnlyInCase(t *testing.T) {
} }
} }
} }
// TestRelayOwnChangeOnce checks that an IRC listener user who
// sets a topic, changes a channel mode or kicks gets one TOPIC,
// MODE or KICK line for it, and so does the other member.
func TestRelayOwnChangeOnce(t *testing.T) {
t.Parallel()
for _, step := range []struct {
command, line string
}{
{"TOPIC", "TOPIC #dup :new topic"},
{"MODE", "MODE #dup +m"},
{"KICK", "KICK #dup carl :bye"},
} {
t.Run(step.command, func(t *testing.T) {
t.Parallel()
env := newTestEnv(t)
alice := env.dial(t)
alice.register("alice")
alice.joinAndDrain("#dup")
carl := env.dial(t)
carl.register("carl")
carl.joinAndDrain("#dup")
alice.send(step.line)
// The reply to alice's next command comes after her
// command has finished, so her own copy comes before it.
beforePong := alice.sendAndExpect("PING :done", "PONG")
// The relay sends a user's queue in order, so a message
// queued now arrives after any relayed copy.
for nick, client := range map[string]*testClient{
"alice": alice, "carl": carl,
} {
env.queueMessage(
t, nick, "PRIVMSG", "dave", nick,
[]string{"after the change"},
)
lines := client.readUntil(func(l string) bool {
return strings.HasSuffix(l, " :after the change")
})
if client == alice {
lines = slices.Concat(beforePong, lines)
}
var changes []string
for _, line := range lines {
if strings.Contains(line, " "+step.command+" #dup ") {
changes = append(changes, line)
}
}
if len(changes) != 1 {
t.Errorf("%s got %q, want one %s line",
nick, changes, step.command)
}
}
})
}
}