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

View File

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

View File

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

View File

@ -253,14 +253,60 @@ func (target *Client) RplEndOfWho(name string) {
"%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,
"%s %s", channel.name, ban)
"%s %s", channel, mask)
}
func (target *Client) RplEndOfBanList(channel *Channel) {
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() {