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). git-svn-id: file:///srv/svn/repo/suika/trunk@159 f0ae65fe-ee39-954e-97ec-027ff2717ef4
This commit is contained in:
parent
8a4a0173a4
commit
3318e3fbfe
@ -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…
x
Reference in New Issue
Block a user