commit e1967c5e1d907594d55e30010579bf997f72e734
parent 65e10c4665d32d325c0a174999bef69ac89e0ab4
Author: sin <sin@2f30.org>
Date: Fri, 3 May 2013 14:27:57 +0100
update irc
Diffstat:
4 files changed, 133 insertions(+), 88 deletions(-)
diff --git a/src/irc/events.go b/src/irc/events.go
@@ -4,10 +4,6 @@ import (
"fmt"
)
-const (
- MAX_EVENTS = 16
-)
-
type IrcEvent struct {
Command string
Fn func(IrcMessage)
diff --git a/src/irc/irc.go b/src/irc/irc.go
@@ -8,7 +8,7 @@ import (
)
type IrcContext struct {
- conn net.Conn // Actual connection
+ conn net.Conn // actual connection
outgoingMsg chan IrcMessage // TX messaging channel
incomingMsg chan IrcMessage // RX messaging channel
ev []IrcEvent // slice of callbacks
@@ -18,14 +18,14 @@ type IrcContext struct {
}
type IrcConfig struct {
- Network string // network name
- Nick string // nickname
- User string // username
- Pass string // password
- Serv string // server address
- Port string // server port
- Tls bool // enable/disable ssl
- Ipv6 bool // enable/disable ipv6 (not implemented)
+ NetworkName string // network name
+ Nick string // nickname
+ User string // username
+ Pass string // password
+ Serv string // server address
+ Port string // server port
+ Tls bool // enable/disable ssl
+ Ipv6 bool // enable/disable ipv6 (not implemented)
}
type ircChan struct {
@@ -34,45 +34,43 @@ type ircChan struct {
}
type ircNetwork struct {
- network string // network name
- nick string // nickname
- user string // username
- pass string // password
- serv string // server address
- port string // server port
- tls bool // enable/disable ssl
- ipv6 bool // enable/disable ipv6 (not implemented)
- channels [32]ircChan // a maximum of 32 channels for now
- channum int // number of channels
+ name string // network name
+ nick string // nickname
+ user string // username
+ pass string // password
+ serv string // server address
+ port string // server port
+ tls bool // enable/disable ssl
+ ipv6 bool // enable/disable ipv6 (not implemented)
+ channels []ircChan // slice of channels
}
// Create a new IrcContext
func NewIrcContext(ircConfig IrcConfig) *IrcContext {
network := ircNetwork{
- network: ircConfig.Network,
- nick: ircConfig.Nick,
- user: ircConfig.User,
- pass: ircConfig.Pass,
- serv: ircConfig.Serv,
- port: ircConfig.Port,
- tls: ircConfig.Tls,
- ipv6: ircConfig.Ipv6,
+ name: ircConfig.NetworkName,
+ nick: ircConfig.Nick,
+ user: ircConfig.User,
+ pass: ircConfig.Pass,
+ serv: ircConfig.Serv,
+ port: ircConfig.Port,
+ tls: ircConfig.Tls,
+ ipv6: ircConfig.Ipv6,
+ channels: make([]ircChan, 0),
}
return &IrcContext{
outgoingMsg: make(chan IrcMessage),
incomingMsg: make(chan IrcMessage),
- ev: make([]IrcEvent, 0, MAX_EVENTS),
+ ev: make([]IrcEvent, 0),
network: network,
intercepts: make([]*chan IrcMessage, 0),
}
}
-// Appends a new channel pointer to intercept rx
func (i *IrcContext) AddIntercept(a *chan IrcMessage) {
i.intercepts = append(i.intercepts, a)
}
-// Deletes based on pointer equality. caller must hold ref.
func (i *IrcContext) DelIntercept(ap *chan IrcMessage) error {
for j := 0; j < len(i.intercepts); j++ {
if ap == i.intercepts[j] {
@@ -87,40 +85,52 @@ func (i *IrcContext) DelIntercept(ap *chan IrcMessage) error {
return fmt.Errorf("Intercept not found")
}
-// Add a channel to the set of channels
func (i *IrcContext) AddChannel(s string) error {
- for c := 0; c < i.network.channum; c++ {
- if i.network.channels[c].name == s {
+ for _, v := range i.network.channels {
+ if v.name == s {
return fmt.Errorf("Channel %s already added", s)
}
}
- if i.network.channum+1 < len(i.network.channels) {
- i.network.channels[i.network.channum] = ircChan{s, false}
- i.network.channum++
- return nil
+ i.network.channels = append(i.network.channels, ircChan{s, false})
+ return nil
+}
+
+func (i *IrcContext) JoinChannel(s string) error {
+ for c, v := range i.network.channels {
+ if v.name == s {
+ if !v.joined {
+ i.Join(v.name)
+ i.network.channels[c].joined = true
+ return nil
+ } else {
+ return fmt.Errorf("Already joined on channel %s", s)
+ }
+ }
}
- return fmt.Errorf("Too many channels added")
+ return fmt.Errorf("Can't find channel %s", s)
}
-// Join all channels
-func (i *IrcContext) JoinChannels() {
- for c := 0; c < i.network.channum; c++ {
- if !i.network.channels[c].joined {
- i.Join(i.network.channels[c].name)
+func (i *IrcContext) JoinChannels() error {
+ for c, v := range i.network.channels {
+ if !v.joined {
+ if err := i.JoinChannel(v.name); err != nil {
+ return err
+ }
i.network.channels[c].joined = true
}
}
+ return nil
}
func (i *IrcContext) PartChannel(s string) error {
- for c := 0; c < i.network.channum; c++ {
- if i.network.channels[c].name == s {
- if i.network.channels[c].joined {
+ for c, v := range i.network.channels {
+ if v.name == s {
+ if v.joined {
i.Part(s)
i.network.channels[c].joined = false
return nil
} else {
- return fmt.Errorf("Channel %s is not joined\n", s)
+ return fmt.Errorf("Channel %s is not joined", s)
}
}
}
@@ -141,27 +151,27 @@ func (i *IrcContext) Connect() error {
service := i.network.serv + ":" + i.network.port
if i.network.tls {
- conf, err := loadCerts()
- if err != nil {
- return err
- }
- conn, err := tls.Dial("tcp", service, conf)
- if err != nil {
+ if conf, err := loadCerts(); err != nil {
return err
+ } else {
+ if conn, err := tls.Dial("tcp", service, conf); err != nil {
+ return err
+ } else {
+ i.conn = conn
+ }
}
- i.conn = conn
} else {
- conn, err := net.Dial("tcp", service)
- if err != nil {
+ if conn, err := net.Dial("tcp", service); err != nil {
return err
+ } else {
+ i.conn = conn
}
- i.conn = conn
}
// Fire off the goroutines now!
go i.incomingMsgLoop()
go i.outgoingMsgLoop()
- go i.readLoop()
+ go i.RxRawMessages()
i.Nick()
i.User()
@@ -178,7 +188,7 @@ func (i *IrcContext) read(buf []byte) (int, error) {
// This is the actual raw read loop. Here we parse the incoming bytes
// and form messages.
-func (i *IrcContext) readLoop() error {
+func (i *IrcContext) RxRawMessages() error {
for {
var buf [512]byte
n, err := i.read(buf[0:])
@@ -188,16 +198,6 @@ func (i *IrcContext) readLoop() error {
fmt.Println(string(buf[0 : n-1]))
s := string(buf[0:n])
- if strings.HasPrefix(s, "PING :") {
- r := strings.Replace(s, "PING :", "PONG :", 6)
- r = strings.TrimSpace(r) + "\r\n"
- err := i.TxRawMessage([]byte(r))
- if err != nil {
- return err
- }
- continue
- }
-
msg := i.ParseRawMessage(s)
i.incomingMsg <- msg
for _, v := range i.intercepts {
@@ -206,3 +206,48 @@ func (i *IrcContext) readLoop() error {
}
return nil
}
+
+// Transmit a raw message
+func (i *IrcContext) TxRawMessage(msg []byte) error {
+ _, err := i.conn.Write(msg[0:])
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (i *IrcContext) String() string {
+ s := fmt.Sprintf("IRC CONTEXT DUMP")
+ if len(i.ev) == 0 {
+ s += fmt.Sprintf("\n\tEvent handlers: [NONE]\n")
+ } else {
+ s += fmt.Sprintf("\n\tEvent handlers: [%d]\n", len(i.ev))
+ for _, v := range i.ev {
+ s += fmt.Sprintf("\t\tCommand: %s\n", v.Command)
+ }
+ }
+ s += fmt.Sprintf("\tNetwork:\n")
+ s += fmt.Sprintf("\t\tName: %s\n", i.network.name)
+ s += fmt.Sprintf("\t\tNick: %s\n", i.network.nick)
+ s += fmt.Sprintf("\t\tUser: %s\n", i.network.user)
+ if i.network.pass != "" {
+ s += fmt.Sprintf("\t\tPass: %s\n", i.network.pass)
+ } else {
+ s += fmt.Sprintf("\t\tPass: [NONE]\n")
+ }
+ s += fmt.Sprintf("\t\tServer: %s\n", i.network.serv)
+ if i.network.tls {
+ s += fmt.Sprintf("\t\tTLS: on")
+ } else {
+ s += fmt.Sprintf("\t\tTLS: off")
+ }
+ if len(i.network.channels) == 0 {
+ s += fmt.Sprintf("\n\t\tChannels: [NONE]")
+ } else {
+ s += fmt.Sprintf("\n\t\tChannels: [%d]\n", len(i.network.channels))
+ for _, v := range i.network.channels {
+ s += fmt.Sprintf("\t\t\tName: %s\n", v.name)
+ }
+ }
+ return strings.TrimSpace(s)
+}
diff --git a/src/irc/message.go b/src/irc/message.go
@@ -17,6 +17,15 @@ const (
IRCTEXT
)
+// Send PONG reply
+func (i *IrcContext) Pong(host string) {
+ msg := IrcMessage{
+ Command: "PONG",
+ Args: []string{":" + host},
+ }
+ i.outgoingMsg <- msg
+}
+
// Send the nickname
func (i *IrcContext) Nick() {
msg := IrcMessage{
@@ -109,15 +118,6 @@ func (i *IrcContext) UnpackMessage(msg IrcMessage) []byte {
return []byte(rawMsg)
}
-// Transmit a raw message
-func (i *IrcContext) TxRawMessage(msg []byte) error {
- _, err := i.conn.Write(msg[0:])
- if err != nil {
- return err
- }
- return nil
-}
-
func (i *IrcContext) incomingMsgLoop() error {
for {
select {
diff --git a/src/kunt/kunt.go b/src/kunt/kunt.go
@@ -359,12 +359,12 @@ func main() {
}
cfg := irc.IrcConfig{
- Network: "grnet",
- Nick: botname,
- User: "z0mg",
- Serv: hostport[0],
- Port: hostport[1],
- Tls: *sslon,
+ NetworkName: "grnet",
+ Nick: botname,
+ User: "z0mg",
+ Serv: hostport[0],
+ Port: hostport[1],
+ Tls: *sslon,
}
kunt.ircCtx = irc.NewIrcContext(cfg)
@@ -377,6 +377,10 @@ func main() {
}
}})
+ kunt.ircCtx.AddEventHandler(irc.IrcEvent{"PING", func(msg irc.IrcMessage) {
+ kunt.ircCtx.Pong(msg.Args[0])
+ }})
+
kunt.ircCtx.Connect()
kunt.ircCtx.AddChannel("#2f30")
kunt.ircCtx.JoinChannels()