mirror of
https://github.com/ergochat/ergo.git
synced 2025-02-16 21:50:39 +01:00
capability: Add 3.2 CAP values
This commit is contained in:
parent
9162d0da61
commit
e643c2101f
@ -12,8 +12,9 @@ Improved compatibility, more features, etc.
|
|||||||
### Security
|
### Security
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* Added integrated help.
|
* Added integrated help (with the `/HELP` command).
|
||||||
* Support for IRCv3 capability [`account-notify`](http://ircv3.net/specs/extensions/account-notify-3.1.html), and draft capability [`message-tags`](http://ircv3.net/specs/core/message-tags-3.3.html) as `draft/message-tags`.
|
* 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), and draft capability [`message-tags`](http://ircv3.net/specs/core/message-tags-3.3.html) as `draft/message-tags`.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Casemapping changed from custom unicode mapping to preliminary [rfc7700](https://github.com/ircv3/ircv3-specifications/pull/272) mapping.
|
* Casemapping changed from custom unicode mapping to preliminary [rfc7700](https://github.com/ircv3/ircv3-specifications/pull/272) mapping.
|
||||||
@ -43,7 +44,7 @@ Initial release of Oragono!
|
|||||||
* Ability to parse complex mode change syntax commonly used these days (i.e. `+h-ov dan dan dan`).
|
* Ability to parse complex mode change syntax commonly used these days (i.e. `+h-ov dan dan dan`).
|
||||||
* User mode for clients connected via TLS (`+Z`).
|
* User mode for clients connected via TLS (`+Z`).
|
||||||
* Ability to register and login to accounts (with passphrase or certfp).
|
* Ability to register and login to accounts (with passphrase or certfp).
|
||||||
* Support for IRCv3 capabilities [`account-tag`](http://ircv3.net/specs/extensions/account-tag-3.2.html), [`away-notify`](http://ircv3.net/specs/extensions/away-notify-3.1.html), [`extended-join`](http://ircv3.net/specs/extensions/extended-join-3.1.html), [`sasl`](http://ircv3.net/specs/extensions/sasl-3.1.html), [`server-time`](http://ircv3.net/specs/extensions/server-time-3.2.html), and [`userhost-in-names`](http://ircv3.net/specs/extensions/userhost-in-names-3.2.html).
|
* Added support for IRCv3 capabilities [`account-tag`](http://ircv3.net/specs/extensions/account-tag-3.2.html), [`away-notify`](http://ircv3.net/specs/extensions/away-notify-3.1.html), [`extended-join`](http://ircv3.net/specs/extensions/extended-join-3.1.html), [`sasl`](http://ircv3.net/specs/extensions/sasl-3.1.html), [`server-time`](http://ircv3.net/specs/extensions/server-time-3.2.html), and [`userhost-in-names`](http://ircv3.net/specs/extensions/userhost-in-names-3.2.html).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Channel creator (`O`) privilege changed to founder/admin/halfops (`qah`) privileges.
|
* Channel creator (`O`) privilege changed to founder/admin/halfops (`qah`) privileges.
|
||||||
|
@ -37,6 +37,9 @@ var (
|
|||||||
ServerTime: true,
|
ServerTime: true,
|
||||||
UserhostInNames: true,
|
UserhostInNames: true,
|
||||||
}
|
}
|
||||||
|
CapValues = map[Capability]string{
|
||||||
|
SASL: "PLAIN,EXTERNAL",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (capability Capability) String() string {
|
func (capability Capability) String() string {
|
||||||
@ -65,14 +68,32 @@ const (
|
|||||||
CapNegotiated CapState = iota
|
CapNegotiated CapState = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CapVersion is used to select which max version of CAP the client supports.
|
||||||
|
type CapVersion uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Cap301 refers to the base CAP spec.
|
||||||
|
Cap301 CapVersion = 301
|
||||||
|
// Cap302 refers to the IRCv3.2 CAP spec.
|
||||||
|
Cap302 CapVersion = 302
|
||||||
|
)
|
||||||
|
|
||||||
|
// CapabilitySet is used to track supported, enabled, and existing caps.
|
||||||
type CapabilitySet map[Capability]bool
|
type CapabilitySet map[Capability]bool
|
||||||
|
|
||||||
func (set CapabilitySet) String() string {
|
func (set CapabilitySet) String(version CapVersion) string {
|
||||||
strs := make([]string, len(set))
|
strs := make([]string, len(set))
|
||||||
index := 0
|
index := 0
|
||||||
for capability := range set {
|
for capability := range set {
|
||||||
strs[index] = string(capability)
|
capString := string(capability)
|
||||||
index += 1
|
if version == Cap302 {
|
||||||
|
val, exists := CapValues[capability]
|
||||||
|
if exists {
|
||||||
|
capString += "=" + val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strs[index] = capString
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
return strings.Join(strs, " ")
|
return strings.Join(strs, " ")
|
||||||
}
|
}
|
||||||
@ -108,13 +129,17 @@ func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
if !client.registered {
|
if !client.registered {
|
||||||
client.capState = CapNegotiating
|
client.capState = CapNegotiating
|
||||||
}
|
}
|
||||||
// client.server needs to be here to workaround a parsing bug in weechat 1.4
|
if len(msg.Params) > 1 && msg.Params[1] == "302" {
|
||||||
// and let it connect to the server (otherwise it doesn't respond to the CAP
|
client.capVersion = 302
|
||||||
// message with anything and just hangs on connection)
|
}
|
||||||
client.Send(nil, server.name, "CAP", client.nick, subCommand, SupportedCapabilities.String())
|
// weechat 1.4 has a bug here where it won't accept the CAP reply unless it contains
|
||||||
|
// the server.name source... otherwise it doesn't respond to the CAP message with
|
||||||
|
// anything and just hangs on connection.
|
||||||
|
//TODO(dan): limit number of caps and send it multiline in 3.2 style as appropriate.
|
||||||
|
client.Send(nil, server.name, "CAP", client.nick, subCommand, SupportedCapabilities.String(client.capVersion))
|
||||||
|
|
||||||
case "LIST":
|
case "LIST":
|
||||||
client.Send(nil, server.name, "CAP", client.nick, subCommand, client.capabilities.String())
|
client.Send(nil, server.name, "CAP", client.nick, subCommand, client.capabilities.String(Cap301)) // values not sent on LIST so force 3.1
|
||||||
|
|
||||||
case "REQ":
|
case "REQ":
|
||||||
// make sure all capabilities actually exist
|
// make sure all capabilities actually exist
|
||||||
|
@ -33,6 +33,7 @@ type Client struct {
|
|||||||
awayMessage string
|
awayMessage string
|
||||||
capabilities CapabilitySet
|
capabilities CapabilitySet
|
||||||
capState CapState
|
capState CapState
|
||||||
|
capVersion CapVersion
|
||||||
certfp string
|
certfp string
|
||||||
channels ChannelSet
|
channels ChannelSet
|
||||||
ctime time.Time
|
ctime time.Time
|
||||||
@ -64,8 +65,9 @@ func NewClient(server *Server, conn net.Conn, isTLS bool) *Client {
|
|||||||
client := &Client{
|
client := &Client{
|
||||||
atime: now,
|
atime: now,
|
||||||
authorized: server.password == nil,
|
authorized: server.password == nil,
|
||||||
capState: CapNone,
|
|
||||||
capabilities: make(CapabilitySet),
|
capabilities: make(CapabilitySet),
|
||||||
|
capState: CapNone,
|
||||||
|
capVersion: Cap301,
|
||||||
channels: make(ChannelSet),
|
channels: make(ChannelSet),
|
||||||
ctime: now,
|
ctime: now,
|
||||||
flags: make(map[UserMode]bool),
|
flags: make(map[UserMode]bool),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user