3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-29 15:40:02 +01:00

channel: Add comments, fix a small bug with moderated mode

This commit is contained in:
Daniel Oaks 2017-03-27 14:29:51 +10:00
parent 479cd376d2
commit 6aebd4aad9

View File

@ -66,6 +66,7 @@ func NewChannel(s *Server, name string, addDefaultModes bool) *Channel {
return channel return channel
} }
// IsEmpty returns true if the channel has no clients.
func (channel *Channel) IsEmpty() bool { func (channel *Channel) IsEmpty() bool {
channel.membersMutex.RLock() channel.membersMutex.RLock()
defer channel.membersMutex.RUnlock() defer channel.membersMutex.RUnlock()
@ -77,6 +78,7 @@ func (channel *Channel) isEmptyNoMutex() bool {
return len(channel.members) == 0 return len(channel.members) == 0
} }
// Names sends the list of users joined to the channel to the given client.
func (channel *Channel) Names(client *Client) { func (channel *Channel) Names(client *Client) {
channel.membersMutex.RLock() channel.membersMutex.RLock()
defer channel.membersMutex.RUnlock() defer channel.membersMutex.RUnlock()
@ -172,19 +174,11 @@ func (channel *Channel) nicksNoMutex(target *Client) []string {
} else { } else {
nicks[i] += client.nick nicks[i] += client.nick
} }
i += 1 i++
} }
return nicks return nicks
} }
func (channel *Channel) Id() string {
return channel.name
}
func (channel *Channel) Nick() string {
return channel.name
}
// <mode> <mode params> // <mode> <mode params>
func (channel *Channel) modeStringNoLock(client *Client) (str string) { func (channel *Channel) modeStringNoLock(client *Client) (str string) {
// RLock() // RLock()
@ -220,14 +214,18 @@ func (channel *Channel) modeStringNoLock(client *Client) (str string) {
return str return str
} }
// IsFull returns true if this channel is at its' members limit.
func (channel *Channel) IsFull() bool { func (channel *Channel) IsFull() bool {
return (channel.userLimit > 0) && (uint64(len(channel.members)) >= channel.userLimit) return (channel.userLimit > 0) && (uint64(len(channel.members)) >= channel.userLimit)
} }
// CheckKey returns true if the key is not set or matches the given key.
func (channel *Channel) CheckKey(key string) bool { func (channel *Channel) CheckKey(key string) bool {
return (channel.key == "") || (channel.key == key) return (channel.key == "") || (channel.key == key)
} }
// Join joins the given client to this channel (if they can be joined).
//TODO(dan): /SAJOIN and maybe a ForceJoin function?
func (channel *Channel) Join(client *Client, key string) { func (channel *Channel) Join(client *Client, key string) {
channel.membersMutex.Lock() channel.membersMutex.Lock()
defer channel.membersMutex.Unlock() defer channel.membersMutex.Unlock()
@ -319,6 +317,7 @@ func (channel *Channel) Join(client *Client, key string) {
} }
} }
// Part parts the given client from this channel, with the given message.
func (channel *Channel) Part(client *Client, message string) { func (channel *Channel) Part(client *Client, message string) {
channel.membersMutex.Lock() channel.membersMutex.Lock()
defer channel.membersMutex.Unlock() defer channel.membersMutex.Unlock()
@ -336,6 +335,7 @@ func (channel *Channel) Part(client *Client, message string) {
client.server.logger.Debug("part", fmt.Sprintf("%s left channel %s", client.nick, channel.name)) client.server.logger.Debug("part", fmt.Sprintf("%s left channel %s", client.nick, channel.name))
} }
// GetTopic sends the channel topic to the given client.
func (channel *Channel) GetTopic(client *Client) { func (channel *Channel) GetTopic(client *Client) {
channel.membersMutex.RLock() channel.membersMutex.RLock()
defer channel.membersMutex.RUnlock() defer channel.membersMutex.RUnlock()
@ -343,6 +343,8 @@ func (channel *Channel) GetTopic(client *Client) {
channel.getTopicNoMutex(client) channel.getTopicNoMutex(client)
} }
// GetTopic sends the channel topic to the given client without getting the membersMutex.
// This is required because of channel joins.
func (channel *Channel) getTopicNoMutex(client *Client) { func (channel *Channel) getTopicNoMutex(client *Client) {
if !channel.members.Has(client) { if !channel.members.Has(client) {
client.Send(nil, client.server.name, ERR_NOTONCHANNEL, client.nick, channel.name, "You're not on that channel") client.Send(nil, client.server.name, ERR_NOTONCHANNEL, client.nick, channel.name, "You're not on that channel")
@ -358,6 +360,7 @@ func (channel *Channel) getTopicNoMutex(client *Client) {
client.Send(nil, client.server.name, RPL_TOPICTIME, client.nick, channel.name, channel.topicSetBy, strconv.FormatInt(channel.topicSetTime.Unix(), 10)) client.Send(nil, client.server.name, RPL_TOPICTIME, client.nick, channel.name, channel.topicSetBy, strconv.FormatInt(channel.topicSetTime.Unix(), 10))
} }
// SetTopic sets the topic of this channel, if the client is allowed to do so.
func (channel *Channel) SetTopic(client *Client, topic string) { func (channel *Channel) SetTopic(client *Client, topic string) {
channel.membersMutex.RLock() channel.membersMutex.RLock()
defer channel.membersMutex.RUnlock() defer channel.membersMutex.RUnlock()
@ -403,6 +406,7 @@ func (channel *Channel) SetTopic(client *Client, topic string) {
}) })
} }
// CanSpeak returns true if the client can speak on this channel.
func (channel *Channel) CanSpeak(client *Client) bool { func (channel *Channel) CanSpeak(client *Client) bool {
channel.membersMutex.RLock() channel.membersMutex.RLock()
defer channel.membersMutex.RUnlock() defer channel.membersMutex.RUnlock()
@ -413,8 +417,7 @@ func (channel *Channel) CanSpeak(client *Client) bool {
if channel.flags[NoOutside] && !channel.members.Has(client) { if channel.flags[NoOutside] && !channel.members.Has(client) {
return false return false
} }
if channel.flags[Moderated] && !(channel.members.HasMode(client, Voice) || if channel.flags[Moderated] && !channel.clientIsAtLeastNoMutex(client, Voice) {
channel.members.HasMode(client, ChannelOperator)) {
return false return false
} }
return true return true
@ -425,6 +428,7 @@ func (channel *Channel) TagMsg(msgid string, minPrefix *Mode, clientOnlyTags *ma
channel.sendMessage(msgid, "TAGMSG", []Capability{MessageTags}, minPrefix, clientOnlyTags, client, nil) channel.sendMessage(msgid, "TAGMSG", []Capability{MessageTags}, minPrefix, clientOnlyTags, client, nil)
} }
// sendMessage sends a given message to everyone on this channel.
func (channel *Channel) sendMessage(msgid, cmd string, requiredCaps []Capability, minPrefix *Mode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message *string) { func (channel *Channel) sendMessage(msgid, cmd string, requiredCaps []Capability, minPrefix *Mode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message *string) {
if !channel.CanSpeak(client) { if !channel.CanSpeak(client) {
client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "Cannot send to channel") client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "Cannot send to channel")
@ -589,6 +593,7 @@ func (channel *Channel) applyModeMemberNoMutex(client *Client, mode Mode,
return nil return nil
} }
// ShowMaskList shows the given list to the client.
func (channel *Channel) ShowMaskList(client *Client, mode Mode) { func (channel *Channel) ShowMaskList(client *Client, mode Mode) {
// choose appropriate modes // choose appropriate modes
var rpllist, rplendoflist string var rpllist, rplendoflist string
@ -685,6 +690,7 @@ func (channel *Channel) kickNoMutex(client *Client, target *Client, comment stri
channel.quitNoMutex(target) channel.quitNoMutex(target)
} }
// Invite invites the given client to the channel, if the inviter can do so.
func (channel *Channel) Invite(invitee *Client, inviter *Client) { func (channel *Channel) Invite(invitee *Client, inviter *Client) {
if channel.flags[InviteOnly] && !channel.ClientIsAtLeast(inviter, ChannelOperator) { if channel.flags[InviteOnly] && !channel.ClientIsAtLeast(inviter, ChannelOperator) {
inviter.Send(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator") inviter.Send(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, channel.name, "You're not a channel operator")