Skip to content

Commit

Permalink
Add basic nick tracking functions.
Browse files Browse the repository at this point in the history
irc.SetupNickTrack() Adds nessesarry callbacks
irc.Channels map Populated by said callbacks
irc.Channels["#chan"].Users[nickname]
  • Loading branch information
thoj committed Jul 28, 2016
1 parent a6b1561 commit 86d5996
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions irc.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ func IRC(nick, user string) *Connection {
PingFreq: 15 * time.Minute,
SASLMech: "PLAIN",
QuitMessage: "",
Channels: make(map[string]Channel),
}
irc.setupCallbacks()
return irc
Expand Down
103 changes: 103 additions & 0 deletions irc_nicktrack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package irc

import (
"regexp"
"strings"
)

//Struct to store Channel Info
type Channel struct {
Topic string
Mode string
Users map[string]User
}

type User struct {
Host string
Mode string
}

var mode_split = regexp.MustCompile("([%@+]{0,1})(.+)") //Half-Op, //Op, //Voice

func (irc *Connection) SetupNickTrack() {
// 353: RPL_NAMEREPLY per RFC1459
// will typically receive this on channel joins and when NAMES is
// called via GetNicksOnCHan
irc.AddCallback("353", func(e *Event) {
// get chan
channelName := e.Arguments[2]
// check if chan exists in map
_, ok := irc.Channels[channelName]

// if not make one
if ok != true {
irc.Channels[channelName] = Channel{Users: make(map[string]User)}
}
// split the datat into a slice
for _, modenick := range strings.Split(e.Message(), " ") {
nickandmode := mode_split.FindStringSubmatch(modenick)
u := User{}
if len(nickandmode) == 3 {
if nickandmode[1] == "@" {
u.Mode = "+o" // Ooof should be mode struct?
} else if nickandmode[1] == "+" {
u.Mode = "+v" // Ooof should be mode struct?
} else if nickandmode[1] == "%" {
u.Mode = "+h"
}
irc.Channels[channelName].Users[nickandmode[2]] = u
} else {
irc.Channels[channelName].Users[modenick] = u
}
}
})

irc.AddCallback("MODE", func(e *Event) {
channelName := e.Arguments[0]
if len(e.Arguments) == 3 { // 3 == for channel 2 == for user on server
if _, ok := irc.Channels[channelName]; ok != true {
irc.Channels[channelName] = Channel{Users: make(map[string]User)}
}
if _, ok := irc.Channels[channelName].Users[e.Arguments[2]]; ok != true {
irc.Channels[channelName].Users[e.Arguments[2]] = User{Mode: e.Arguments[1]}
} else {
u := irc.Channels[channelName].Users[e.Arguments[2]]
u.Mode = e.Arguments[1]
irc.Channels[channelName].Users[e.Arguments[2]] = u
}
}
})

//Really hacky since the message from the server does not include the channel
irc.AddCallback("NICK", func(e *Event) {
if len(e.Arguments) == 1 { // Sanity check
for k, _ := range irc.Channels {
if _, ok := irc.Channels[k].Users[e.Nick]; ok {
u := irc.Channels[k].Users[e.Nick]
u.Host = e.Host
irc.Channels[k].Users[e.Arguments[0]] = u //New nick
delete(irc.Channels[k].Users, e.Nick) //Delete old
}
}
}
})

irc.AddCallback("JOIN", func(e *Event) {
channelName := e.Arguments[0]
if _, ok := irc.Channels[channelName]; ok != true {
irc.Channels[channelName] = Channel{Users: make(map[string]User)}
}
irc.Channels[channelName].Users[e.Nick] = User{Host: e.Source}
})

irc.AddCallback("PART", func(e *Event) {
channelName := e.Arguments[0]
delete(irc.Channels[channelName].Users, e.Nick)
})

irc.AddCallback("QUIT", func(e *Event) {
for k, _ := range irc.Channels {
delete(irc.Channels[k].Users, e.Nick)
}
})
}
2 changes: 2 additions & 0 deletions irc_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type Connection struct {

stopped bool
quit bool

Channels map[string]Channel
}

// A struct to represent an event.
Expand Down
13 changes: 12 additions & 1 deletion irc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ func TestConnection(t *testing.T) {
teststr := randStr(20)
testmsgok := false

irccon1.SetupNickTrack()
irccon2.SetupNickTrack()

irccon1.AddCallback("001", func(e *Event) { irccon1.Join(channel) })
irccon2.AddCallback("001", func(e *Event) { irccon2.Join(channel) })
irccon1.AddCallback("366", func(e *Event) {
Expand All @@ -223,10 +226,18 @@ func TestConnection(t *testing.T) {
})

irccon2.AddCallback("PRIVMSG", func(e *Event) {
t.Log(e.Message())
if e.Message() == teststr {
if e.Nick == ircnick1 {
testmsgok = true
if _, ok := irccon2.Channels[channel]; !ok {
t.Error("Nick tracker did not create channel in map")
}
if _, ok := irccon2.Channels[channel].Users[ircnick1]; !ok {
t.Errorf("Nick tracker did not track other bot nick. List: %v", irccon2.Channels[channel].Users)
}
if _, ok := irccon2.Channels[channel].Users[ircnick2]; !ok {
t.Errorf("Nick tracker did not track own nick. List: %v", irccon2.Channels[channel].Users)
}
irccon2.Quit()
} else {
t.Fatal("Test message came from an unexpected nickname")
Expand Down

0 comments on commit 86d5996

Please sign in to comment.