Merge branch 'fix23-source-id'

fixes #23
This commit is contained in:
Liam Stanley 2018-12-09 16:25:34 -08:00
commit 16faee0ef1
7 changed files with 54 additions and 51 deletions

@ -143,13 +143,13 @@ func handleJOIN(c *Client, e Event) {
channel = c.state.lookupChannel(channelName)
}
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user == nil {
if ok := c.state.createUser(e.Source.Name); !ok {
if ok := c.state.createUser(e.Source); !ok {
c.state.Unlock()
return
}
user = c.state.lookupUser(e.Source.Name)
user = c.state.lookupUser(e.Source.ID())
}
defer c.state.notify(c, UPDATE_STATE)
@ -169,7 +169,7 @@ func handleJOIN(c *Client, e Event) {
}
c.state.Unlock()
if e.Source.Name == c.GetNick() {
if e.Source.ID() == ToRFC1459(c.GetNick()) {
// If it's us, don't just add our user to the list. Run a WHO which
// will tell us who exactly is in the entire channel.
c.Send(&Event{Command: WHO, Params: []string{channelName, "%tacuhnr,1"}})
@ -209,7 +209,7 @@ func handlePART(c *Client, e Event) {
defer c.state.notify(c, UPDATE_STATE)
if e.Source.Name == c.GetNick() {
if e.Source.ID() == ToRFC1459(c.GetNick()) {
c.state.Lock()
c.state.deleteChannel(channel)
c.state.Unlock()
@ -217,7 +217,7 @@ func handlePART(c *Client, e Event) {
}
c.state.Lock()
c.state.deleteUser(channel, e.Source.Name)
c.state.deleteUser(channel, e.Source.ID())
c.state.Unlock()
}
@ -327,9 +327,9 @@ func handleNICK(c *Client, e Event) {
c.state.Lock()
// renameUser updates the LastActive time automatically.
if len(e.Params) == 1 {
c.state.renameUser(e.Source.Name, e.Params[0])
c.state.renameUser(e.Source.ID(), e.Params[0])
} else if len(e.Trailing) > 0 {
c.state.renameUser(e.Source.Name, e.Trailing)
c.state.renameUser(e.Source.ID(), e.Trailing)
}
c.state.Unlock()
c.state.notify(c, UPDATE_STATE)
@ -341,12 +341,12 @@ func handleQUIT(c *Client, e Event) {
return
}
if e.Source.Name == c.GetNick() {
if e.Source.ID() == ToRFC1459(c.GetNick()) {
return
}
c.state.Lock()
c.state.deleteUser("", e.Source.Name)
c.state.deleteUser("", e.Source.ID())
c.state.Unlock()
c.state.notify(c, UPDATE_STATE)
}
@ -443,8 +443,9 @@ func handleNAMES(c *Client, e Event) {
parts := strings.Split(e.Trailing, " ")
var host, ident, modes, nick string
var modes, nick string
var ok bool
s := &Source{}
c.state.Lock()
for i := 0; i < len(parts); i++ {
@ -455,36 +456,29 @@ func handleNAMES(c *Client, e Event) {
// If userhost-in-names.
if strings.Contains(nick, "@") {
s := ParseSource(nick)
s = ParseSource(nick)
if s == nil {
continue
}
host = s.Host
nick = s.Name
ident = s.Ident
} else {
s = &Source{
Name: nick,
}
if !IsValidNick(s.Name) {
continue
}
}
if !IsValidNick(nick) {
continue
}
c.state.createUser(nick)
user := c.state.lookupUser(nick)
c.state.createUser(s)
user := c.state.lookupUser(s.ID())
if user == nil {
continue
}
user.addChannel(channel.Name)
channel.addUser(nick)
// Add necessary userhost-in-names data into the user.
if host != "" {
user.Host = host
}
if ident != "" {
user.Ident = ident
}
channel.addUser(s.ID())
// Don't append modes, overwrite them.
perms, _ := user.Perms.Lookup(channel.Name)
@ -507,7 +501,7 @@ func updateLastActive(c *Client, e Event) {
c.state.Lock()
// Update the users last active time, if they exist.
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user == nil {
c.state.Unlock()
return

6
cap.go

@ -193,7 +193,7 @@ func handleCHGHOST(c *Client, e Event) {
}
c.state.Lock()
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user != nil {
user.Ident = e.Params[0]
user.Host = e.Params[1]
@ -206,7 +206,7 @@ func handleCHGHOST(c *Client, e Event) {
// when users are no longer away, or when they are away.
func handleAWAY(c *Client, e Event) {
c.state.Lock()
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user != nil {
user.Extras.Away = e.Trailing
}
@ -229,7 +229,7 @@ func handleACCOUNT(c *Client, e Event) {
}
c.state.Lock()
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user != nil {
user.Extras.Account = account
}

@ -25,7 +25,7 @@ func handleTags(c *Client, e Event) {
}
c.state.Lock()
user := c.state.lookupUser(e.Source.Name)
user := c.state.lookupUser(e.Source.ID())
if user != nil {
user.Extras.Account = account
}

@ -374,7 +374,7 @@ func (c *Client) readLoop(ctx context.Context, errs chan error, wg *sync.WaitGro
// Check if it's an echo-message.
if !c.Config.disableTracking {
event.Echo = (event.Command == PRIVMSG || event.Command == NOTICE) &&
event.Source != nil && event.Source.Name == c.GetNick()
event.Source != nil && event.Source.ID() == ToRFC1459(c.GetNick())
}
c.rx <- event

18
ctcp.go

@ -155,8 +155,8 @@ func (c *CTCP) call(client *Client, event *CTCPEvent) {
}
// Send a ERRMSG reply, if we know who sent it.
if event.Source != nil && IsValidNick(event.Source.Name) {
client.Cmd.SendCTCPReply(event.Source.Name, CTCP_ERRMSG, "that is an unknown CTCP query")
if event.Source != nil && IsValidNick(event.Source.ID()) {
client.Cmd.SendCTCPReply(event.Source.ID(), CTCP_ERRMSG, "that is an unknown CTCP query")
}
return
}
@ -248,7 +248,7 @@ func handleCTCPPing(client *Client, ctcp CTCPEvent) {
if ctcp.Reply {
return
}
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_PING, ctcp.Text)
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_PING, ctcp.Text)
}
// handleCTCPPong replies with a pong.
@ -256,7 +256,7 @@ func handleCTCPPong(client *Client, ctcp CTCPEvent) {
if ctcp.Reply {
return
}
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_PONG, "")
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_PONG, "")
}
// handleCTCPVersion replies with the name of the client, Go version, as well
@ -264,12 +264,12 @@ func handleCTCPPong(client *Client, ctcp CTCPEvent) {
// arm, etc).
func handleCTCPVersion(client *Client, ctcp CTCPEvent) {
if client.Config.Version != "" {
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_VERSION, client.Config.Version)
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_VERSION, client.Config.Version)
return
}
client.Cmd.SendCTCPReplyf(
ctcp.Source.Name, CTCP_VERSION,
ctcp.Source.ID(), CTCP_VERSION,
"girc (github.com/lrstanley/girc) using %s (%s, %s)",
runtime.Version(), runtime.GOOS, runtime.GOARCH,
)
@ -277,13 +277,13 @@ func handleCTCPVersion(client *Client, ctcp CTCPEvent) {
// handleCTCPSource replies with the public git location of this library.
func handleCTCPSource(client *Client, ctcp CTCPEvent) {
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_SOURCE, "https://github.com/lrstanley/girc")
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_SOURCE, "https://github.com/lrstanley/girc")
}
// handleCTCPTime replies with a RFC 1123 (Z) formatted version of Go's
// local time.
func handleCTCPTime(client *Client, ctcp CTCPEvent) {
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_TIME, ":"+time.Now().Format(time.RFC1123Z))
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_TIME, ":"+time.Now().Format(time.RFC1123Z))
}
// handleCTCPFinger replies with the realname and idle time of the user. This
@ -293,5 +293,5 @@ func handleCTCPFinger(client *Client, ctcp CTCPEvent) {
active := client.conn.lastActive
client.conn.mu.RUnlock()
client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_FINGER, fmt.Sprintf("%s -- idle %s", client.Config.Name, time.Since(active)))
client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_FINGER, fmt.Sprintf("%s -- idle %s", client.Config.Name, time.Since(active)))
}

@ -516,7 +516,8 @@ const (
// Source represents the sender of an IRC event, see RFC1459 section 2.3.1.
// <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
type Source struct {
// Name is the nickname, server name, or service name.
// Name is the nickname, server name, or service name, in its original
// non-rfc1459 form.
Name string `json:"name"`
// Ident is commonly known as the "user".
Ident string `json:"ident"`
@ -525,6 +526,12 @@ type Source struct {
Host string `json:"host"`
}
// ID is the nickname, server name, or service name, in it's converted
// and comparable) form.
func (s *Source) ID() string {
return ToRFC1459(s.Name)
}
// Equals compares two Sources for equality.
func (s *Source) Equals(ss *Source) bool {
if s == nil && ss == nil {
@ -533,7 +540,7 @@ func (s *Source) Equals(ss *Source) bool {
if s != nil && ss == nil || s == nil && ss != nil {
return false
}
if s.Name != ss.Name || s.Ident != ss.Ident || s.Host != ss.Host {
if s.ID() != ss.ID() || s.Ident != ss.Ident || s.Host != ss.Host {
return false
}
return true

@ -419,14 +419,16 @@ func (s *state) lookupUser(name string) *User {
}
// createUser creates the user in state, if not already done.
func (s *state) createUser(nick string) (ok bool) {
if _, ok := s.users[ToRFC1459(nick)]; ok {
func (s *state) createUser(src *Source) (ok bool) {
if _, ok := s.users[src.ID()]; ok {
// User already exists.
return false
}
s.users[ToRFC1459(nick)] = &User{
Nick: nick,
s.users[src.ID()] = &User{
Nick: src.Name,
Host: src.Host,
Ident: src.Ident,
FirstSeen: time.Now(),
LastActive: time.Now(),
Perms: &UserPerms{channels: make(map[string]Perms)},