Skip to content

Commit

Permalink
Add basic nick tracking functions.
Browse files Browse the repository at this point in the history
irc.SetupNickTracker() Adds nessesarry callbacks
irc.Channels Populated by said callvbacks
  • Loading branch information
thoj committed Jul 28, 2016
1 parent a6b1561 commit 980ef6b
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 980ef6b

Please sign in to comment.