Centralize logged messages marshaling
This allows messages added to logs to be handled just like messages added to the ring buffer.
This commit is contained in:
parent
37cd9e4d89
commit
3195809c30
@ -222,17 +222,35 @@ func (dc *downstreamConn) SendMessage(msg *irc.Message) {
|
||||
dc.conn.SendMessage(msg)
|
||||
}
|
||||
|
||||
func (dc *downstreamConn) sendFromUpstream(msg *irc.Message, uc *upstreamConn) {
|
||||
// marshalMessage re-formats a message coming from an upstream connection so
|
||||
// that it's suitable for being sent on this downstream connection. Only
|
||||
// messages that may appear in logs are supported.
|
||||
func (dc *downstreamConn) marshalMessage(msg *irc.Message, uc *upstreamConn) *irc.Message {
|
||||
msg = msg.Copy()
|
||||
msg.Prefix = dc.marshalUserPrefix(uc, msg.Prefix)
|
||||
|
||||
switch msg.Command {
|
||||
case "PRIVMSG", "NOTICE":
|
||||
msg.Prefix = dc.marshalUserPrefix(uc, msg.Prefix)
|
||||
msg.Params[0] = dc.marshalEntity(uc, msg.Params[0])
|
||||
case "NICK":
|
||||
// Nick change for another user
|
||||
msg.Params[0] = dc.marshalNick(uc, msg.Params[0])
|
||||
case "JOIN", "PART":
|
||||
msg.Params[0] = dc.marshalChannel(uc, msg.Params[0])
|
||||
case "KICK":
|
||||
msg.Params[0] = dc.marshalChannel(uc, msg.Params[0])
|
||||
msg.Params[1] = dc.marshalNick(uc, msg.Params[1])
|
||||
case "TOPIC":
|
||||
msg.Params[0] = dc.marshalChannel(uc, msg.Params[0])
|
||||
case "MODE":
|
||||
msg.Params[0] = dc.marshalEntity(uc, msg.Params[0])
|
||||
case "QUIT":
|
||||
// This space is intentinally left blank
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected %q message", msg.Command))
|
||||
}
|
||||
|
||||
dc.SendMessage(msg)
|
||||
return msg
|
||||
}
|
||||
|
||||
func (dc *downstreamConn) handleMessage(msg *irc.Message) error {
|
||||
@ -684,7 +702,19 @@ func (dc *downstreamConn) welcome() error {
|
||||
break
|
||||
}
|
||||
|
||||
dc.sendFromUpstream(msg, uc)
|
||||
// Don't replay all messages, because that would mess up client
|
||||
// state. For instance we just sent the list of users, sending
|
||||
// PART messages for one of these users would be incorrect.
|
||||
ignore := true
|
||||
switch msg.Command {
|
||||
case "PRIVMSG", "NOTICE":
|
||||
ignore = false
|
||||
}
|
||||
if ignore {
|
||||
continue
|
||||
}
|
||||
|
||||
dc.SendMessage(dc.marshalMessage(msg, uc))
|
||||
}
|
||||
})
|
||||
|
||||
|
99
upstream.go
99
upstream.go
@ -562,12 +562,9 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
}
|
||||
|
||||
if !me {
|
||||
uc.network.ring.Produce(msg)
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "NICK",
|
||||
Params: []string{dc.marshalEntity(uc, newNick)},
|
||||
})
|
||||
dc.SendMessage(dc.marshalMessage(msg, uc))
|
||||
})
|
||||
}
|
||||
case "JOIN":
|
||||
@ -601,15 +598,9 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
ch.Members[msg.Prefix.Name] = nil
|
||||
}
|
||||
|
||||
uc.appendLog(ch, msg)
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "JOIN",
|
||||
Params: []string{dc.marshalChannel(uc, ch)},
|
||||
})
|
||||
})
|
||||
chMsg := msg.Copy()
|
||||
chMsg.Params[0] = ch
|
||||
uc.produce(ch, chMsg, nil)
|
||||
}
|
||||
case "PART":
|
||||
if msg.Prefix == nil {
|
||||
@ -621,11 +612,6 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var reason string
|
||||
if len(msg.Params) > 1 {
|
||||
reason = msg.Params[1]
|
||||
}
|
||||
|
||||
for _, ch := range strings.Split(channels, ",") {
|
||||
if msg.Prefix.Name == uc.nick {
|
||||
uc.logger.Printf("parted channel %q", ch)
|
||||
@ -638,19 +624,9 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
delete(ch.Members, msg.Prefix.Name)
|
||||
}
|
||||
|
||||
uc.appendLog(ch, msg)
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
params := []string{dc.marshalChannel(uc, ch)}
|
||||
if reason != "" {
|
||||
params = append(params, reason)
|
||||
}
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "PART",
|
||||
Params: params,
|
||||
})
|
||||
})
|
||||
chMsg := msg.Copy()
|
||||
chMsg.Params[0] = ch
|
||||
uc.produce(ch, chMsg, nil)
|
||||
}
|
||||
case "KICK":
|
||||
if msg.Prefix == nil {
|
||||
@ -662,11 +638,6 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var reason string
|
||||
if len(msg.Params) > 2 {
|
||||
reason = msg.Params[2]
|
||||
}
|
||||
|
||||
if user == uc.nick {
|
||||
uc.logger.Printf("kicked from channel %q by %s", channel, msg.Prefix.Name)
|
||||
delete(uc.channels, channel)
|
||||
@ -678,19 +649,7 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
delete(ch.Members, user)
|
||||
}
|
||||
|
||||
uc.appendLog(channel, msg)
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
params := []string{dc.marshalChannel(uc, channel), dc.marshalNick(uc, user)}
|
||||
if reason != "" {
|
||||
params = append(params, reason)
|
||||
}
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "KICK",
|
||||
Params: params,
|
||||
})
|
||||
})
|
||||
uc.produce(channel, msg, nil)
|
||||
case "QUIT":
|
||||
if msg.Prefix == nil {
|
||||
return fmt.Errorf("expected a prefix")
|
||||
@ -709,12 +668,9 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
}
|
||||
|
||||
if msg.Prefix.Name != uc.nick {
|
||||
uc.network.ring.Produce(msg)
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "QUIT",
|
||||
Params: msg.Params,
|
||||
})
|
||||
dc.SendMessage(dc.marshalMessage(msg, uc))
|
||||
})
|
||||
}
|
||||
case irc.RPL_TOPIC, irc.RPL_NOTOPIC:
|
||||
@ -745,18 +701,7 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
} else {
|
||||
ch.Topic = ""
|
||||
}
|
||||
uc.appendLog(ch.Name, msg)
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
params := []string{dc.marshalChannel(uc, name)}
|
||||
if ch.Topic != "" {
|
||||
params = append(params, ch.Topic)
|
||||
}
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "TOPIC",
|
||||
Params: params,
|
||||
})
|
||||
})
|
||||
uc.produce(ch.Name, msg, nil)
|
||||
case "MODE":
|
||||
var name, modeStr string
|
||||
if err := parseMessageParams(msg, &name, &modeStr); err != nil {
|
||||
@ -781,18 +726,7 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
}
|
||||
}
|
||||
|
||||
uc.appendLog(ch.Name, msg)
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
params := []string{dc.marshalChannel(uc, name), modeStr}
|
||||
params = append(params, msg.Params[2:]...)
|
||||
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.marshalUserPrefix(uc, msg.Prefix),
|
||||
Command: "MODE",
|
||||
Params: params,
|
||||
})
|
||||
})
|
||||
uc.produce(ch.Name, msg, nil)
|
||||
}
|
||||
case irc.RPL_UMODEIS:
|
||||
if err := parseMessageParams(msg, nil); err != nil {
|
||||
@ -1362,6 +1296,11 @@ func (uc *upstreamConn) appendLog(entity string, msg *irc.Message) {
|
||||
}
|
||||
}
|
||||
|
||||
// produce appends a message to the logs, adds it to the history and forwards
|
||||
// it to connected downstream connections.
|
||||
//
|
||||
// If origin is not nil and origin doesn't support echo-message, the message is
|
||||
// forwarded to all connections except origin.
|
||||
func (uc *upstreamConn) produce(target string, msg *irc.Message, origin *downstreamConn) {
|
||||
if target != "" {
|
||||
uc.appendLog(target, msg)
|
||||
@ -1371,7 +1310,7 @@ func (uc *upstreamConn) produce(target string, msg *irc.Message, origin *downstr
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
if dc != origin || dc.caps["echo-message"] {
|
||||
dc.sendFromUpstream(msg, uc)
|
||||
dc.SendMessage(dc.marshalMessage(msg, uc))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user