mirror of https://github.com/velour/catbase.git
sisyphus: add plugin
This commit is contained in:
parent
1ac566c2c2
commit
827879b72d
2
main.go
2
main.go
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/velour/catbase/plugins/reminder"
|
||||
"github.com/velour/catbase/plugins/rpgORdie"
|
||||
"github.com/velour/catbase/plugins/rss"
|
||||
"github.com/velour/catbase/plugins/sisyphus"
|
||||
"github.com/velour/catbase/plugins/stats"
|
||||
"github.com/velour/catbase/plugins/talker"
|
||||
"github.com/velour/catbase/plugins/twitch"
|
||||
|
@ -71,6 +72,7 @@ func main() {
|
|||
b.AddHandler("twitch", twitch.New(b))
|
||||
b.AddHandler("inventory", inventory.New(b))
|
||||
b.AddHandler("rpgORdie", rpgORdie.New(b))
|
||||
b.AddHandler("sisyphus", sisyphus.New(b))
|
||||
// catches anything left, will always return true
|
||||
b.AddHandler("factoid", fact.New(b))
|
||||
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
package sisyphus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/velour/catbase/bot"
|
||||
"github.com/velour/catbase/bot/msg"
|
||||
)
|
||||
|
||||
const (
|
||||
BOULDER = ":full_moon:"
|
||||
MOUNTAIN = ":new_moon:"
|
||||
)
|
||||
|
||||
type SisyphusPlugin struct {
|
||||
Bot bot.Bot
|
||||
listenFor map[string]*game
|
||||
}
|
||||
|
||||
type game struct {
|
||||
id string
|
||||
channel string
|
||||
bot bot.Bot
|
||||
who string
|
||||
start time.Time
|
||||
size int
|
||||
hardness int
|
||||
current int
|
||||
nextPush time.Time
|
||||
nextDec time.Time
|
||||
timers [2]*time.Timer
|
||||
ended bool
|
||||
nextAns int
|
||||
}
|
||||
|
||||
func NewRandomGame(bot bot.Bot, channel, who string) *game {
|
||||
size := rand.Intn(9) + 2
|
||||
g := game{
|
||||
channel: channel,
|
||||
bot: bot,
|
||||
who: who,
|
||||
start: time.Now(),
|
||||
size: size,
|
||||
hardness: rand.Intn(9) + 1,
|
||||
current: size / 2,
|
||||
}
|
||||
g.id = bot.SendMessage(channel, g.toMessageString())
|
||||
|
||||
g.schedulePush()
|
||||
g.scheduleDecrement()
|
||||
|
||||
return &g
|
||||
}
|
||||
|
||||
func (g *game) scheduleDecrement() {
|
||||
if g.timers[0] != nil {
|
||||
g.timers[0].Stop()
|
||||
}
|
||||
g.nextDec = time.Now().Add(time.Duration((60 + rand.Intn(60*5))) * time.Second)
|
||||
go func() {
|
||||
t := time.NewTimer(g.nextDec.Sub(time.Now()))
|
||||
g.timers[0] = t
|
||||
select {
|
||||
case <-t.C:
|
||||
g.handleDecrement()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (g *game) schedulePush() {
|
||||
if g.timers[1] != nil {
|
||||
g.timers[1].Stop()
|
||||
}
|
||||
g.nextPush = time.Now().Add(time.Duration(rand.Intn(60)+1) * time.Minute)
|
||||
go func() {
|
||||
t := time.NewTimer(g.nextPush.Sub(time.Now()))
|
||||
g.timers[1] = t
|
||||
select {
|
||||
case <-t.C:
|
||||
g.handleNotify()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (g *game) endGame() {
|
||||
for _, t := range g.timers {
|
||||
t.Stop()
|
||||
}
|
||||
g.ended = true
|
||||
}
|
||||
|
||||
func (g *game) handleDecrement() {
|
||||
g.current++
|
||||
g.bot.Edit(g.channel, g.toMessageString(), g.id)
|
||||
if g.current > g.size-2 {
|
||||
g.bot.ReplyToMessageIdentifier(g.channel, "you lose", g.id)
|
||||
msg := fmt.Sprintf("%s just lost the game after %s", g.who, time.Now().Sub(g.start))
|
||||
g.bot.SendMessage(g.channel, msg)
|
||||
g.endGame()
|
||||
} else {
|
||||
g.scheduleDecrement()
|
||||
}
|
||||
}
|
||||
|
||||
func (g *game) handleNotify() {
|
||||
g.bot.ReplyToMessageIdentifier(g.channel, "You can push now.\n"+g.generateQuestion(), g.id)
|
||||
}
|
||||
|
||||
func (g *game) generateQuestion() string {
|
||||
n1 := rand.Intn(99) + (rand.Intn(9)+1)*100
|
||||
n2 := rand.Intn(99) + (rand.Intn(9)+1)*100
|
||||
var op string
|
||||
switch i := rand.Intn(3); i {
|
||||
case 0:
|
||||
// times
|
||||
g.nextAns = n1 * n2
|
||||
op = "*"
|
||||
case 1:
|
||||
// plus
|
||||
g.nextAns = n1 + n2
|
||||
op = "+"
|
||||
case 2:
|
||||
// minus
|
||||
g.nextAns = n1 - n2
|
||||
op = "-"
|
||||
}
|
||||
return fmt.Sprintf("What is %d %s %d?", n1, op, n2)
|
||||
}
|
||||
|
||||
func (g *game) checkAnswer(ans string) bool {
|
||||
if strings.Contains(ans, strconv.Itoa(g.nextAns)) {
|
||||
g.current--
|
||||
if g.current < 0 {
|
||||
g.current = 0
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *game) toMessageString() string {
|
||||
out := ""
|
||||
for i := 0; i < g.size; i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
out = out + MOUNTAIN
|
||||
}
|
||||
if i == g.current {
|
||||
out = out + BOULDER
|
||||
} else if i == g.current+1 {
|
||||
out = out + ":" + g.who + ":"
|
||||
}
|
||||
out = out + "\n"
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func New(b bot.Bot) *SisyphusPlugin {
|
||||
return &SisyphusPlugin{
|
||||
Bot: b,
|
||||
listenFor: map[string]*game{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) Message(message msg.Message) bool {
|
||||
if strings.ToLower(message.Body) == "start sisyphus" {
|
||||
b := NewRandomGame(p.Bot, message.Channel, message.User.Name)
|
||||
p.listenFor[b.id] = b
|
||||
p.Bot.ReplyToMessageIdentifier(message.Channel, "Over here.", b.id)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) Help(channel string, parts []string) {
|
||||
p.Bot.SendMessage(channel, "https://en.wikipedia.org/wiki/Sisyphus")
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) Event(kind string, message msg.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) BotMessage(message msg.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) RegisterWeb() *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *SisyphusPlugin) ReplyMessage(message msg.Message, identifier string) bool {
|
||||
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Nick) {
|
||||
if g, ok := p.listenFor[identifier]; ok {
|
||||
|
||||
log.Printf("got message on %s: %+v", identifier, message)
|
||||
|
||||
if g.ended {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.ToLower(message.Body) == "end game" {
|
||||
g.endGame()
|
||||
return true
|
||||
}
|
||||
|
||||
if time.Now().After(g.nextPush) {
|
||||
if g.checkAnswer(message.Body) {
|
||||
p.Bot.Edit(message.Channel, g.toMessageString(), identifier)
|
||||
g.schedulePush()
|
||||
msg := fmt.Sprintf("Ok. You can push again in %s", g.nextPush.Sub(time.Now()))
|
||||
p.Bot.ReplyToMessageIdentifier(message.Channel, msg, identifier)
|
||||
} else {
|
||||
p.Bot.ReplyToMessageIdentifier(message.Channel, "you lose", identifier)
|
||||
msg := fmt.Sprintf("%s just lost the sisyphus game after %s", g.who, time.Now().Sub(g.start))
|
||||
p.Bot.SendMessage(message.Channel, msg)
|
||||
g.endGame()
|
||||
}
|
||||
} else {
|
||||
p.Bot.ReplyToMessageIdentifier(message.Channel, "you cannot push yet", identifier)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package sisyphus
|
|
@ -39,8 +39,8 @@ type Slack struct {
|
|||
|
||||
emoji map[string]string
|
||||
|
||||
eventReceived func(msg.Message)
|
||||
messageReceived func(msg.Message)
|
||||
eventReceived func(msg.Message)
|
||||
messageReceived func(msg.Message)
|
||||
replyMessageReceived func(msg.Message, string)
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ type slackMessage struct {
|
|||
User string `json:"user"`
|
||||
Username string `json:"username"`
|
||||
Ts string `json:"ts"`
|
||||
ThreadTs string `json:"thread_ts"`
|
||||
ThreadTs string `json:"thread_ts"`
|
||||
Error struct {
|
||||
Code uint64 `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
|
@ -207,6 +207,7 @@ func (s *Slack) SendMessageType(channel, message string, meMessage bool) (string
|
|||
|
||||
resp, err := http.PostForm(postUrl,
|
||||
url.Values{"token": {s.config.Slack.Token},
|
||||
"as_user": {"true"},
|
||||
"channel": {channel},
|
||||
"text": {message},
|
||||
})
|
||||
|
@ -256,6 +257,7 @@ func (s *Slack) SendAction(channel, message string) string {
|
|||
func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
|
||||
resp, err := http.PostForm("https://slack.com/api/chat.postMessage",
|
||||
url.Values{"token": {s.config.Slack.Token},
|
||||
"as_user": {"true"},
|
||||
"channel": {channel},
|
||||
"text": {message},
|
||||
"thread_ts": {identifier},
|
||||
|
|
Loading…
Reference in New Issue