-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgerri.go
157 lines (139 loc) · 3.4 KB
/
gerri.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
/*
Minimal IRC bot in Go
*/
import (
"bufio"
"encoding/json"
"fmt"
"github.com/dysfn/gerri/cmd"
"github.com/dysfn/gerri/data"
"github.com/dysfn/gerri/plugin"
"io/ioutil"
"log"
"net"
"net/textproto"
"strings"
)
const (
CONFIG = "config.json" // config filename
)
/* plugin mappings */
var repliers = map[string]func(data.Privmsg, *data.Config) (string, error){
":!advice": plugin.ReplyAdvice,
":!ask": plugin.ReplyAsk,
":!beertime": plugin.ReplyBeertime,
":!day": plugin.ReplyDay,
":!ddg": plugin.ReplyDdg,
":!gif": plugin.ReplyGIF,
":!jira": plugin.ReplyJira,
":!ping": plugin.ReplyPing,
":!py": plugin.ReplyPy,
":!quote": plugin.ReplyQuote,
":!slap": plugin.ReplySlap,
":!title": plugin.ReplyTitle,
":!time": plugin.ReplyTime,
":!ud": plugin.ReplyUd,
":!ver": plugin.ReplyVer,
":!version": plugin.ReplyVer,
":!wik": plugin.ReplyWik,
":!wa": plugin.ReplyWA,
}
func buildReply(conn net.Conn, pm data.Privmsg) {
/* replies PRIVMSG message */
fn, found := repliers[pm.Message[0]]
if found {
reply, err := fn(pm, readConfig(CONFIG))
if err != nil {
log.Printf("error: %s", err)
} else {
if reply != "" {
log.Printf("reply: %s", reply)
conn.Write([]byte(reply))
}
}
}
}
func connect(server string, port string) (net.Conn, error) {
/* establishes irc connection */
log.Printf("connecting to %s:%s...", server, port)
conn, err := net.Dial("tcp", server+":"+port)
if err != nil {
log.Fatal(err)
}
log.Printf("connected")
return conn, err
}
func send(ch chan<- string, conn net.Conn) {
/* defines goroutine sending messages to channel */
reader := textproto.NewReader(bufio.NewReader(conn))
for {
line, err := reader.ReadLine()
if err != nil {
log.Fatal(err)
break
}
ch <- line
}
}
func receive(ch <-chan string, conn net.Conn) {
/* defines goroutine receiving messages from channel */
for {
line, ok := <-ch
if !ok {
log.Fatal("aborted: failed to receive from channel")
break
}
log.Printf(line)
tokens := strings.Split(line, " ")
if tokens[0] == cmd.PING {
// reply PING with PONG
msg := cmd.Pong(strings.Split(line, ":")[1])
conn.Write([]byte(msg))
log.Printf(msg)
} else {
// reply PRIVMSG
if len(tokens) >= 4 && tokens[1] == cmd.PRIVMSG {
pm := data.Privmsg{Source: tokens[0], Target: tokens[2], Message: tokens[3:]}
go buildReply(conn, pm) // reply asynchronously
}
}
}
}
func readConfig(filename string) *data.Config {
/* reads config from file */
file, e := ioutil.ReadFile(filename)
if e != nil {
fmt.Printf("File error: %v\n", e)
}
var config *data.Config = &data.Config{}
if err := json.Unmarshal(file, config); err != nil {
log.Fatal(err)
}
return config
}
func main() {
// read config from file
config := readConfig(CONFIG)
// connect to quote db
if len(config.QuoteDB) != 0 {
plugin.QuoteDB = plugin.ConnectQuoteDB(config.QuoteDB)
defer plugin.QuoteDB.Close()
}
// connect to irc
conn, err := connect(config.Server, config.Port)
if err != nil {
log.Fatal(err)
}
// send messages: USER/NICK/JOIN
conn.Write([]byte(cmd.User(config.Nick)))
conn.Write([]byte(cmd.Nick(config.Nick)))
conn.Write([]byte(cmd.Join(config.Channel)))
defer conn.Close()
// define goroutines communicating via channel
ch := make(chan string)
go send(ch, conn)
go receive(ch, conn)
var input string
fmt.Scanln(&input)
}