diff --git a/channel.go b/channel.go index cc889ba..fa8c71c 100644 --- a/channel.go +++ b/channel.go @@ -49,6 +49,10 @@ func (channel *Channel) Handle(event *Event, client *Client) { { channel.userlist.Remove(event.Nick) } + case "packet.nick": + { + channel.userlist.Rename(event.Nick, event.Arg(0)) + } case "packet.account": { newAccount := event.Arg(0) @@ -59,6 +63,14 @@ func (channel *Channel) Handle(event *Event, client *Client) { channel.userlist.Patch(event.Nick, list.UserPatch{ClearAccount: true}) } } + case "packet.away": + { + if event.Text != "" { + channel.userlist.Patch(event.Nick, list.UserPatch{Away: event.Text}) + } else { + channel.userlist.Patch(event.Nick, list.UserPatch{ClearAway: true}) + } + } case "packet.chghost": { newUser := event.Arg(0) diff --git a/client.go b/client.go index cb88ada..c6cd894 100644 --- a/client.go +++ b/client.go @@ -27,6 +27,7 @@ var supportedCaps = []string{ "multi-prefix", "userhost-in-names", "account-notify", + "away-notify", "extended-join", "chghost", } @@ -630,7 +631,7 @@ func (client *Client) handleEvent(event *Event) { } } - case "packer.nick": + case "packet.nick": { client.handleInTargets(event.Nick, event) @@ -858,11 +859,17 @@ func (client *Client) handleEvent(event *Event) { } } - // Account handling + // account-notify case "packet.account": { client.handleInTargets(event.Nick, event) } + + // away-notify + case "packet.away": + { + client.handleInTargets(event.Nick, event) + } } if len(event.targets) == 0 { diff --git a/client_test.go b/client_test.go index 6b59b64..a67f7f1 100644 --- a/client_test.go +++ b/client_test.go @@ -71,7 +71,7 @@ func TestClient(t *testing.T) { {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 MODE #Test +N-s "}, {Kind: 'S', Data: ":Test1234!~test2@172.17.37.1 JOIN #Test Test1234"}, {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 MODE #Test +v Test1234"}, - {Kind: 'S', Data: "PING :archgisle.lan"}, + {Kind: 'S', Data: "PING :archgisle.lan"}, // Ping/Pong to sync. {Kind: 'C', Data: "PONG :archgisle.lan"}, {Callback: func() error { channel := client.Channel("#Test") @@ -92,6 +92,44 @@ func TestClient(t *testing.T) { return errors.New("Test1234 did not get account from extended-join") } + return nil + }}, + {Kind: 'S', Data: ":Test1234!~test2@172.17.37.1 NICK Hunter2"}, + {Kind: 'S', Data: ":Hunter2!~test2@172.17.37.1 AWAY :Doing stuff"}, + {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 AWAY"}, + {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 PART #Test :Leaving the channel"}, + {Kind: 'S', Data: "PING :archgisle.lan"}, // Ping/Pong to sync. + {Kind: 'C', Data: "PONG :archgisle.lan"}, + {Callback: func() error { + channel := client.Channel("#Test") + if channel == nil { + return errors.New("Channel #Test not found") + } + + err := irctest.AssertUserlist(t, channel, "@Test768", "+Hunter2") + if err != nil { + return err + } + + _, ok := channel.UserList().User("Test1234") + if ok { + return errors.New("Test1234 is still there") + } + + userHunter2, ok := channel.UserList().User("Hunter2") + if !ok { + return errors.New("Test1234 not found") + } + if userHunter2.Account != "Test1234" { + return errors.New("Hunter2 did not persist account post nick change") + } + if !userHunter2.IsAway() { + return errors.New("Hunter2 should be away") + } + if userHunter2.Away != "Doing stuff" { + return errors.New("Hunter2 has the wrong away message: " + userHunter2.Away) + } + return nil }}, }, diff --git a/list/list.go b/list/list.go index 4fea52f..a1a0fe4 100644 --- a/list/list.go +++ b/list/list.go @@ -253,6 +253,10 @@ func (list *List) Patch(nick string, patch UserPatch) (ok bool) { user.Account = patch.Account } + if patch.Away != "" || patch.ClearAway { + user.Away = patch.Away + } + if patch.User != "" { user.User = patch.User } diff --git a/list/user.go b/list/user.go index a4d9618..2a37d0a 100644 --- a/list/user.go +++ b/list/user.go @@ -6,6 +6,7 @@ type User struct { User string `json:"user,omitempty"` Host string `json:"host,omitempty"` Account string `json:"account,omitempty"` + Away string `json:"away,omitempty"` Modes string `json:"modes"` Prefixes string `json:"prefixes"` PrefixedNick string `json:"prefixedNick"` @@ -17,6 +18,8 @@ type UserPatch struct { Host string Account string ClearAccount bool + Away string + ClearAway bool } // HighestMode returns the highest mode. @@ -28,6 +31,11 @@ func (user *User) HighestMode() rune { return rune(user.Modes[0]) } +// IsAway returns true if user.Away is non-empty +func (user *User) IsAway() bool { + return user.Away != "" +} + // PrefixedNick gets the full nick. func (user *User) updatePrefixedNick() { if len(user.Prefixes) == 0 {