Browse Source

fix nick change being done during capability negotiation.

master
Gisle Aune 4 years ago
parent
commit
9d8bbd4198
  1. 35
      client.go
  2. 2
      client_test.go

35
client.go

@ -850,6 +850,8 @@ func (client *Client) handleSendLoop() {
// handleEvent is always first and gets to break a few rules. // handleEvent is always first and gets to break a few rules.
func (client *Client) handleEvent(event *Event) { func (client *Client) handleEvent(event *Event) {
sentCapEnd := false
// IRCv3 `server-time` // IRCv3 `server-time`
if timeTag, ok := event.Tags["time"]; ok { if timeTag, ok := event.Tags["time"]; ok {
serverTime, err := time.Parse(time.RFC3339Nano, timeTag) serverTime, err := time.Parse(time.RFC3339Nano, timeTag)
@ -946,33 +948,36 @@ func (client *Client) handleEvent(event *Event) {
// Nick rotation // Nick rotation
case "packet.431", "packet.432", "packet.433", "packet.436": case "packet.431", "packet.432", "packet.433", "packet.436":
{ {
lockNickChange, _ := client.Value("internal.lockNickChange").(bool)
// Ignore if client is registered // Ignore if client is registered
if client.Nick() != "" { if client.Nick() != "" {
break break
} }
// Ignore if in middle of SASL authentication
if event.Verb() == "433" && client.Value("sasl.usingMethod") != nil {
break
}
nick := event.Args[1] nick := event.Args[1]
newNick := ""
// "AltN" -> "AltN+1", ... // "AltN" -> "AltN+1", ...
prev := client.config.Nick prev := client.config.Nick
sent := false
for _, alt := range client.config.Alternatives { for _, alt := range client.config.Alternatives {
if nick == prev { if nick == prev {
_ = client.Sendf("NICK %s", alt)
sent = true
newNick = alt
break break
} }
prev = alt prev = alt
} }
if !sent {
if newNick == "" {
// "LastAlt" -> "Nick23962" // "LastAlt" -> "Nick23962"
_ = client.Sendf("NICK %s%05d", client.config.Nick, mathRand.Int31n(99999))
newNick = fmt.Sprintf("%s%05d", client.config.Nick, mathRand.Int31n(99999))
}
if lockNickChange {
client.SetValue("internal.primedNickChange", newNick)
} else {
_ = client.Sendf("NICK %s", newNick)
} }
} }
@ -1008,6 +1013,8 @@ func (client *Client) handleEvent(event *Event) {
switch capCommand { switch capCommand {
case "LS": case "LS":
{ {
client.SetValue("internal.lockNickChange", true)
for _, token := range capTokens { for _, token := range capTokens {
split := strings.SplitN(token, "=", 2) split := strings.SplitN(token, "=", 2)
key := split[0] key := split[0]
@ -1042,6 +1049,7 @@ func (client *Client) handleEvent(event *Event) {
_ = client.Send("CAP REQ :" + requestedCaps) _ = client.Send("CAP REQ :" + requestedCaps)
} else { } else {
sentCapEnd = true
_ = client.Send("CAP END") _ = client.Send("CAP END")
} }
} }
@ -1122,6 +1130,7 @@ func (client *Client) handleEvent(event *Event) {
} }
if !client.Ready() { if !client.Ready() {
sentCapEnd = true
_ = client.Send("CAP END") _ = client.Send("CAP END")
} }
} }
@ -1464,6 +1473,14 @@ func (client *Client) handleEvent(event *Event) {
} }
} }
if sentCapEnd {
client.SetValue("internal.lockNickChange", false)
if primedNick, _ := client.Value("internal.primedNickChange").(string); primedNick != "" {
_ = client.Sendf("NICK %s", primedNick)
}
}
if len(event.targets) == 0 { if len(event.targets) == 0 {
client.handleInTarget(client.status, event) client.handleInTarget(client.status, event)
} }

2
client_test.go

@ -37,6 +37,7 @@ func TestClient(t *testing.T) {
{Client: "USER Tester 8 * :..."}, {Client: "USER Tester 8 * :..."},
{Server: ":testserver.example.com NOTICE * :*** Checking your bits..."}, {Server: ":testserver.example.com NOTICE * :*** Checking your bits..."},
{Server: ":testserver.example.com CAP * LS :multi-prefix chghost userhost-in-names vendorname/custom-stuff echo-message =malformed vendorname/advanced-custom-stuff=things,and,items"}, {Server: ":testserver.example.com CAP * LS :multi-prefix chghost userhost-in-names vendorname/custom-stuff echo-message =malformed vendorname/advanced-custom-stuff=things,and,items"},
{Server: ":testserver.example.com 433 * Test :Nick is not available"},
{Client: "CAP REQ :multi-prefix chghost userhost-in-names echo-message"}, {Client: "CAP REQ :multi-prefix chghost userhost-in-names echo-message"},
{Server: ":testserver.example.com CAP * ACK :multi-prefix userhost-in-names"}, {Server: ":testserver.example.com CAP * ACK :multi-prefix userhost-in-names"},
{Client: "CAP END"}, {Client: "CAP END"},
@ -56,7 +57,6 @@ func TestClient(t *testing.T) {
return nil return nil
}}, }},
{Server: ":testserver.example.com 433 * Test :Nick is not available"},
{Client: "NICK Test2"}, {Client: "NICK Test2"},
{Server: ":testserver.example.com 433 * Test2 :Nick is not available"}, {Server: ":testserver.example.com 433 * Test2 :Nick is not available"},
{Client: "NICK Test3"}, {Client: "NICK Test3"},

Loading…
Cancel
Save