diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d552afc..26265bb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ Improved compatibility, more features, etc. ### Added * Added integrated help (with the `/HELP` command). * Added support for IRCv3.2 [capability negotiation](http://ircv3.net/specs/core/capability-negotiation-3.2.html) including CAP values. -* Added support for IRCv3 capability [`account-notify`](http://ircv3.net/specs/extensions/account-notify-3.1.html), [`sasl`](http://ircv3.net/specs/extensions/sasl-3.2.html), and draft capability [`message-tags`](http://ircv3.net/specs/core/message-tags-3.3.html) as `draft/message-tags`. +* Added support for IRCv3 capability [`account-notify`](http://ircv3.net/specs/extensions/account-notify-3.1.html), [`invite-notify`](http://ircv3.net/specs/extensions/invite-notify-3.2.html), [`sasl`](http://ircv3.net/specs/extensions/sasl-3.2.html), and draft capability [`message-tags`](http://ircv3.net/specs/core/message-tags-3.3.html) as `draft/message-tags`. ### Changed * Casemapping changed from custom unicode mapping to preliminary [rfc7700](https://github.com/ircv3/ircv3-specifications/pull/272) mapping. diff --git a/irc/capability.go b/irc/capability.go index c00963b4..cd3bd203 100644 --- a/irc/capability.go +++ b/irc/capability.go @@ -18,6 +18,7 @@ const ( AccountNotify Capability = "account-notify" AwayNotify Capability = "away-notify" ExtendedJoin Capability = "extended-join" + InviteNotify Capability = "invite-notify" MessageTags Capability = "draft/message-tags" MultiPrefix Capability = "multi-prefix" SASL Capability = "sasl" @@ -31,6 +32,7 @@ var ( AccountNotify: true, AwayNotify: true, ExtendedJoin: true, + InviteNotify: true, MessageTags: true, MultiPrefix: true, SASL: true, diff --git a/irc/channel.go b/irc/channel.go index 80e4c9f4..e38f5024 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -91,8 +91,14 @@ func (channel *Channel) Names(client *Client) { client.Send(nil, client.server.name, RPL_ENDOFNAMES, client.nick, channel.name, "End of NAMES list") } +// ClientIsHalfOp returns whether client is at least a halfop. +func (channel *Channel) ClientIsHalfOp(client *Client) bool { + return client.flags[Operator] || channel.members.HasMode(client, Halfop) || channel.members.HasMode(client, ChannelOperator) || channel.members.HasMode(client, ChannelAdmin) || channel.members.HasMode(client, ChannelFounder) +} + +// ClientIsOperator returns whether client is at least a chanop. func (channel *Channel) ClientIsOperator(client *Client) bool { - return client.flags[Operator] || channel.members.HasMode(client, ChannelOperator) + return client.flags[Operator] || channel.members.HasMode(client, ChannelOperator) || channel.members.HasMode(client, ChannelAdmin) || channel.members.HasMode(client, ChannelFounder) } // Prefixes returns a list of prefixes for the given set of channel modes. @@ -485,10 +491,18 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client) { 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[InviteOnly] { channel.lists[InviteMask].Add(invitee.UserHost()) } + // send invite-notify + for member := range channel.members { + if member.capabilities[InviteNotify] && member != inviter && member != invitee && channel.ClientIsHalfOp(member) { + member.Send(nil, inviter.nickMaskString, "INVITE", invitee.nick, channel.name) + } + } + //TODO(dan): should inviter.server.name here be inviter.nickMaskString ? inviter.Send(nil, inviter.server.name, RPL_INVITING, invitee.nick, channel.name) invitee.Send(nil, inviter.nickMaskString, "INVITE", invitee.nick, channel.name)