add all channel mask list replies

This commit is contained in:
Jeremy Latt 2014-02-22 15:01:11 -08:00
parent c5c7469cf0
commit f482b6b82f
4 changed files with 118 additions and 56 deletions

View File

@ -5,8 +5,8 @@ import (
) )
type Channel struct { type Channel struct {
banList []UserMask
flags ChannelModeSet flags ChannelModeSet
lists map[ChannelMode][]UserMask
key string key string
members MemberSet members MemberSet
name string name string
@ -23,8 +23,12 @@ func IsChannel(target string) bool {
// string, which must be unique on the server. // string, which must be unique on the server.
func NewChannel(s *Server, name string) *Channel { func NewChannel(s *Server, name string) *Channel {
channel := &Channel{ channel := &Channel{
banList: make([]UserMask, 0), flags: make(ChannelModeSet),
flags: make(ChannelModeSet), lists: map[ChannelMode][]UserMask{
BanMask: []UserMask{},
ExceptMask: []UserMask{},
InviteMask: []UserMask{},
},
members: make(MemberSet), members: make(MemberSet),
name: name, name: name,
server: s, server: s,
@ -228,31 +232,72 @@ func (channel *Channel) PrivMsg(client *Client, message string) {
} }
} }
func (channel *Channel) applyModeFlag(client *Client, mode ChannelMode,
op ModeOp) bool {
if !channel.ClientIsOperator(client) {
client.ErrChanOPrivIsNeeded(channel)
return false
}
switch op {
case Add:
channel.flags[mode] = true
return true
case Remove:
delete(channel.flags, mode)
return true
}
return false
}
func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
op ModeOp, nick string) bool {
if !channel.ClientIsOperator(client) {
client.ErrChanOPrivIsNeeded(channel)
return false
}
if nick == "" {
client.ErrNeedMoreParams("MODE")
return false
}
target := channel.server.clients.Get(nick)
if target == nil {
client.ErrNoSuchNick(nick)
return false
}
if !channel.members.Has(target) {
client.ErrUserNotInChannel(channel, target)
return false
}
switch op {
case Add:
channel.members[target][mode] = true
return true
case Remove:
channel.members[target][mode] = false
return true
}
return false
}
func (channel *Channel) applyMode(client *Client, change ChannelModeChange) bool { func (channel *Channel) applyMode(client *Client, change ChannelModeChange) bool {
switch change.mode { switch change.mode {
case BanMask: case BanMask, ExceptMask, InviteMask:
// TODO add/remove // TODO add/remove
for _, banMask := range channel.banList { for _, mask := range channel.lists[change.mode] {
client.RplBanList(channel, banMask) client.RplMaskList(change.mode, channel, mask)
} }
client.RplEndOfBanList(channel) client.RplEndOfMaskList(change.mode, channel)
case Moderated, NoOutside, OpOnlyTopic, Private: case Moderated, NoOutside, OpOnlyTopic, Private:
if !channel.ClientIsOperator(client) { return channel.applyModeFlag(client, change.mode, change.op)
client.ErrChanOPrivIsNeeded(channel)
return false
}
switch change.op {
case Add:
channel.flags[change.mode] = true
return true
case Remove:
delete(channel.flags, change.mode)
return true
}
case Key: case Key:
if !channel.ClientIsOperator(client) { if !channel.ClientIsOperator(client) {
@ -289,36 +334,7 @@ func (channel *Channel) applyMode(client *Client, change ChannelModeChange) bool
return true return true
case ChannelOperator, Voice: case ChannelOperator, Voice:
if !channel.ClientIsOperator(client) { return channel.applyModeMember(client, change.mode, change.op, change.arg)
client.ErrChanOPrivIsNeeded(channel)
return false
}
if change.arg == "" {
client.ErrNeedMoreParams("MODE")
return false
}
target := channel.server.clients.Get(change.arg)
if target == nil {
client.ErrNoSuchNick(change.arg)
return false
}
if !channel.members.Has(target) {
client.ErrUserNotInChannel(channel, target)
return false
}
switch change.op {
case Add:
channel.members[target][change.mode] = true
return true
case Remove:
channel.members[target][change.mode] = false
return true
}
default: default:
client.ErrUnknownMode(change.mode, channel) client.ErrUnknownMode(change.mode, channel)

View File

@ -566,7 +566,7 @@ func NewChannelModeCommand(args []string) (editableCommand, error) {
op: op, op: op,
} }
switch change.mode { switch change.mode {
case Key, BanMask, ExceptionMask, InviteMask, UserLimit, case Key, BanMask, ExceptMask, InviteMask, UserLimit,
ChannelOperator, ChannelCreator, Voice: ChannelOperator, ChannelCreator, Voice:
if len(args) > skipArgs { if len(args) > skipArgs {
change.arg = args[skipArgs] change.arg = args[skipArgs]

View File

@ -212,7 +212,7 @@ const (
BanMask ChannelMode = 'b' // arg BanMask ChannelMode = 'b' // arg
ChannelCreator ChannelMode = 'O' // flag ChannelCreator ChannelMode = 'O' // flag
ChannelOperator ChannelMode = 'o' // arg ChannelOperator ChannelMode = 'o' // arg
ExceptionMask ChannelMode = 'e' // arg ExceptMask ChannelMode = 'e' // arg
InviteMask ChannelMode = 'I' // arg InviteMask ChannelMode = 'I' // arg
InviteOnly ChannelMode = 'i' // flag InviteOnly ChannelMode = 'i' // flag
Key ChannelMode = 'k' // flag arg Key ChannelMode = 'k' // flag arg

View File

@ -253,14 +253,60 @@ func (target *Client) RplEndOfWho(name string) {
"%s :End of WHO list", name) "%s :End of WHO list", name)
} }
func (target *Client) RplBanList(channel *Channel, ban UserMask) { func (target *Client) RplMaskList(mode ChannelMode, channel *Channel, mask UserMask) {
switch mode {
case BanMask:
target.RplBanList(channel, mask)
case ExceptMask:
target.RplExceptList(channel, mask)
case InviteMask:
target.RplInviteList(channel, mask)
}
}
func (target *Client) RplEndOfMaskList(mode ChannelMode, channel *Channel) {
switch mode {
case BanMask:
target.RplEndOfBanList(channel)
case ExceptMask:
target.RplEndOfExceptList(channel)
case InviteMask:
target.RplEndOfInviteList(channel)
}
}
func (target *Client) RplBanList(channel *Channel, mask UserMask) {
target.NumericReply(RPL_BANLIST, target.NumericReply(RPL_BANLIST,
"%s %s", channel.name, ban) "%s %s", channel, mask)
} }
func (target *Client) RplEndOfBanList(channel *Channel) { func (target *Client) RplEndOfBanList(channel *Channel) {
target.NumericReply(RPL_ENDOFBANLIST, target.NumericReply(RPL_ENDOFBANLIST,
"%s :End of channel ban list", channel.name) "%s :End of channel ban list", channel)
}
func (target *Client) RplExceptList(channel *Channel, mask UserMask) {
target.NumericReply(RPL_EXCEPTLIST,
"%s %s", channel, mask)
}
func (target *Client) RplEndOfExceptList(channel *Channel) {
target.NumericReply(RPL_ENDOFEXCEPTLIST,
"%s :End of channel exception list", channel)
}
func (target *Client) RplInviteList(channel *Channel, mask UserMask) {
target.NumericReply(RPL_INVITELIST,
"%s %s", channel, mask)
}
func (target *Client) RplEndOfInviteList(channel *Channel) {
target.NumericReply(RPL_ENDOFINVITELIST,
"%s :End of channel invite list", channel)
} }
func (target *Client) RplNowAway() { func (target *Client) RplNowAway() {