mirror of https://github.com/velour/catbase.git
commit
ab989a544b
1
AUTHORS
1
AUTHORS
|
@ -1 +1,2 @@
|
||||||
Chris Sexton <chris.sexton!@!gmail.com>
|
Chris Sexton <chris.sexton!@!gmail.com>
|
||||||
|
Ethan Burns <burns.ethan@gmail.com>
|
4
main.go
4
main.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/velour/catbase/config"
|
"github.com/velour/catbase/config"
|
||||||
"github.com/velour/catbase/irc"
|
"github.com/velour/catbase/irc"
|
||||||
"github.com/velour/catbase/plugins/admin"
|
"github.com/velour/catbase/plugins/admin"
|
||||||
|
"github.com/velour/catbase/plugins/babbler"
|
||||||
"github.com/velour/catbase/plugins/beers"
|
"github.com/velour/catbase/plugins/beers"
|
||||||
"github.com/velour/catbase/plugins/counter"
|
"github.com/velour/catbase/plugins/counter"
|
||||||
"github.com/velour/catbase/plugins/dice"
|
"github.com/velour/catbase/plugins/dice"
|
||||||
|
@ -17,9 +18,9 @@ import (
|
||||||
"github.com/velour/catbase/plugins/fact"
|
"github.com/velour/catbase/plugins/fact"
|
||||||
"github.com/velour/catbase/plugins/leftpad"
|
"github.com/velour/catbase/plugins/leftpad"
|
||||||
"github.com/velour/catbase/plugins/reminder"
|
"github.com/velour/catbase/plugins/reminder"
|
||||||
"github.com/velour/catbase/plugins/babbler"
|
|
||||||
"github.com/velour/catbase/plugins/talker"
|
"github.com/velour/catbase/plugins/talker"
|
||||||
"github.com/velour/catbase/plugins/your"
|
"github.com/velour/catbase/plugins/your"
|
||||||
|
"github.com/velour/catbase/plugins/zork"
|
||||||
"github.com/velour/catbase/slack"
|
"github.com/velour/catbase/slack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ func main() {
|
||||||
b.AddHandler("counter", counter.New(b))
|
b.AddHandler("counter", counter.New(b))
|
||||||
b.AddHandler("reminder", reminder.New(b))
|
b.AddHandler("reminder", reminder.New(b))
|
||||||
b.AddHandler("babbler", babbler.New(b))
|
b.AddHandler("babbler", babbler.New(b))
|
||||||
|
b.AddHandler("zork", zork.New(b))
|
||||||
// catches anything left, will always return true
|
// catches anything left, will always return true
|
||||||
b.AddHandler("factoid", fact.New(b))
|
b.AddHandler("factoid", fact.New(b))
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,124 @@
|
||||||
|
// © 2016 the CatBase Authors under the WTFPL license. See AUTHORS for the list of authors.
|
||||||
|
|
||||||
|
// Package zork implements a zork plugin for catbase.
|
||||||
|
package zork
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"go/build"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/velour/catbase/bot"
|
||||||
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZorkPlugin is a catbase plugin for playing zork.
|
||||||
|
type ZorkPlugin struct {
|
||||||
|
bot bot.Bot
|
||||||
|
sync.Mutex
|
||||||
|
// zorks is a map from channels to their corresponding zork instances.
|
||||||
|
zorks map[string]io.WriteCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(b bot.Bot) bot.Handler {
|
||||||
|
return &ZorkPlugin{
|
||||||
|
bot: b,
|
||||||
|
zorks: make(map[string]io.WriteCloser),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) runZork(ch string) error {
|
||||||
|
const importString = "github.com/velour/catbase/plugins/zork"
|
||||||
|
pkg, err := build.Import(importString, "", build.FindOnly)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
zorkdat := filepath.Join(pkg.Dir, "ZORK1.DAT")
|
||||||
|
cmd := exec.Command("dfrotz", zorkdat)
|
||||||
|
|
||||||
|
var r io.ReadCloser
|
||||||
|
r, cmd.Stdout = io.Pipe()
|
||||||
|
cmd.Stderr = cmd.Stdout
|
||||||
|
|
||||||
|
var w io.WriteCloser
|
||||||
|
cmd.Stdin, w = io.Pipe()
|
||||||
|
|
||||||
|
log.Printf("zork running %s\n", cmd)
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
w.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer r.Close()
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
// Scan until the next prompt.
|
||||||
|
s.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||||
|
if atEOF && len(data) == 0 {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
if i := bytes.Index(data, []byte{'\n', '>'}); i > 0 {
|
||||||
|
return i + 1, data[:i], nil
|
||||||
|
}
|
||||||
|
if atEOF {
|
||||||
|
return len(data), data, nil
|
||||||
|
}
|
||||||
|
return 0, nil, nil
|
||||||
|
})
|
||||||
|
for s.Scan() {
|
||||||
|
// Remove > and quote the whole thing.
|
||||||
|
m := strings.Replace(s.Text(), ">", "", -1)
|
||||||
|
m = strings.Replace(m, "\n", "\n>", -1)
|
||||||
|
m = ">" + m + "\n"
|
||||||
|
p.bot.SendMessage(ch, m)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
log.Printf("zork exited: %v\n", err)
|
||||||
|
}
|
||||||
|
p.Lock()
|
||||||
|
p.zorks[ch] = nil
|
||||||
|
p.Unlock()
|
||||||
|
}()
|
||||||
|
log.Printf("zork is running in %s\n", ch)
|
||||||
|
p.zorks[ch] = w
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) Message(message msg.Message) bool {
|
||||||
|
m := strings.ToLower(message.Body)
|
||||||
|
log.Printf("got message [%s]\n", m)
|
||||||
|
if ts := strings.Fields(m); len(ts) < 1 || ts[0] != "zork" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
m = strings.TrimSpace(strings.TrimPrefix(m, "zork"))
|
||||||
|
ch := message.Channel
|
||||||
|
|
||||||
|
p.Lock()
|
||||||
|
defer p.Unlock()
|
||||||
|
if p.zorks[ch] == nil {
|
||||||
|
if err := p.runZork(ch); err != nil {
|
||||||
|
p.bot.SendMessage(ch, "failed to run zork: "+err.Error())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("zorking, [%s]\n", m)
|
||||||
|
io.WriteString(p.zorks[ch], m+"\n")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) Event(_ string, _ msg.Message) bool { return false }
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) BotMessage(_ msg.Message) bool { return false }
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) Help(ch string, _ []string) {
|
||||||
|
p.bot.SendMessage(ch, "Play zork using 'zork <zork command>'.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ZorkPlugin) RegisterWeb() *string { return nil }
|
Loading…
Reference in New Issue