mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-23 03:02:48 +01:00
Merge pull request #314 from slingamn/invite.1
fix #313 and a related issue
This commit is contained in:
commit
f3d138d909
@ -366,9 +366,11 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
|
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
chname := channel.name
|
chname := channel.name
|
||||||
|
chcfname := channel.nameCasefolded
|
||||||
founder := channel.registeredFounder
|
founder := channel.registeredFounder
|
||||||
channel.stateMutex.RUnlock()
|
channel.stateMutex.RUnlock()
|
||||||
account := client.Account()
|
account := client.Account()
|
||||||
|
nickMaskCasefolded := client.NickMaskCasefolded()
|
||||||
hasPrivs := isSajoin || (founder != "" && founder == account)
|
hasPrivs := isSajoin || (founder != "" && founder == account)
|
||||||
|
|
||||||
if !hasPrivs && channel.IsFull() {
|
if !hasPrivs && channel.IsFull() {
|
||||||
@ -381,15 +383,15 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isInvited := channel.lists[modes.InviteMask].Match(client.nickMaskCasefolded)
|
isInvited := client.CheckInvited(chcfname) || channel.lists[modes.InviteMask].Match(nickMaskCasefolded)
|
||||||
if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
|
if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
|
||||||
rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
|
rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasPrivs && channel.lists[modes.BanMask].Match(client.nickMaskCasefolded) &&
|
if !hasPrivs && channel.lists[modes.BanMask].Match(nickMaskCasefolded) &&
|
||||||
!isInvited &&
|
!isInvited &&
|
||||||
!channel.lists[modes.ExceptMask].Match(client.nickMaskCasefolded) {
|
!channel.lists[modes.ExceptMask].Match(nickMaskCasefolded) {
|
||||||
rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
|
rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -955,33 +957,29 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
|||||||
|
|
||||||
// Invite invites the given client to the channel, if the inviter can do so.
|
// Invite invites the given client to the channel, if the inviter can do so.
|
||||||
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
||||||
|
chname := channel.Name()
|
||||||
if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
||||||
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, channel.name, inviter.t("You're not a channel operator"))
|
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, chname, inviter.t("You're not a channel operator"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !channel.hasClient(inviter) {
|
if !channel.hasClient(inviter) {
|
||||||
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, channel.name, inviter.t("You're not on that channel"))
|
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, chname, inviter.t("You're not on that channel"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO(dan): handle this more nicely, keep a list of last X invited channels on invitee rather than explicitly modifying the invite list?
|
|
||||||
if channel.flags.HasMode(modes.InviteOnly) {
|
if channel.flags.HasMode(modes.InviteOnly) {
|
||||||
nmc := invitee.NickCasefolded()
|
invitee.Invite(channel.NameCasefolded())
|
||||||
channel.stateMutex.Lock()
|
|
||||||
channel.lists[modes.InviteMask].Add(nmc)
|
|
||||||
channel.stateMutex.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
if member.capabilities.Has(caps.InviteNotify) && member != inviter && member != invitee && channel.ClientIsAtLeast(member, modes.Halfop) {
|
if member.capabilities.Has(caps.InviteNotify) && member != inviter && member != invitee && channel.ClientIsAtLeast(member, modes.Halfop) {
|
||||||
member.Send(nil, inviter.NickMaskString(), "INVITE", invitee.Nick(), channel.name)
|
member.Send(nil, inviter.NickMaskString(), "INVITE", invitee.Nick(), chname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO(dan): should inviter.server.name here be inviter.nickMaskString ?
|
rb.Add(nil, inviter.server.name, RPL_INVITING, inviter.Nick(), invitee.Nick(), chname)
|
||||||
rb.Add(nil, inviter.server.name, RPL_INVITING, invitee.nick, channel.name)
|
invitee.Send(nil, inviter.nickMaskString, "INVITE", invitee.nick, chname)
|
||||||
invitee.Send(nil, inviter.nickMaskString, "INVITE", invitee.nick, channel.name)
|
|
||||||
if invitee.HasMode(modes.Away) {
|
if invitee.HasMode(modes.Away) {
|
||||||
rb.Add(nil, inviter.server.name, RPL_AWAY, invitee.nick, invitee.awayMessage)
|
rb.Add(nil, inviter.server.name, RPL_AWAY, invitee.nick, invitee.awayMessage)
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ type Client struct {
|
|||||||
hops int
|
hops int
|
||||||
hostname string
|
hostname string
|
||||||
idletimer *IdleTimer
|
idletimer *IdleTimer
|
||||||
|
invitedTo map[string]bool
|
||||||
isDestroyed bool
|
isDestroyed bool
|
||||||
isQuitting bool
|
isQuitting bool
|
||||||
languages []string
|
languages []string
|
||||||
@ -1102,3 +1103,26 @@ func (client *Client) generateResumeToken() (token string, err error) {
|
|||||||
|
|
||||||
return client.resumeToken, err
|
return client.resumeToken, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Records that the client has been invited to join an invite-only channel
|
||||||
|
func (client *Client) Invite(casefoldedChannel string) {
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
if client.invitedTo == nil {
|
||||||
|
client.invitedTo = make(map[string]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
client.invitedTo[casefoldedChannel] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks that the client was invited to join a given channel
|
||||||
|
func (client *Client) CheckInvited(casefoldedChannel string) (invited bool) {
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
invited = client.invitedTo[casefoldedChannel]
|
||||||
|
// joining an invited channel "uses up" your invite, so you can't rejoin on kick
|
||||||
|
delete(client.invitedTo, casefoldedChannel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -84,6 +84,12 @@ func (client *Client) NickCasefolded() string {
|
|||||||
return client.nickCasefolded
|
return client.nickCasefolded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) NickMaskCasefolded() string {
|
||||||
|
client.stateMutex.RLock()
|
||||||
|
defer client.stateMutex.RUnlock()
|
||||||
|
return client.nickMaskCasefolded
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) Username() string {
|
func (client *Client) Username() string {
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
defer client.stateMutex.RUnlock()
|
defer client.stateMutex.RUnlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user