kunt

golang IRC bot
git clone git://git.2f30.org/kunt
Log | Files | Refs | LICENSE

commit 701eb4d0cf266ace9ebb0adbc0f95b9b89275077
parent 722d1e5de5c686c653e3b05099592ba52e68683c
Author: sin <sin@2f30.org>
Date:   Thu,  9 May 2013 14:05:03 +0100

gofmt -w -r 'IrcMessage -> Message' etc.

Diffstat:
Msrc/games/games.go | 16++++++++--------
Msrc/games/hangman.go | 4++--
Msrc/irc/events.go | 8++++----
Msrc/irc/irc.go | 86+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/irc/message.go | 57++++++++++++++++++++++++++-------------------------------
Msrc/kunt/kunt.go | 48++++++++++++++++++++++++------------------------
6 files changed, 106 insertions(+), 113 deletions(-)

diff --git a/src/games/games.go b/src/games/games.go @@ -6,21 +6,21 @@ import ( // This is a base gamestate for irc games type gameState struct { - ictx *irc.IrcContext // The context to send commands with - gchan *chan irc.IrcMessage // A chan that intercepts game irc messages - name string // Name of the game - creator string // Name of game creator + ictx *irc.Context // The context to send commands with + gchan *chan irc.Message // A chan that intercepts game irc messages + name string // Name of the game + creator string // Name of game creator } // A GameEnger will List available games and invoke a new one if it is on the map. // New games are invoked as new goroutines that communicate via channels. type GameEnger interface { List() []string - New(string, *irc.IrcContext, *chan irc.IrcMessage) + New(string, *irc.Context, *chan irc.Message) } type gameEng struct { - games map[string]func(*irc.IrcContext, *chan irc.IrcMessage) + games map[string]func(*irc.Context, *chan irc.Message) } // Returns all available games as a string array @@ -34,12 +34,12 @@ func (g *gameEng) List() []string { // Initializes games strings with their corresponding goroutines func NewGameEng() *gameEng { - return &gameEng{games: map[string]func(*irc.IrcContext, *chan irc.IrcMessage){"hangman": cmdHangman}} + return &gameEng{games: map[string]func(*irc.Context, *chan irc.Message){"hangman": cmdHangman}} } // Fire up a goroutine if the game is in the map -func (g *gameEng) New(a string, ic *irc.IrcContext, gc *chan irc.IrcMessage) { +func (g *gameEng) New(a string, ic *irc.Context, gc *chan irc.Message) { if f, ok := g.games[a]; ok { go f(ic, gc) } diff --git a/src/games/hangman.go b/src/games/hangman.go @@ -24,7 +24,7 @@ type hangmanState struct { } // Creates a new hangman state with default values -func newHangmanState(ic *irc.IrcContext, gc *chan irc.IrcMessage, sc *chan hgstateFn) *hangmanState { +func newHangmanState(ic *irc.Context, gc *chan irc.Message, sc *chan hgstateFn) *hangmanState { return &hangmanState{gameState{ic, gc, "hangman", "dsp"}, 5, "", "", "", "unnamed", "", sc} } @@ -138,7 +138,7 @@ func hangmanEnd(cs *hangmanState) { // Main hangman dispatch, It sets a timeout and then runs as a new goroutine each // consecutive state it receives on the statechannel. Before ending it removes // the irc Intercept channel for this game. -func cmdHangman(a *irc.IrcContext, gc *chan irc.IrcMessage) { +func cmdHangman(a *irc.Context, gc *chan irc.Message) { timeout := time.After(4 * time.Minute) a.AddIntercept(gc) stchan := make(chan hgstateFn, 1) diff --git a/src/irc/events.go b/src/irc/events.go @@ -4,12 +4,12 @@ import ( "fmt" ) -type IrcEvent struct { +type Event struct { Command string - Fn func(IrcMessage) + Fn func(Message) } -func (i *IrcContext) AddEventHandler(ev IrcEvent) error { +func (i *Context) AddEventHandler(ev Event) error { i.Lock() defer i.Unlock() for j := 0; j < i.evnum; j++ { @@ -23,7 +23,7 @@ func (i *IrcContext) AddEventHandler(ev IrcEvent) error { return nil } -func (i *IrcContext) DelEventHandler(ev *IrcEvent) error { +func (i *Context) DelEventHandler(ev *Event) error { i.Lock() defer i.Unlock() for j := 0; j < i.evnum; j++ { diff --git a/src/irc/irc.go b/src/irc/irc.go @@ -9,18 +9,18 @@ import ( "sync" ) -type IrcContext struct { - conn net.Conn // actual connection - outgoingMsg chan IrcMessage // TX messaging channel - incomingMsg chan IrcMessage // RX messaging channel - ev []IrcEvent // slice of callbacks - evnum int // number of callbacks - network ircNetwork // irc network state - intercepts []*chan IrcMessage // intercept chans +type Context struct { + conn net.Conn // actual connection + outgoingMsg chan Message // TX messaging channel + incomingMsg chan Message // RX messaging channel + ev []Event // slice of callbacks + evnum int // number of callbacks + network network // irc network state + intercepts []*chan Message // intercept chans sync.Mutex } -type IrcConfig struct { +type Config struct { NetworkName string // network name Nick string // nickname User string // username @@ -32,13 +32,13 @@ type IrcConfig struct { Ipv6 bool // enable/disable ipv6 (not implemented) } -type ircChan struct { +type Channel struct { name string // name of irc channel key string // password for irc channel joined bool // whether we have joined this channel or not } -type ircNetwork struct { +type network struct { name string // network name nick string // nickname user string // username @@ -48,12 +48,12 @@ type ircNetwork struct { port string // server port tls bool // enable/disable ssl ipv6 bool // enable/disable ipv6 (not implemented) - channels []ircChan // slice of channels + channels []Channel // slice of channels } // Create a new IrcContext -func NewIrcContext(ircConfig IrcConfig) *IrcContext { - network := ircNetwork{ +func NewIrcContext(ircConfig Config) *Context { + network := network{ name: ircConfig.NetworkName, nick: ircConfig.Nick, user: ircConfig.User, @@ -63,30 +63,30 @@ func NewIrcContext(ircConfig IrcConfig) *IrcContext { port: ircConfig.Port, tls: ircConfig.Tls, ipv6: ircConfig.Ipv6, - channels: make([]ircChan, 0), + channels: make([]Channel, 0), } - return &IrcContext{ - outgoingMsg: make(chan IrcMessage), - incomingMsg: make(chan IrcMessage), - ev: make([]IrcEvent, 0), + return &Context{ + outgoingMsg: make(chan Message), + incomingMsg: make(chan Message), + ev: make([]Event, 0), network: network, - intercepts: make([]*chan IrcMessage, 0), + intercepts: make([]*chan Message, 0), } } -func (i *IrcContext) AddIntercept(a *chan IrcMessage) { +func (i *Context) AddIntercept(a *chan Message) { i.Lock() defer i.Unlock() i.intercepts = append(i.intercepts, a) } -func (i *IrcContext) DelIntercept(ap *chan IrcMessage) error { +func (i *Context) DelIntercept(ap *chan Message) error { i.Lock() defer i.Unlock() for j := 0; j < len(i.intercepts); j++ { if ap == i.intercepts[j] { if j == 0 { - i.intercepts = make([]*chan IrcMessage, 0) + i.intercepts = make([]*chan Message, 0) return nil } i.intercepts = append(i.intercepts[:j], i.intercepts[j+1:]...) @@ -96,54 +96,52 @@ func (i *IrcContext) DelIntercept(ap *chan IrcMessage) error { return fmt.Errorf("Intercept not found") } -type ChanIter func() (channel string, key string, joined bool, ok bool) +type ChanIter func() (c *Channel, ok bool) -func MakeChanIter(i *IrcContext) ChanIter { +func MakeChanIter(i *Context) ChanIter { j := 0 - return func() (channel string, key string, joined bool, ok bool) { + return func() (c *Channel, ok bool) { i.Lock() defer i.Unlock() if j < len(i.network.channels) { - c := i.network.channels[j] j++ - return c.name, c.key, c.joined, true + return &i.network.channels[j], true } else { - return "", "", false, false + return nil, false } } } -func (i *IrcContext) JoinChannel(channel string, key string) error { +func (i *Context) JoinChannel(c string, key string) error { i.Lock() defer i.Unlock() found := false for _, v := range i.network.channels { - if v.name == channel { + if v.name == c { found = true break } } if !found { i.network.channels = append(i.network.channels, - ircChan{channel, key, false}) + Channel{c, key, false}) } - for c, v := range i.network.channels { - if v.name != channel { + for j, v := range i.network.channels { + if v.name != c { continue } if !v.joined { i.Join(v.name, v.key) - i.network.channels[c].joined = true + i.network.channels[j].joined = true return nil } else { - return fmt.Errorf("Already joined channel %s", - channel) + return fmt.Errorf("Already joined channel %s", c) } } return nil } -func (i *IrcContext) PartChannel(s string, text string) error { +func (i *Context) PartChannel(s string, text string) error { i.Lock() defer i.Unlock() for c, v := range i.network.channels { @@ -161,7 +159,7 @@ func (i *IrcContext) PartChannel(s string, text string) error { } // Connect to the server. Do not join any channels by default. -func (i *IrcContext) Connect() error { +func (i *Context) Connect() error { service := i.network.serv + ":" + i.network.port if i.network.tls { @@ -190,7 +188,7 @@ func (i *IrcContext) Connect() error { return nil } -func (i *IrcContext) Login() { +func (i *Context) Login() { if i.network.pass != "" { i.Pass() } @@ -198,7 +196,7 @@ func (i *IrcContext) Login() { i.User() } -func (i *IrcContext) read(buf []byte) (int, error) { +func (i *Context) read(buf []byte) (int, error) { n, err := i.conn.Read(buf) if err != nil { return n, err @@ -208,7 +206,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) rxRawMessages() error { +func (i *Context) rxRawMessages() error { for { var buf [512]byte n, err := i.read(buf[0:]) @@ -234,7 +232,7 @@ func (i *IrcContext) rxRawMessages() error { } // Transmit a raw message -func (i *IrcContext) TxRawMessage(msg []byte) error { +func (i *Context) TxRawMessage(msg []byte) error { _, err := i.conn.Write(msg[0:]) if err != nil { return err @@ -242,7 +240,7 @@ func (i *IrcContext) TxRawMessage(msg []byte) error { return nil } -func (i *IrcContext) String() string { +func (i *Context) String() string { s := fmt.Sprintf("IRC CONTEXT DUMP") if len(i.ev) == 0 { s += fmt.Sprintf("\n\tEvent handlers: [NONE]\n") diff --git a/src/irc/message.go b/src/irc/message.go @@ -6,7 +6,7 @@ import ( "unicode" ) -type IrcMessage struct { +type Message struct { Command string Raw string Nick string @@ -16,37 +16,32 @@ type IrcMessage struct { Args []string } -const ( - IRCARG0 = iota - IRCTEXT -) - -func (i *IrcContext) Pong(host string) { - msg := IrcMessage{ +func (i *Context) Pong(host string) { + msg := Message{ Command: "PONG", Args: []string{":" + host}, } i.outgoingMsg <- msg } -func (i *IrcContext) Pass() { - msg := IrcMessage{ +func (i *Context) Pass() { + msg := Message{ Command: "PASS", Args: []string{i.network.pass}, } i.outgoingMsg <- msg } -func (i *IrcContext) Nick() { - msg := IrcMessage{ +func (i *Context) Nick() { + msg := Message{ Command: "NICK", Args: []string{i.network.nick}, } i.outgoingMsg <- msg } -func (i *IrcContext) User() { - msg := IrcMessage{ +func (i *Context) User() { + msg := Message{ Command: "USER", Args: []string{ i.network.user, @@ -57,16 +52,16 @@ func (i *IrcContext) User() { i.outgoingMsg <- msg } -func (i *IrcContext) Join(channel string, key string) { - msg := IrcMessage{ +func (i *Context) Join(channel string, key string) { + msg := Message{ Command: "JOIN", Args: []string{channel, key}, } i.outgoingMsg <- msg } -func (i *IrcContext) Part(channel string, text string) { - msg := IrcMessage{ +func (i *Context) Part(channel string, text string) { + msg := Message{ Command: "PART", Args: []string{ channel, @@ -76,16 +71,16 @@ func (i *IrcContext) Part(channel string, text string) { i.outgoingMsg <- msg } -func (i *IrcContext) Quit(text string) { - msg := IrcMessage{ +func (i *Context) Quit(text string) { + msg := Message{ Command: "QUIT", Args: []string{":" + text}, } i.outgoingMsg <- msg } -func (i *IrcContext) Privmsg(channel string, text string) { - msg := IrcMessage{ +func (i *Context) Privmsg(channel string, text string) { + msg := Message{ Command: "PRIVMSG", Args: []string{ channel, @@ -95,8 +90,8 @@ func (i *IrcContext) Privmsg(channel string, text string) { i.outgoingMsg <- msg } -func (i *IrcContext) Notice(nick string, text string) { - msg := IrcMessage{ +func (i *Context) Notice(nick string, text string) { + msg := Message{ Command: "NOTICE", Args: []string{ nick, @@ -106,8 +101,8 @@ func (i *IrcContext) Notice(nick string, text string) { i.outgoingMsg <- msg } -func (i *IrcContext) Topic(channel string, text string) { - msg := IrcMessage{ +func (i *Context) Topic(channel string, text string) { + msg := Message{ Command: "TOPIC", Args: []string{ channel, @@ -132,8 +127,8 @@ func validNick(n string) bool { return true } -func (i *IrcContext) ParseRawMessage(raw string) (*IrcMessage, error) { - var msg IrcMessage +func (i *Context) ParseRawMessage(raw string) (*Message, error) { + var msg Message msg.Raw = raw raw = strings.TrimSpace(raw) if raw[0] == ':' { @@ -177,13 +172,13 @@ func (i *IrcContext) ParseRawMessage(raw string) (*IrcMessage, error) { } // Unpack a message into a byte array -func (i *IrcContext) UnpackMessage(msg IrcMessage) []byte { +func (i *Context) UnpackMessage(msg Message) []byte { rawMsg := msg.Command + " " + strings.Join(msg.Args, " ") rawMsg = strings.TrimSpace(rawMsg) + "\r\n" return []byte(rawMsg) } -func (i *IrcContext) incomingMsgLoop() error { +func (i *Context) incomingMsgLoop() error { for { select { case msg, ok := <-i.incomingMsg: @@ -203,7 +198,7 @@ func (i *IrcContext) incomingMsgLoop() error { return nil } -func (i *IrcContext) outgoingMsgLoop() error { +func (i *Context) outgoingMsgLoop() error { for { select { case msg, ok := <-i.outgoingMsg: diff --git a/src/kunt/kunt.go b/src/kunt/kunt.go @@ -19,7 +19,7 @@ import ( type kuntCtx struct { stime time.Time - ircCtx *irc.IrcContext + ircCtx *irc.Context } func resolveYoutubeTitle(link string) (title string, ret bool) { @@ -39,7 +39,7 @@ func resolveYoutubeTitle(link string) (title string, ret bool) { return } -func cmdKunt(msg irc.IrcMessage) { +func cmdKunt(msg irc.Message) { replies := []string{ "dn niotho maaaan", "eimai kokalo telios... gama ta", @@ -77,7 +77,7 @@ func cmdKunt(msg irc.IrcMessage) { kunt.ircCtx.Privmsg(msg.Args[0], string(replies[idx])) } -func cmdWisdom(msg irc.IrcMessage) { +func cmdWisdom(msg irc.Message) { out, err := exec.Command("./fortune").Output() if err != nil { log.Fatal(err) @@ -92,7 +92,7 @@ func cmdWisdom(msg irc.IrcMessage) { } } -func cmdHelp(msg irc.IrcMessage) { +func cmdHelp(msg irc.Message) { help := []string{ "!addquote <quote> -> Add a quote to the db", "!randquote -> Print a random quote from the db", @@ -114,12 +114,12 @@ func cmdHelp(msg irc.IrcMessage) { } } -func cmdVersion(msg irc.IrcMessage) { +func cmdVersion(msg irc.Message) { ver := "v0.2.8" kunt.ircCtx.Privmsg(msg.Args[0], ver) } -func cmdRandQuote(msg irc.IrcMessage) { +func cmdRandQuote(msg irc.Message) { if quoteDb.Empty() { kunt.ircCtx.Privmsg(msg.Args[0], "Empty quote database") return @@ -132,7 +132,7 @@ func cmdRandQuote(msg irc.IrcMessage) { kunt.ircCtx.Privmsg(msg.Args[0], text) } -func cmdAddQuote(msg irc.IrcMessage) { +func cmdAddQuote(msg irc.Message) { text := msg.Args[1] if len(strings.Fields(text)) < 2 { kunt.ircCtx.Privmsg(msg.Args[0], "Missing parameter for !addquote") @@ -158,12 +158,12 @@ func cmdAddQuote(msg irc.IrcMessage) { } } -func cmdCountQuotes(msg irc.IrcMessage) { +func cmdCountQuotes(msg irc.Message) { text := fmt.Sprintf("The quote DB has %d quotes", quoteDb.Size()) kunt.ircCtx.Privmsg(msg.Args[0], text) } -func cmdRandUrl(msg irc.IrcMessage) { +func cmdRandUrl(msg irc.Message) { if urlDb.Empty() { kunt.ircCtx.Privmsg(msg.Args[0], "Empty url database") return @@ -181,7 +181,7 @@ func cmdRandUrl(msg irc.IrcMessage) { } } -func cmdAddUrl(msg irc.IrcMessage) { +func cmdAddUrl(msg irc.Message) { text := msg.Args[1] if len(strings.Fields(text)) < 2 { kunt.ircCtx.Privmsg(msg.Args[0], "Missing parameter for !addurl") @@ -207,12 +207,12 @@ func cmdAddUrl(msg irc.IrcMessage) { } } -func cmdCountUrls(msg irc.IrcMessage) { +func cmdCountUrls(msg irc.Message) { r := fmt.Sprintf("The url DB has %d urls", urlDb.Size()) kunt.ircCtx.Privmsg(msg.Args[0], r) } -func cmdRadio(msg irc.IrcMessage) { +func cmdRadio(msg irc.Message) { np, e := http.Get("http://radio.2f30.org:8000/npsong.xsl") if e != nil { kunt.ircCtx.Privmsg(msg.Args[0], "Is radio broken?") @@ -226,18 +226,18 @@ func cmdRadio(msg irc.IrcMessage) { } } -func cmdUptime(msg irc.IrcMessage) { +func cmdUptime(msg irc.Message) { etime := time.Now() r := fmt.Sprintf("%v", etime.Sub(kunt.stime)) kunt.ircCtx.Privmsg(msg.Args[0], r) } -func cmdSrc(msg irc.IrcMessage) { +func cmdSrc(msg irc.Message) { src := "http://amnezia.2f30.org/tmp/kunt-latest.tgz" kunt.ircCtx.Privmsg(msg.Args[0], src) } -func cmdTodo(msg irc.IrcMessage) { +func cmdTodo(msg irc.Message) { todo, err := ioutil.ReadFile("TODO") if err != nil { kunt.ircCtx.Privmsg(msg.Args[0], "No TODO list available") @@ -256,7 +256,7 @@ func cmdTodo(msg irc.IrcMessage) { } } -func cmdGame(msg irc.IrcMessage) { +func cmdGame(msg irc.Message) { text := msg.Args[1] if len(strings.Fields(text)) < 2 { kunt.ircCtx.Privmsg(msg.Args[0], "Missing parameter for !game") @@ -271,11 +271,11 @@ func cmdGame(msg irc.IrcMessage) { } return } - gchan := make(chan irc.IrcMessage) + gchan := make(chan irc.Message) geng.New(text, kunt.ircCtx, &gchan) time.Sleep(512 * time.Millisecond) - gchan <- irc.IrcMessage{Command: "SETNICK", Args: []string{botname}} //Let the game engine know. - gchan <- irc.IrcMessage{Command: "SETCHAN", Args: []string{msg.Args[0]}} + gchan <- irc.Message{Command: "SETNICK", Args: []string{botname}} //Let the game engine know. + gchan <- irc.Message{Command: "SETCHAN", Args: []string{msg.Args[0]}} } var sslon = flag.Bool("s", false, "SSL support") @@ -340,7 +340,7 @@ func main() { rand.Seed(time.Now().UnixNano()) - dispatch := map[string]func(irc.IrcMessage){ + dispatch := map[string]func(irc.Message){ "kunt": cmdKunt, "!wisdom": cmdWisdom, "!help": cmdHelp, @@ -358,7 +358,7 @@ func main() { "!game": cmdGame, } - cfg := irc.IrcConfig{ + cfg := irc.Config{ NetworkName: "grnet", Nick: botname, User: "z0mg", @@ -369,7 +369,7 @@ func main() { } kunt.ircCtx = irc.NewIrcContext(cfg) - kunt.ircCtx.AddEventHandler(irc.IrcEvent{"PRIVMSG", func(msg irc.IrcMessage) { + kunt.ircCtx.AddEventHandler(irc.Event{"PRIVMSG", func(msg irc.Message) { cmd := msg.Args[1] for i, v := range dispatch { if strings.HasPrefix(cmd, i) { @@ -378,11 +378,11 @@ func main() { } }}) - kunt.ircCtx.AddEventHandler(irc.IrcEvent{"PING", func(msg irc.IrcMessage) { + kunt.ircCtx.AddEventHandler(irc.Event{"PING", func(msg irc.Message) { kunt.ircCtx.Pong(msg.Args[0]) }}) - kunt.ircCtx.AddEventHandler(irc.IrcEvent{"ERROR", func(msg irc.IrcMessage) { + kunt.ircCtx.AddEventHandler(irc.Event{"ERROR", func(msg irc.Message) { os.Exit(0) }})