mirror of https://github.com/velour/catbase.git
parent
0e5f7eb2d5
commit
75a12ca9a5
2
main.go
2
main.go
|
@ -59,7 +59,6 @@ import (
|
||||||
"github.com/velour/catbase/plugins/tldr"
|
"github.com/velour/catbase/plugins/tldr"
|
||||||
"github.com/velour/catbase/plugins/twitch"
|
"github.com/velour/catbase/plugins/twitch"
|
||||||
"github.com/velour/catbase/plugins/your"
|
"github.com/velour/catbase/plugins/your"
|
||||||
"github.com/velour/catbase/plugins/zork"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -133,7 +132,6 @@ func main() {
|
||||||
b.AddPlugin(goals.New(b))
|
b.AddPlugin(goals.New(b))
|
||||||
b.AddPlugin(reminder.New(b))
|
b.AddPlugin(reminder.New(b))
|
||||||
b.AddPlugin(babbler.New(b))
|
b.AddPlugin(babbler.New(b))
|
||||||
b.AddPlugin(zork.New(b))
|
|
||||||
b.AddPlugin(rss.New(b))
|
b.AddPlugin(rss.New(b))
|
||||||
b.AddPlugin(reaction.New(b))
|
b.AddPlugin(reaction.New(b))
|
||||||
b.AddPlugin(twitch.New(b))
|
b.AddPlugin(twitch.New(b))
|
||||||
|
|
Binary file not shown.
|
@ -1,128 +0,0 @@
|
||||||
// © 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"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
|
|
||||||
"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.Plugin {
|
|
||||||
z := &ZorkPlugin{
|
|
||||||
bot: b,
|
|
||||||
zorks: make(map[string]io.WriteCloser),
|
|
||||||
}
|
|
||||||
b.Register(z, bot.Message, z.message)
|
|
||||||
b.Register(z, bot.Help, z.help)
|
|
||||||
return z
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ZorkPlugin) runZork(c bot.Connector, ch string) error {
|
|
||||||
const importString = "github.com/velour/catbase/plugins/zork"
|
|
||||||
pkgPath := ""
|
|
||||||
pkg, err := build.Import(importString, "", build.FindOnly)
|
|
||||||
if err == nil {
|
|
||||||
pkgPath = pkg.Dir
|
|
||||||
}
|
|
||||||
zorkPath := p.bot.Config().GetString("zork.path", pkgPath)
|
|
||||||
zorkdat := filepath.Join(zorkPath, "ZORK1.DAT")
|
|
||||||
zorkFlags := p.bot.Config().GetArray("zork.args", []string{"-p"})
|
|
||||||
zorkExec := p.bot.Config().GetString("zork.binary", "frotz")
|
|
||||||
zorkFlags = append(zorkFlags, zorkdat)
|
|
||||||
cmd := exec.Command(zorkExec, zorkFlags...)
|
|
||||||
|
|
||||||
var r io.ReadCloser
|
|
||||||
r, cmd.Stdout = io.Pipe()
|
|
||||||
cmd.Stderr = cmd.Stdout
|
|
||||||
|
|
||||||
var w io.WriteCloser
|
|
||||||
cmd.Stdin, w = io.Pipe()
|
|
||||||
|
|
||||||
log.Info().Msgf("zork running %v", 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.Send(c, bot.Message, ch, m)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
if err := cmd.Wait(); err != nil {
|
|
||||||
log.Error().Err(err).Msg("zork exited")
|
|
||||||
}
|
|
||||||
p.Lock()
|
|
||||||
p.zorks[ch] = nil
|
|
||||||
p.Unlock()
|
|
||||||
}()
|
|
||||||
log.Info().Msgf("zork is running in %s\n", ch)
|
|
||||||
p.zorks[ch] = w
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ZorkPlugin) message(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool {
|
|
||||||
m := strings.ToLower(message.Body)
|
|
||||||
log.Debug().Msgf("got message [%s]", 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(c, ch); err != nil {
|
|
||||||
p.bot.Send(c, bot.Message, ch, "failed to run zork: "+err.Error())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Debug().Msgf("zorking, [%s]", m)
|
|
||||||
io.WriteString(p.zorks[ch], m+"\n")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ZorkPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool {
|
|
||||||
p.bot.Send(c, bot.Message, message.Channel, "Play zork using 'zork <zork command>'.")
|
|
||||||
return true
|
|
||||||
}
|
|
Loading…
Reference in New Issue