Add KICK support
Downstream and upstream message handling are slightly different because downstreams can send KICK messages with multiple channels or users, while upstreams can only send KICK messages with one channel and one user (according to the RFC).
This commit is contained in:
parent
9b7309d4c9
commit
bab26c7a6f
@ -903,6 +903,62 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
dc.logger.Printf("failed to delete channel %q in DB: %v", upstreamName, err)
|
||||
}
|
||||
}
|
||||
case "KICK":
|
||||
var channelStr, userStr string
|
||||
if err := parseMessageParams(msg, &channelStr, &userStr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
channels := strings.Split(channelStr, ",")
|
||||
users := strings.Split(userStr, ",")
|
||||
|
||||
var reason string
|
||||
if len(msg.Params) > 2 {
|
||||
reason = msg.Params[2]
|
||||
}
|
||||
|
||||
if len(channels) != 1 && len(channels) != len(users) {
|
||||
return ircError{&irc.Message{
|
||||
Command: irc.ERR_BADCHANMASK,
|
||||
Params: []string{dc.nick, channelStr, "Bad channel mask"},
|
||||
}}
|
||||
}
|
||||
|
||||
for i, user := range users {
|
||||
var channel string
|
||||
if len(channels) == 1 {
|
||||
channel = channels[0]
|
||||
} else {
|
||||
channel = channels[i]
|
||||
}
|
||||
|
||||
ucChannel, upstreamChannel, err := dc.unmarshalEntity(channel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ucUser, upstreamUser, err := dc.unmarshalEntity(user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ucChannel != ucUser {
|
||||
return ircError{&irc.Message{
|
||||
Command: irc.ERR_USERNOTINCHANNEL,
|
||||
Params: []string{dc.nick, user, channel, "They aren't on that channel"},
|
||||
}}
|
||||
}
|
||||
uc := ucChannel
|
||||
|
||||
params := []string{upstreamChannel, upstreamUser}
|
||||
if reason != "" {
|
||||
params = append(params, reason)
|
||||
}
|
||||
uc.SendMessage(&irc.Message{
|
||||
Command: "KICK",
|
||||
Params: params,
|
||||
})
|
||||
}
|
||||
case "MODE":
|
||||
var name string
|
||||
if err := parseMessageParams(msg, &name); err != nil {
|
||||
|
37
upstream.go
37
upstream.go
@ -582,6 +582,43 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
})
|
||||
})
|
||||
}
|
||||
case "KICK":
|
||||
if msg.Prefix == nil {
|
||||
return fmt.Errorf("expected a prefix")
|
||||
}
|
||||
|
||||
var channel, user string
|
||||
if err := parseMessageParams(msg, &channel, &user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var reason string
|
||||
if len(msg.Params) > 2 {
|
||||
reason = msg.Params[1]
|
||||
}
|
||||
|
||||
if user == uc.nick {
|
||||
uc.logger.Printf("kicked from channel %q by %s", channel, msg.Prefix.Name)
|
||||
delete(uc.channels, channel)
|
||||
} else {
|
||||
ch, err := uc.getChannel(channel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(ch.Members, user)
|
||||
}
|
||||
|
||||
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,
|
||||
})
|
||||
})
|
||||
case "QUIT":
|
||||
if msg.Prefix == nil {
|
||||
return fmt.Errorf("expected a prefix")
|
||||
|
Loading…
Reference in New Issue
Block a user