mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
modes: Fix modes, re-add channel modes
This commit is contained in:
parent
04442ddef1
commit
e19c1527a4
175
irc/channel.go
175
irc/channel.go
@ -6,7 +6,6 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@ -66,7 +65,7 @@ func (channel *Channel) Names(client *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(buffer)+1+len(nick) > maxNamLen {
|
if len(buffer)+1+len(nick) > maxNamLen {
|
||||||
client.Send(nil, client.server.nameString, RPL_NAMREPLY, "=", channel.nameString, buffer)
|
client.Send(nil, client.server.nameString, RPL_NAMREPLY, client.nickString, "=", channel.nameString, buffer)
|
||||||
buffer = nick
|
buffer = nick
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -75,8 +74,8 @@ func (channel *Channel) Names(client *Client) {
|
|||||||
buffer += nick
|
buffer += nick
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Send(nil, client.server.nameString, RPL_NAMREPLY, "=", channel.nameString, buffer)
|
client.Send(nil, client.server.nameString, RPL_NAMREPLY, client.nickString, "=", channel.nameString, buffer)
|
||||||
client.Send(nil, client.server.nameString, RPL_ENDOFNAMES, channel.nameString, "End of NAMES list")
|
client.Send(nil, client.server.nameString, RPL_ENDOFNAMES, client.nickString, channel.nameString, "End of NAMES list")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) ClientIsOperator(client *Client) bool {
|
func (channel *Channel) ClientIsOperator(client *Client) bool {
|
||||||
@ -158,7 +157,7 @@ func (channel *Channel) ModeString(client *Client) (str string) {
|
|||||||
str += " " + strconv.FormatUint(channel.userLimit, 10)
|
str += " " + strconv.FormatUint(channel.userLimit, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) IsFull() bool {
|
func (channel *Channel) IsFull() bool {
|
||||||
@ -199,6 +198,10 @@ func (channel *Channel) Join(client *Client, key string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for member := range channel.members {
|
||||||
|
member.Send(nil, client.nickMaskString, "JOIN", channel.nameString)
|
||||||
|
}
|
||||||
|
|
||||||
client.channels.Add(channel)
|
client.channels.Add(channel)
|
||||||
channel.members.Add(client)
|
channel.members.Add(client)
|
||||||
if !channel.flags[Persistent] && (len(channel.members) == 1) {
|
if !channel.flags[Persistent] && (len(channel.members) == 1) {
|
||||||
@ -207,16 +210,8 @@ func (channel *Channel) Join(client *Client, key string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
client.Send(nil, client.nickMaskString, "JOIN", channel.nameString)
|
client.Send(nil, client.nickMaskString, "JOIN", channel.nameString)
|
||||||
return
|
channel.GetTopic(client)
|
||||||
//TODO(dan): should we be continuing here????
|
channel.Names(client)
|
||||||
// return was above this originally, is it required?
|
|
||||||
/*
|
|
||||||
for member := range channel.members {
|
|
||||||
member.Reply(reply)
|
|
||||||
}
|
|
||||||
channel.GetTopic(client)
|
|
||||||
channel.Names(client)
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) Part(client *Client, message string) {
|
func (channel *Channel) Part(client *Client, message string) {
|
||||||
@ -233,17 +228,17 @@ func (channel *Channel) Part(client *Client, message string) {
|
|||||||
|
|
||||||
func (channel *Channel) GetTopic(client *Client) {
|
func (channel *Channel) GetTopic(client *Client) {
|
||||||
if !channel.members.Has(client) {
|
if !channel.members.Has(client) {
|
||||||
client.Send(nil, client.server.nameString, ERR_NOTONCHANNEL, channel.nameString, "You're not on that channel")
|
client.Send(nil, client.server.nameString, ERR_NOTONCHANNEL, client.nickString, channel.nameString, "You're not on that channel")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if channel.topic == "" {
|
if channel.topic == "" {
|
||||||
// clients appear not to expect this
|
client.Send(nil, client.server.nameString, RPL_NOTOPIC, client.nickString, channel.nameString, "No topic is set")
|
||||||
//replier.Reply(RplNoTopic(channel))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Send(nil, client.server.nameString, RPL_TOPIC, channel.nameString, channel.topic)
|
client.Send(nil, client.server.nameString, RPL_TOPIC, client.nickString, channel.nameString, channel.topic)
|
||||||
|
//TODO(dan): show topic time and setter here too
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) SetTopic(client *Client, topic string) {
|
func (channel *Channel) SetTopic(client *Client, topic string) {
|
||||||
@ -322,16 +317,11 @@ func (channel *Channel) applyModeFlag(client *Client, mode ChannelMode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
|
func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
|
||||||
op ModeOp, nick string) bool {
|
op ModeOp, nick string) *ChannelModeChange {
|
||||||
if !channel.ClientIsOperator(client) {
|
|
||||||
client.Send(nil, client.server.nameString, ERR_CHANOPRIVSNEEDED, channel.nameString, "You're not a channel operator")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if nick == "" {
|
if nick == "" {
|
||||||
//TODO(dan): shouldn't this be handled before it reaches this function?
|
//TODO(dan): shouldn't this be handled before it reaches this function?
|
||||||
client.Send(nil, client.server.nameString, ERR_NEEDMOREPARAMS, "MODE", "Not enough parameters")
|
client.Send(nil, client.server.nameString, ERR_NEEDMOREPARAMS, "MODE", "Not enough parameters")
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
target := channel.server.clients.Get(Name(nick))
|
target := channel.server.clients.Get(Name(nick))
|
||||||
@ -339,30 +329,38 @@ func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
|
|||||||
//TODO(dan): investigate using NOSUCHNICK and NOSUCHCHANNEL specifically as that other IRCd (insp?) does,
|
//TODO(dan): investigate using NOSUCHNICK and NOSUCHCHANNEL specifically as that other IRCd (insp?) does,
|
||||||
// since I think that would make sense
|
// since I think that would make sense
|
||||||
client.Send(nil, client.server.nameString, ERR_NOSUCHNICK, nick, "No such nick")
|
client.Send(nil, client.server.nameString, ERR_NOSUCHNICK, nick, "No such nick")
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !channel.members.Has(target) {
|
if !channel.members.Has(target) {
|
||||||
client.Send(nil, client.server.nameString, ERR_USERNOTINCHANNEL, client.nickString, channel.nameString, "They aren't on that channel")
|
client.Send(nil, client.server.nameString, ERR_USERNOTINCHANNEL, client.nickString, channel.nameString, "They aren't on that channel")
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case Add:
|
case Add:
|
||||||
if channel.members[target][mode] {
|
if channel.members[target][mode] {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
channel.members[target][mode] = true
|
channel.members[target][mode] = true
|
||||||
return true
|
return &ChannelModeChange{
|
||||||
|
op: Add,
|
||||||
|
mode: mode,
|
||||||
|
arg: nick,
|
||||||
|
}
|
||||||
|
|
||||||
case Remove:
|
case Remove:
|
||||||
if !channel.members[target][mode] {
|
if !channel.members[target][mode] {
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
channel.members[target][mode] = false
|
channel.members[target][mode] = false
|
||||||
return true
|
return &ChannelModeChange{
|
||||||
|
op: Remove,
|
||||||
|
mode: mode,
|
||||||
|
arg: nick,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) ShowMaskList(client *Client, mode ChannelMode) {
|
func (channel *Channel) ShowMaskList(client *Client, mode ChannelMode) {
|
||||||
@ -404,117 +402,6 @@ func (channel *Channel) applyModeMask(client *Client, mode ChannelMode, op ModeO
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) applyMode(client *Client, change *ChannelModeChange) bool {
|
|
||||||
switch change.mode {
|
|
||||||
case BanMask, ExceptMask, InviteMask:
|
|
||||||
return channel.applyModeMask(client, change.mode, change.op,
|
|
||||||
NewName(change.arg))
|
|
||||||
|
|
||||||
case InviteOnly, Moderated, NoOutside, OpOnlyTopic, Persistent, Secret:
|
|
||||||
return channel.applyModeFlag(client, change.mode, change.op)
|
|
||||||
|
|
||||||
case Key:
|
|
||||||
if !channel.ClientIsOperator(client) {
|
|
||||||
client.Send(nil, client.server.nameString, ERR_CHANOPRIVSNEEDED, channel.nameString, "You're not a channel operator")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch change.op {
|
|
||||||
case Add:
|
|
||||||
if change.arg == "" {
|
|
||||||
client.Send(nil, client.server.nameString, ERR_NEEDMOREPARAMS, "MODE", "Not enough parameters")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
key := change.arg
|
|
||||||
if key == channel.key {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.key = key
|
|
||||||
return true
|
|
||||||
|
|
||||||
case Remove:
|
|
||||||
channel.key = ""
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
case UserLimit:
|
|
||||||
limit, err := strconv.ParseUint(change.arg, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
client.Send(nil, client.server.nameString, ERR_NEEDMOREPARAMS, "MODE", "Not enough parameters")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (limit == 0) || (limit == channel.userLimit) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.userLimit = limit
|
|
||||||
return true
|
|
||||||
|
|
||||||
case ChannelFounder, ChannelAdmin, ChannelOperator, Halfop, Voice:
|
|
||||||
var hasPrivs bool
|
|
||||||
|
|
||||||
// make sure client has privs to edit the given prefix
|
|
||||||
for _, mode := range ChannelPrivModes {
|
|
||||||
if channel.members[client][mode] {
|
|
||||||
hasPrivs = true
|
|
||||||
|
|
||||||
// Admins can't give other people Admin or remove it from others,
|
|
||||||
// standard for that channel mode, we worry about this later
|
|
||||||
if mode == ChannelAdmin && change.mode == ChannelAdmin {
|
|
||||||
hasPrivs = false
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
} else if mode == change.mode {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name := NewName(change.arg)
|
|
||||||
|
|
||||||
if !hasPrivs {
|
|
||||||
if change.op == Remove && name.ToLower() == client.nick.ToLower() {
|
|
||||||
// success!
|
|
||||||
} else {
|
|
||||||
client.Send(nil, client.server.nameString, ERR_CHANOPRIVSNEEDED, channel.nameString, "You're not a channel operator")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return channel.applyModeMember(client, change.mode, change.op, name.String())
|
|
||||||
|
|
||||||
default:
|
|
||||||
client.Send(nil, client.server.nameString, ERR_UNKNOWNMODE, change.mode.String(), fmt.Sprintf(":is an unknown mode char to me for %s", channel))
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (channel *Channel) Mode(client *Client, changes ChannelModeChanges) {
|
|
||||||
if len(changes) == 0 {
|
|
||||||
client.Send(nil, client.server.nameString, RPL_CHANNELMODEIS, channel.nameString, channel.ModeString(client))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
applied := make(ChannelModeChanges, 0)
|
|
||||||
for _, change := range changes {
|
|
||||||
if channel.applyMode(client, change) {
|
|
||||||
applied = append(applied, change)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(applied) > 0 {
|
|
||||||
appliedString := applied.String()
|
|
||||||
for member := range channel.members {
|
|
||||||
member.Send(nil, client.nickMaskString, "MODE", channel.nameString, appliedString)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := channel.Persist(); err != nil {
|
|
||||||
log.Println("Channel.Persist:", channel, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (channel *Channel) Persist() (err error) {
|
func (channel *Channel) Persist() (err error) {
|
||||||
if channel.flags[Persistent] {
|
if channel.flags[Persistent] {
|
||||||
_, err = channel.server.db.Exec(`
|
_, err = channel.server.db.Exec(`
|
||||||
|
169
irc/modes.go
169
irc/modes.go
@ -132,9 +132,7 @@ var (
|
|||||||
func modeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func modeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
name := NewName(msg.Params[0])
|
name := NewName(msg.Params[0])
|
||||||
if name.IsChannel() {
|
if name.IsChannel() {
|
||||||
// return cmodeHandler(server, client, msg)
|
return cmodeHandler(server, client, msg)
|
||||||
client.Notice("CMODEs are not yet supported!")
|
|
||||||
return false
|
|
||||||
} else {
|
} else {
|
||||||
return umodeHandler(server, client, msg)
|
return umodeHandler(server, client, msg)
|
||||||
}
|
}
|
||||||
@ -164,14 +162,15 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
// assemble changes
|
// assemble changes
|
||||||
changes := make(ModeChanges, 0)
|
changes := make(ModeChanges, 0)
|
||||||
|
applied := make(ModeChanges, 0)
|
||||||
|
|
||||||
if len(msg.Params) > 1 {
|
if len(msg.Params) > 1 {
|
||||||
modeArg := msg.Params[0]
|
modeArg := msg.Params[1]
|
||||||
op := ModeOp(modeArg[0])
|
op := ModeOp(modeArg[0])
|
||||||
if (op == Add) || (op == Remove) {
|
if (op == Add) || (op == Remove) {
|
||||||
modeArg = modeArg[1:]
|
modeArg = modeArg[1:]
|
||||||
} else {
|
} else {
|
||||||
client.Send(nil, server.nameString, ERR_UNKNOWNERROR, client.nickString, "MODE", "Mode string could not be parsed correctly")
|
client.Send(nil, server.nameString, ERR_UNKNOWNMODE, client.nickString, string(modeArg[1]), "is an unknown mode character to me")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,14 +194,14 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
target.flags[change.mode] = true
|
target.flags[change.mode] = true
|
||||||
changes = append(changes, change)
|
applied = append(applied, change)
|
||||||
|
|
||||||
case Remove:
|
case Remove:
|
||||||
if !target.flags[change.mode] {
|
if !target.flags[change.mode] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(target.flags, change.mode)
|
delete(target.flags, change.mode)
|
||||||
changes = append(changes, change)
|
applied = append(applied, change)
|
||||||
}
|
}
|
||||||
|
|
||||||
case Operator, LocalOperator:
|
case Operator, LocalOperator:
|
||||||
@ -211,7 +210,7 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(target.flags, change.mode)
|
delete(target.flags, change.mode)
|
||||||
changes = append(changes, change)
|
applied = append(applied, change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,15 +224,153 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// MODE <target> [<modestring> [<mode arguments>...]]
|
||||||
func (msg *ChannelModeCommand) HandleServer(server *Server) {
|
func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
client := msg.Client()
|
channelName := NewName(msg.Params[0])
|
||||||
channel := server.channels.Get(msg.channel)
|
channel := server.channels.Get(channelName)
|
||||||
|
|
||||||
if channel == nil {
|
if channel == nil {
|
||||||
client.ErrNoSuchChannel(msg.channel)
|
client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, msg.Params[0], "No such channel")
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.Mode(client, msg.changes)
|
// assemble changes
|
||||||
|
//TODO(dan): split out assembling changes into func that returns changes, err
|
||||||
|
changes := make(ChannelModeChanges, 0)
|
||||||
|
applied := make(ChannelModeChanges, 0)
|
||||||
|
|
||||||
|
if len(msg.Params) > 1 {
|
||||||
|
modeArg := msg.Params[1]
|
||||||
|
op := ModeOp(modeArg[0])
|
||||||
|
if (op == Add) || (op == Remove) {
|
||||||
|
modeArg = modeArg[1:]
|
||||||
|
} else {
|
||||||
|
client.Send(nil, server.nameString, ERR_UNKNOWNMODE, client.nickString, string(modeArg[1]), "is an unknown mode character to me")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
skipArgs := 2
|
||||||
|
for _, mode := range modeArg {
|
||||||
|
if mode == '-' || mode == '+' {
|
||||||
|
op = ModeOp(mode)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
change := ChannelModeChange{
|
||||||
|
mode: ChannelMode(mode),
|
||||||
|
op: op,
|
||||||
|
}
|
||||||
|
|
||||||
|
// put arg into modechange if needed
|
||||||
|
switch ChannelMode(mode) {
|
||||||
|
case BanMask, ExceptMask, InviteMask:
|
||||||
|
if len(msg.Params) > skipArgs {
|
||||||
|
change.arg = msg.Params[skipArgs]
|
||||||
|
skipArgs += 1
|
||||||
|
} else {
|
||||||
|
change.op = List
|
||||||
|
}
|
||||||
|
case Key, UserLimit, ChannelFounder, ChannelAdmin, ChannelOperator, Halfop, Voice:
|
||||||
|
if len(msg.Params) > skipArgs {
|
||||||
|
change.arg = msg.Params[skipArgs]
|
||||||
|
skipArgs += 1
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applied = append(applied, &change)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, change := range changes {
|
||||||
|
switch change.mode {
|
||||||
|
case BanMask, ExceptMask, InviteMask:
|
||||||
|
mask := change.arg
|
||||||
|
list := channel.lists[change.mode]
|
||||||
|
if list == nil {
|
||||||
|
// This should never happen, but better safe than panicky.
|
||||||
|
client.Send(nil, server.nameString, ERR_UNKNOWNERROR, client.nickString, "MODE", "Could not complete MODE command")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change.op == List) || (mask == "") {
|
||||||
|
channel.ShowMaskList(client, change.mode)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch change.op {
|
||||||
|
case Add:
|
||||||
|
list.Add(Name(mask))
|
||||||
|
applied = append(applied, change)
|
||||||
|
|
||||||
|
case Remove:
|
||||||
|
list.Remove(Name(mask))
|
||||||
|
applied = append(applied, change)
|
||||||
|
}
|
||||||
|
|
||||||
|
case InviteOnly, Moderated, NoOutside, OpOnlyTopic, Persistent, Secret:
|
||||||
|
switch change.op {
|
||||||
|
case Add:
|
||||||
|
if channel.flags[change.mode] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
channel.flags[change.mode] = true
|
||||||
|
applied = append(applied, change)
|
||||||
|
|
||||||
|
case Remove:
|
||||||
|
if !channel.flags[change.mode] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
delete(channel.flags, change.mode)
|
||||||
|
applied = append(applied, change)
|
||||||
|
}
|
||||||
|
|
||||||
|
case ChannelFounder, ChannelAdmin, ChannelOperator, Halfop, Voice:
|
||||||
|
// make sure client has privs to edit the given prefix
|
||||||
|
var hasPrivs bool
|
||||||
|
|
||||||
|
for _, mode := range ChannelPrivModes {
|
||||||
|
if channel.members[client][mode] {
|
||||||
|
hasPrivs = true
|
||||||
|
|
||||||
|
// Admins can't give other people Admin or remove it from others,
|
||||||
|
// standard for that channel mode, we worry about this later
|
||||||
|
if mode == ChannelAdmin && change.mode == ChannelAdmin {
|
||||||
|
hasPrivs = false
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
} else if mode == change.mode {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name := NewName(change.arg)
|
||||||
|
|
||||||
|
if !hasPrivs {
|
||||||
|
if change.op == Remove && name.ToLower() == client.nick.ToLower() {
|
||||||
|
// success!
|
||||||
|
} else {
|
||||||
|
client.Send(nil, client.server.nameString, ERR_CHANOPRIVSNEEDED, channel.nameString, "You're not a channel operator")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
change := channel.applyModeMember(client, change.mode, change.op, change.arg)
|
||||||
|
if change != nil {
|
||||||
|
applied = append(changes, change)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(applied) > 0 {
|
||||||
|
//TODO(dan): we should change the name of String and make it return a slice here
|
||||||
|
args := append([]string{channel.nameString}, strings.Split(applied.String(), " ")...)
|
||||||
|
client.Send(nil, client.nickMaskString, "MODE", args...)
|
||||||
|
} else {
|
||||||
|
//TODO(dan): we should just make ModeString return a slice here
|
||||||
|
args := append([]string{client.nickString, channel.nameString}, strings.Split(channel.ModeString(client), " ")...)
|
||||||
|
client.Send(nil, client.nickMaskString, RPL_CHANNELMODEIS, args...)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
@ -60,6 +60,7 @@ const (
|
|||||||
RPL_LISTEND = "323"
|
RPL_LISTEND = "323"
|
||||||
RPL_CHANNELMODEIS = "324"
|
RPL_CHANNELMODEIS = "324"
|
||||||
RPL_UNIQOPIS = "325"
|
RPL_UNIQOPIS = "325"
|
||||||
|
RPL_CREATIONTIME = "329"
|
||||||
RPL_NOTOPIC = "331"
|
RPL_NOTOPIC = "331"
|
||||||
RPL_TOPIC = "332"
|
RPL_TOPIC = "332"
|
||||||
RPL_INVITING = "341"
|
RPL_INVITING = "341"
|
||||||
|
Loading…
Reference in New Issue
Block a user