commit
f3d1c7c294
@ -134,7 +134,7 @@ func (irc *Connection) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if irc.batchNegotiated && time.Since(lastExpireCheck) > irc.Timeout {
|
if irc.batchNegotiated() && time.Since(lastExpireCheck) > irc.Timeout {
|
||||||
irc.expireBatches(false)
|
irc.expireBatches(false)
|
||||||
lastExpireCheck = time.Now()
|
lastExpireCheck = time.Now()
|
||||||
}
|
}
|
||||||
@ -376,7 +376,7 @@ func (irc *Connection) Send(command string, params ...string) error {
|
|||||||
// If the server fails to respond correctly, the callback will be invoked with `nil`
|
// If the server fails to respond correctly, the callback will be invoked with `nil`
|
||||||
// as the argument.
|
// as the argument.
|
||||||
func (irc *Connection) SendWithLabel(callback func(*Batch), tags map[string]string, command string, params ...string) error {
|
func (irc *Connection) SendWithLabel(callback func(*Batch), tags map[string]string, command string, params ...string) error {
|
||||||
if !irc.labelNegotiated {
|
if !irc.labelNegotiated() {
|
||||||
return CapabilityNotNegotiated
|
return CapabilityNotNegotiated
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,14 +691,7 @@ func (irc *Connection) negotiateCaps() error {
|
|||||||
|
|
||||||
var acknowledgedCaps []string
|
var acknowledgedCaps []string
|
||||||
defer func() {
|
defer func() {
|
||||||
irc.stateMutex.Lock()
|
irc.processAckedCaps(acknowledgedCaps)
|
||||||
defer irc.stateMutex.Unlock()
|
|
||||||
for _, c := range acknowledgedCaps {
|
|
||||||
irc.capsAcked[c] = irc.capsAdvertised[c]
|
|
||||||
}
|
|
||||||
_, irc.batchNegotiated = irc.capsAcked["batch"]
|
|
||||||
_, labelNegotiated := irc.capsAcked["labeled-response"]
|
|
||||||
irc.labelNegotiated = irc.batchNegotiated && labelNegotiated
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
irc.Send("CAP", "LS", "302")
|
irc.Send("CAP", "LS", "302")
|
||||||
|
@ -325,7 +325,7 @@ func (irc *Connection) runCallbacks(msg ircmsg.Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle batch start or end
|
// handle batch start or end
|
||||||
if irc.batchNegotiated {
|
if irc.batchNegotiated() {
|
||||||
if msg.Command == "BATCH" {
|
if msg.Command == "BATCH" {
|
||||||
irc.handleBatchCommand(msg)
|
irc.handleBatchCommand(msg)
|
||||||
return
|
return
|
||||||
@ -336,7 +336,7 @@ func (irc *Connection) runCallbacks(msg ircmsg.Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle labeled single command, or labeled ACK
|
// handle labeled single command, or labeled ACK
|
||||||
if irc.labelNegotiated {
|
if irc.labelNegotiated() {
|
||||||
if hasLabel, labelStr := msg.GetTag("label"); hasLabel {
|
if hasLabel, labelStr := msg.GetTag("label"); hasLabel {
|
||||||
var labelCallback LabelCallback
|
var labelCallback LabelCallback
|
||||||
if label := deserializeLabel(labelStr); label != 0 {
|
if label := deserializeLabel(labelStr); label != 0 {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/goshuirc/irc-go/ircmsg"
|
"github.com/goshuirc/irc-go/ircmsg"
|
||||||
@ -86,11 +87,10 @@ type Connection struct {
|
|||||||
// Connect() builds these with sufficient capacity to receive all expected
|
// Connect() builds these with sufficient capacity to receive all expected
|
||||||
// responses during negotiation. Sends to them are nonblocking, so anything
|
// responses during negotiation. Sends to them are nonblocking, so anything
|
||||||
// sent outside of negotiation will not cause the relevant callbacks to block.
|
// sent outside of negotiation will not cause the relevant callbacks to block.
|
||||||
welcomeChan chan empty // signals that we got 001 and we are now connected
|
welcomeChan chan empty // signals that we got 001 and we are now connected
|
||||||
saslChan chan saslResult // transmits the final outcome of SASL negotiation
|
saslChan chan saslResult // transmits the final outcome of SASL negotiation
|
||||||
capsChan chan capResult // transmits the final status of each CAP negotiated
|
capsChan chan capResult // transmits the final status of each CAP negotiated
|
||||||
batchNegotiated bool
|
capFlags uint32
|
||||||
labelNegotiated bool
|
|
||||||
|
|
||||||
// callback state
|
// callback state
|
||||||
eventsMutex sync.Mutex
|
eventsMutex sync.Mutex
|
||||||
@ -140,6 +140,56 @@ type Batch struct {
|
|||||||
Items []*Batch
|
Items []*Batch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
capFlagBatch uint32 = 1 << iota
|
||||||
|
capFlagMessageTags
|
||||||
|
capFlagLabeledResponse
|
||||||
|
capFlagMultiline
|
||||||
|
)
|
||||||
|
|
||||||
|
func (irc *Connection) processAckedCaps(acknowledgedCaps []string) {
|
||||||
|
irc.stateMutex.Lock()
|
||||||
|
defer irc.stateMutex.Unlock()
|
||||||
|
var hasBatch, hasLabel, hasTags, hasMultiline bool
|
||||||
|
for _, c := range acknowledgedCaps {
|
||||||
|
irc.capsAcked[c] = irc.capsAdvertised[c]
|
||||||
|
switch c {
|
||||||
|
case "batch":
|
||||||
|
hasBatch = true
|
||||||
|
case "labeled-response":
|
||||||
|
hasLabel = true
|
||||||
|
case "message-tags":
|
||||||
|
hasTags = true
|
||||||
|
case "draft/multiline", "multiline":
|
||||||
|
hasMultiline = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var capFlags uint32
|
||||||
|
if hasBatch {
|
||||||
|
capFlags |= capFlagBatch
|
||||||
|
}
|
||||||
|
if hasBatch && hasLabel {
|
||||||
|
capFlags |= capFlagLabeledResponse
|
||||||
|
}
|
||||||
|
if hasTags {
|
||||||
|
capFlags |= capFlagMessageTags
|
||||||
|
}
|
||||||
|
if hasTags && hasBatch && hasMultiline {
|
||||||
|
capFlags |= capFlagMultiline
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic.StoreUint32(&irc.capFlags, capFlags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (irc *Connection) batchNegotiated() bool {
|
||||||
|
return atomic.LoadUint32(&irc.capFlags)&capFlagBatch != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (irc *Connection) labelNegotiated() bool {
|
||||||
|
return atomic.LoadUint32(&irc.capFlags)&capFlagLabeledResponse != 0
|
||||||
|
}
|
||||||
|
|
||||||
func ExtractNick(source string) string {
|
func ExtractNick(source string) string {
|
||||||
nick, _, _ := SplitNUH(source)
|
nick, _, _ := SplitNUH(source)
|
||||||
return nick
|
return nick
|
||||||
|
Loading…
Reference in New Issue
Block a user