package main
import (
"crypto/tls"
"encoding/json"
"flag"
"fmt"
"log"
"net"
"sync"
"time"
"github.com/go-redis/redis"
"gopkg.in/irc.v3"
)
var messageBeat chan bool
var firstMessage chan bool
var client *irc.Client
var safeLock sync.Mutex
func main() {
nick := flag.String("nick", "NONE", "the ircnick you want")
from := flag.String("ip", "[::1]", "src address")
flag.Parse()
localAddrDialier := &net.Dialer{
LocalAddr: &net.TCPAddr{
IP: net.ParseIP(*from),
Port: 0,
},
}
conn, err := tls.DialWithDialer(localAddrDialier, "tcp", "chat.freenode.net:6697", &tls.Config{})
if err != nil {
log.Fatalln(err)
}
messageBeat = make(chan bool)
firstMessage = make(chan bool, 10)
go ircKeepalive()
redisc := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("127.0.0.1:%d", 6379),
Password: "", // no password set
DB: 0, // use default DB
})
go func() {
for {
time.Sleep(time.Second)
r := redisc.Ping()
if r.Err() != nil {
redisc = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("127.0.0.1:%d", 6379),
Password: "", // no password set
DB: 0, // use default DB
})
}
redisc.Set(fmt.Sprintf("alive-%s", *nick), "yes", time.Second*5)
}
}()
if *nick == "NONE" {
log.Fatalf("You must set a nick")
}
go func() {
<-firstMessage
for {
psub := redisc.Subscribe(fmt.Sprintf("irc-%s", *nick))
for {
msg, err := psub.ReceiveMessage()
if err != nil {
break
}
client.WriteMessage(&irc.Message{
Command: "PRIVMSG",
Params: []string{
"##tvl-ebooks",
msg.Payload,
},
})
}
time.Sleep(time.Second * 10)
}
}()
go func() {
<-firstMessage
for {
psub := redisc.Subscribe(fmt.Sprintf("raw-irc-%s", *nick))
for {
msg, err := psub.ReceiveMessage()
if err != nil {
break
}
im := irc.Message{}
err = json.Unmarshal([]byte(msg.Payload), &im)
if err == nil {
client.WriteMessage(&im)
}
}
time.Sleep(time.Second * 10)
}
}()
seenMsgBefore := false
config := irc.ClientConfig{
Nick: *nick,
User: *nick,
Name: fmt.Sprintf("%s Ebooks", *nick),
Handler: irc.HandlerFunc(func(c *irc.Client, m *irc.Message) {
b, _ := json.Marshal(m)
log.Printf("%#v", string(b))
messageBeat <- true
if !seenMsgBefore {
firstMessage <- true
seenMsgBefore = true
}
res := redisc.Publish("ebook", string(b))
if res.Err() != nil {
log.Printf("Publish error! %#v", err)
}
if m.Command == "001" {
// 001 is a welcome event, so we join channels there
c.Write("JOIN ##tvl-ebooks")
}
// else if m.Command == "PRIVMSG" && c.FromChannel(m) {
// // // Create a handler on all messages.
// // c.WriteMessage(&irc.Message{
// // Command: "PRIVMSG",
// // Params: []string{
// // m.Params[0],
// // m.Trailing(),
// // },
// // })
// }
}),
}
// Create the client
client = irc.NewClient(conn, config)
err = client.Run()
if err != nil {
log.Fatalln(err)
}
}
func ircKeepalive() {
tt := time.NewTimer(time.Second)
lastPing := time.Now()
for {
select {
case <-tt.C:
if time.Since(lastPing) > time.Minute*5 {
log.Fatalf("It's been too long since the last IRC message, blowing up")
}
break
case <-messageBeat:
lastPing = time.Now()
}
}
}