|
@@ -677,6 +677,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
677
|
677
|
chname := channel.name
|
678
|
678
|
chcfname := channel.nameCasefolded
|
679
|
679
|
founder := channel.registeredFounder
|
|
680
|
+ createdAt := channel.createdTime
|
680
|
681
|
chkey := channel.key
|
681
|
682
|
limit := channel.userLimit
|
682
|
683
|
chcount := len(channel.members)
|
|
@@ -695,7 +696,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
695
|
696
|
// 3. people invited with INVITE can join
|
696
|
697
|
hasPrivs := isSajoin || (founder != "" && founder == details.account) ||
|
697
|
698
|
(persistentMode != 0 && persistentMode != modes.Voice) ||
|
698
|
|
- client.CheckInvited(chcfname)
|
|
699
|
+ client.CheckInvited(chcfname, createdAt)
|
699
|
700
|
if !hasPrivs {
|
700
|
701
|
if limit != 0 && chcount >= limit {
|
701
|
702
|
return errLimitExceeded
|
|
@@ -1475,23 +1476,33 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
1475
|
1476
|
|
1476
|
1477
|
// Invite invites the given client to the channel, if the inviter can do so.
|
1477
|
1478
|
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
1478
|
|
- chname := channel.Name()
|
1479
|
|
- if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
1480
|
|
- rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), chname, inviter.t("You're not a channel operator"))
|
|
1479
|
+ channel.stateMutex.RLock()
|
|
1480
|
+ chname := channel.name
|
|
1481
|
+ chcfname := channel.nameCasefolded
|
|
1482
|
+ createdAt := channel.createdTime
|
|
1483
|
+ _, inviterPresent := channel.members[inviter]
|
|
1484
|
+ _, inviteePresent := channel.members[invitee]
|
|
1485
|
+ channel.stateMutex.RUnlock()
|
|
1486
|
+
|
|
1487
|
+ if !inviterPresent {
|
|
1488
|
+ rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), chname, inviter.t("You're not on that channel"))
|
1481
|
1489
|
return
|
1482
|
1490
|
}
|
1483
|
1491
|
|
1484
|
|
- if !channel.hasClient(inviter) {
|
1485
|
|
- rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), chname, inviter.t("You're not on that channel"))
|
|
1492
|
+ inviteOnly := channel.flags.HasMode(modes.InviteOnly)
|
|
1493
|
+ if inviteOnly && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
|
1494
|
+ rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), chname, inviter.t("You're not a channel operator"))
|
1486
|
1495
|
return
|
1487
|
1496
|
}
|
1488
|
1497
|
|
1489
|
|
- if channel.hasClient(invitee) {
|
|
1498
|
+ if inviteePresent {
|
1490
|
1499
|
rb.Add(nil, inviter.server.name, ERR_USERONCHANNEL, inviter.Nick(), invitee.Nick(), chname, inviter.t("User is already on that channel"))
|
1491
|
1500
|
return
|
1492
|
1501
|
}
|
1493
|
1502
|
|
1494
|
|
- invitee.Invite(channel.NameCasefolded())
|
|
1503
|
+ if inviteOnly {
|
|
1504
|
+ invitee.Invite(chcfname, createdAt)
|
|
1505
|
+ }
|
1495
|
1506
|
|
1496
|
1507
|
for _, member := range channel.Members() {
|
1497
|
1508
|
if member == inviter || member == invitee || !channel.ClientIsAtLeast(member, modes.Halfop) {
|
|
@@ -1513,6 +1524,22 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf
|
1513
|
1524
|
}
|
1514
|
1525
|
}
|
1515
|
1526
|
|
|
1527
|
+// Uninvite rescinds a channel invitation, if the inviter can do so.
|
|
1528
|
+func (channel *Channel) Uninvite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
|
1529
|
+ if !channel.flags.HasMode(modes.InviteOnly) {
|
|
1530
|
+ rb.Add(nil, channel.server.name, "FAIL", "UNINVITE", "NOT_INVITE_ONLY", channel.Name(), inviter.t("Channel is not invite-only"))
|
|
1531
|
+ return
|
|
1532
|
+ }
|
|
1533
|
+
|
|
1534
|
+ if !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
|
1535
|
+ rb.Add(nil, channel.server.name, "FAIL", "UNINVITE", "NOT_PRIVED", channel.Name(), inviter.t("You're not a channel operator"))
|
|
1536
|
+ return
|
|
1537
|
+ }
|
|
1538
|
+
|
|
1539
|
+ invitee.Uninvite(channel.NameCasefolded())
|
|
1540
|
+ rb.Add(nil, channel.server.name, "UNINVITE", invitee.Nick(), channel.Name())
|
|
1541
|
+}
|
|
1542
|
+
|
1516
|
1543
|
// returns who the client can "see" in the channel, respecting the auditorium mode
|
1517
|
1544
|
func (channel *Channel) auditoriumFriends(client *Client) (friends []*Client) {
|
1518
|
1545
|
channel.stateMutex.RLock()
|