|
@@ -660,7 +660,7 @@ func (channel *Channel) AddHistoryItem(item history.Item, account string) (err e
|
660
|
660
|
}
|
661
|
661
|
|
662
|
662
|
// Join joins the given client to this channel (if they can be joined).
|
663
|
|
-func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) {
|
|
663
|
+func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) error {
|
664
|
664
|
details := client.Details()
|
665
|
665
|
|
666
|
666
|
channel.stateMutex.RLock()
|
|
@@ -676,39 +676,43 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
676
|
676
|
|
677
|
677
|
if alreadyJoined {
|
678
|
678
|
// no message needs to be sent
|
679
|
|
- return
|
|
679
|
+ return nil
|
680
|
680
|
}
|
681
|
681
|
|
682
|
|
- // the founder can always join (even if they disabled auto +q on join);
|
683
|
|
- // anyone who automatically receives halfop or higher can always join
|
684
|
|
- hasPrivs := isSajoin || (founder != "" && founder == details.account) || (persistentMode != 0 && persistentMode != modes.Voice)
|
|
682
|
+ // 0. SAJOIN always succeeds
|
|
683
|
+ // 1. the founder can always join (even if they disabled auto +q on join)
|
|
684
|
+ // 2. anyone who automatically receives halfop or higher can always join
|
|
685
|
+ // 3. people invited with INVITE can join
|
|
686
|
+ hasPrivs := isSajoin || (founder != "" && founder == details.account) ||
|
|
687
|
+ (persistentMode != 0 && persistentMode != modes.Voice) ||
|
|
688
|
+ client.CheckInvited(chcfname)
|
|
689
|
+ if !hasPrivs {
|
|
690
|
+ if limit != 0 && chcount >= limit {
|
|
691
|
+ return errLimitExceeded
|
|
692
|
+ }
|
685
|
693
|
|
686
|
|
- if !hasPrivs && limit != 0 && chcount >= limit {
|
687
|
|
- rb.Add(nil, client.server.name, ERR_CHANNELISFULL, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
|
688
|
|
- return
|
689
|
|
- }
|
|
694
|
+ if chkey != "" && !utils.SecretTokensMatch(chkey, key) {
|
|
695
|
+ return errWrongChannelKey
|
|
696
|
+ }
|
690
|
697
|
|
691
|
|
- if !hasPrivs && chkey != "" && !utils.SecretTokensMatch(chkey, key) {
|
692
|
|
- rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
|
693
|
|
- return
|
694
|
|
- }
|
|
698
|
+ if channel.flags.HasMode(modes.InviteOnly) &&
|
|
699
|
+ !channel.lists[modes.InviteMask].Match(details.nickMaskCasefolded) {
|
|
700
|
+ return errInviteOnly
|
|
701
|
+ }
|
695
|
702
|
|
696
|
|
- isInvited := client.CheckInvited(chcfname) || channel.lists[modes.InviteMask].Match(details.nickMaskCasefolded)
|
697
|
|
- if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
|
698
|
|
- rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
|
699
|
|
- return
|
700
|
|
- }
|
|
703
|
+ if channel.lists[modes.BanMask].Match(details.nickMaskCasefolded) &&
|
|
704
|
+ !channel.lists[modes.ExceptMask].Match(details.nickMaskCasefolded) &&
|
|
705
|
+ !channel.lists[modes.InviteMask].Match(details.nickMaskCasefolded) {
|
|
706
|
+ return errBanned
|
|
707
|
+ }
|
701
|
708
|
|
702
|
|
- if !hasPrivs && channel.lists[modes.BanMask].Match(details.nickMaskCasefolded) &&
|
703
|
|
- !isInvited &&
|
704
|
|
- !channel.lists[modes.ExceptMask].Match(details.nickMaskCasefolded) {
|
705
|
|
- rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
|
706
|
|
- return
|
|
709
|
+ if channel.flags.HasMode(modes.RegisteredOnly) && details.account == "" {
|
|
710
|
+ return errRegisteredOnly
|
|
711
|
+ }
|
707
|
712
|
}
|
708
|
713
|
|
709
|
|
- if !hasPrivs && channel.flags.HasMode(modes.RegisteredOnly) && details.account == "" && !isInvited {
|
710
|
|
- rb.Add(nil, client.server.name, ERR_NEEDREGGEDNICK, details.nick, chname, client.t("You must be registered to join that channel"))
|
711
|
|
- return
|
|
714
|
+ if joinErr := client.addChannel(channel, rb == nil); joinErr != nil {
|
|
715
|
+ return joinErr
|
712
|
716
|
}
|
713
|
717
|
|
714
|
718
|
client.server.logger.Debug("join", fmt.Sprintf("%s joined channel %s", details.nick, chname))
|
|
@@ -753,10 +757,8 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
753
|
757
|
channel.AddHistoryItem(histItem, details.account)
|
754
|
758
|
}
|
755
|
759
|
|
756
|
|
- client.addChannel(channel, rb == nil)
|
757
|
|
-
|
758
|
760
|
if rb == nil {
|
759
|
|
- return
|
|
761
|
+ return nil
|
760
|
762
|
}
|
761
|
763
|
|
762
|
764
|
var modestr string
|
|
@@ -799,6 +801,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
799
|
801
|
rb.Flush(true)
|
800
|
802
|
|
801
|
803
|
channel.autoReplayHistory(client, rb, message.Msgid)
|
|
804
|
+ return nil
|
802
|
805
|
}
|
803
|
806
|
|
804
|
807
|
func (channel *Channel) autoReplayHistory(client *Client, rb *ResponseBuffer, skipMsgid string) {
|
|
@@ -1437,9 +1440,7 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf
|
1437
|
1440
|
return
|
1438
|
1441
|
}
|
1439
|
1442
|
|
1440
|
|
- if channel.flags.HasMode(modes.InviteOnly) {
|
1441
|
|
- invitee.Invite(channel.NameCasefolded())
|
1442
|
|
- }
|
|
1443
|
+ invitee.Invite(channel.NameCasefolded())
|
1443
|
1444
|
|
1444
|
1445
|
for _, member := range channel.Members() {
|
1445
|
1446
|
if member == inviter || member == invitee || !channel.ClientIsAtLeast(member, modes.Halfop) {
|