Changed random quote functionality to only spit out a quote minutes after somebody (other than the quote timer) has said something. The channels may be a bit buggy, but they don't seem to get stuck or spam, so it should be okayish.

This commit is contained in:
Chris Sexton 2012-10-11 16:28:00 -04:00
parent 684039990d
commit 83b28412a7
4 changed files with 86 additions and 10 deletions

View File

@ -1,9 +1,12 @@
package bot package bot
import irc "github.com/fluffle/goirc/client" import (
import "labix.org/v2/mgo" "bitbucket.org/phlyingpenguin/godeepintir/config"
import "bitbucket.org/phlyingpenguin/godeepintir/config" irc "github.com/fluffle/goirc/client"
import "strings" "labix.org/v2/mgo"
"strings"
"time"
)
// Bot type provides storage for bot-wide information, configs, and database connections // Bot type provides storage for bot-wide information, configs, and database connections
type Bot struct { type Bot struct {
@ -26,9 +29,47 @@ type Bot struct {
varColl *mgo.Collection varColl *mgo.Collection
logIn chan Message
logOut chan Messages
Version string Version string
} }
// Log provides a slice of messages in order
type Log Messages
type Messages []Message
type Logger struct {
in <-chan Message
out chan<- Messages
entries Messages
}
func NewLogger(in chan Message, out chan Messages) *Logger {
return &Logger{in, out, make(Messages, 0)}
}
func RunNewLogger(in chan Message, out chan Messages) {
logger := NewLogger(in, out)
go logger.Run()
}
func (l *Logger) sendEntries() {
l.out <- l.entries
}
func (l *Logger) Run() {
var msg Message
for {
select {
case msg = <-l.in:
l.entries = append(l.entries, msg)
case l.out <- l.entries:
go l.sendEntries()
}
}
}
// User type stores user history. This is a vehicle that will follow the user for the active // User type stores user history. This is a vehicle that will follow the user for the active
// session // session
type User struct { type User struct {
@ -52,6 +93,7 @@ type Message struct {
Raw string Raw string
Command bool Command bool
Action bool Action bool
Time time.Time
} }
type Variable struct { type Variable struct {
@ -67,6 +109,11 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot {
db := session.DB(config.DbName) db := session.DB(config.DbName)
logIn := make(chan Message)
logOut := make(chan Messages)
RunNewLogger(logIn, logOut)
return &Bot{ return &Bot{
Config: config, Config: config,
Plugins: make(map[string]Handler), Plugins: make(map[string]Handler),
@ -76,6 +123,8 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot {
DbSession: session, DbSession: session,
Db: db, Db: db,
varColl: db.C("variables"), varColl: db.C("variables"),
logIn: logIn,
logOut: logOut,
Version: config.Version, Version: config.Version,
} }
} }

View File

@ -1,6 +1,7 @@
package bot package bot
import ( import (
"errors"
"fmt" "fmt"
"math/rand" "math/rand"
"strconv" "strconv"
@ -133,10 +134,19 @@ func (b *Bot) buildMessage(conn *irc.Conn, line *irc.Line) Message {
Raw: message, Raw: message,
Command: iscmd, Command: iscmd,
Action: isaction, Action: isaction,
Time: time.Now(),
} }
return msg return msg
} }
func (b *Bot) LastMessage() (Message, error) {
log := <-b.logOut
if len(log) == 0 {
return Message{}, errors.New("No messages found.")
}
return log[len(log)-1], nil
}
// Handles incomming PRIVMSG requests // Handles incomming PRIVMSG requests
func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) { func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) {
msg := b.buildMessage(conn, line) msg := b.buildMessage(conn, line)
@ -144,7 +154,7 @@ func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) {
if strings.HasPrefix(msg.Body, "help") && msg.Command { if strings.HasPrefix(msg.Body, "help") && msg.Command {
parts := strings.Fields(strings.ToLower(msg.Body)) parts := strings.Fields(strings.ToLower(msg.Body))
b.checkHelp(msg.Channel, parts) b.checkHelp(msg.Channel, parts)
return goto RET
} }
for _, name := range b.PluginOrdering { for _, name := range b.PluginOrdering {
@ -153,6 +163,10 @@ func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) {
break break
} }
} }
RET:
b.logIn <- msg
return
} }
// Take an input string and mutate it based on $vars in the string // Take an input string and mutate it based on $vars in the string

View File

@ -8,8 +8,8 @@
"Nick": "AlePaleTest", "Nick": "AlePaleTest",
"Pass": "AlePaleTest:test", "Pass": "AlePaleTest:test",
"CommandChar": "!", "CommandChar": "!",
"QuoteChance": 0.10, "QuoteChance": 0.75,
"QuoteTime": 30, "QuoteTime": 20,
"LogLength": 50, "LogLength": 50,
"Admins": ["flyngpngn1"], "Admins": ["flyngpngn1"],

View File

@ -394,10 +394,22 @@ func (p *FactoidPlugin) randomFact() *Factoid {
// factTimer spits out a fact at a given interval and with given probability // factTimer spits out a fact at a given interval and with given probability
func (p *FactoidPlugin) factTimer(channel string) { func (p *FactoidPlugin) factTimer(channel string) {
duration := time.Duration(p.Bot.Config.QuoteTime) * time.Minute
myLastMsg := time.Now()
for { for {
time.Sleep(time.Duration(p.Bot.Config.QuoteTime) * time.Minute) time.Sleep(time.Duration(5) * time.Second)
chance := 1.0 / p.Bot.Config.QuoteChance
if rand.Intn(int(chance)) == 0 { lastmsg, err := p.Bot.LastMessage()
if err != nil {
continue
}
tdelta := time.Since(lastmsg.Time)
earlier := time.Since(myLastMsg) > tdelta
chance := rand.Float64()
success := chance < p.Bot.Config.QuoteChance
if success && tdelta > duration && earlier {
fact := p.randomFact() fact := p.randomFact()
if fact == nil { if fact == nil {
continue continue
@ -409,6 +421,7 @@ func (p *FactoidPlugin) factTimer(channel string) {
Channel: channel, Channel: channel,
} }
p.sayFact(message, *fact) p.sayFact(message, *fact)
myLastMsg = time.Now()
} }
} }
} }