diff --git a/bot/bot.go b/bot/bot.go index 92a4220..215c577 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -1,9 +1,12 @@ package bot -import irc "github.com/fluffle/goirc/client" -import "labix.org/v2/mgo" -import "bitbucket.org/phlyingpenguin/godeepintir/config" -import "strings" +import ( + "bitbucket.org/phlyingpenguin/godeepintir/config" + irc "github.com/fluffle/goirc/client" + "labix.org/v2/mgo" + "strings" + "time" +) // Bot type provides storage for bot-wide information, configs, and database connections type Bot struct { @@ -26,9 +29,47 @@ type Bot struct { varColl *mgo.Collection + logIn chan Message + logOut chan Messages + 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 // session type User struct { @@ -52,6 +93,7 @@ type Message struct { Raw string Command bool Action bool + Time time.Time } type Variable struct { @@ -67,6 +109,11 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot { db := session.DB(config.DbName) + logIn := make(chan Message) + logOut := make(chan Messages) + + RunNewLogger(logIn, logOut) + return &Bot{ Config: config, Plugins: make(map[string]Handler), @@ -76,6 +123,8 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot { DbSession: session, Db: db, varColl: db.C("variables"), + logIn: logIn, + logOut: logOut, Version: config.Version, } } diff --git a/bot/handlers.go b/bot/handlers.go index 272316a..84515a6 100644 --- a/bot/handlers.go +++ b/bot/handlers.go @@ -1,6 +1,7 @@ package bot import ( + "errors" "fmt" "math/rand" "strconv" @@ -133,10 +134,19 @@ func (b *Bot) buildMessage(conn *irc.Conn, line *irc.Line) Message { Raw: message, Command: iscmd, Action: isaction, + Time: time.Now(), } 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 func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.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 { parts := strings.Fields(strings.ToLower(msg.Body)) b.checkHelp(msg.Channel, parts) - return + goto RET } for _, name := range b.PluginOrdering { @@ -153,6 +163,10 @@ func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) { break } } + +RET: + b.logIn <- msg + return } // Take an input string and mutate it based on $vars in the string diff --git a/config.json b/config.json index 9b76b94..7d29b78 100644 --- a/config.json +++ b/config.json @@ -8,8 +8,8 @@ "Nick": "AlePaleTest", "Pass": "AlePaleTest:test", "CommandChar": "!", - "QuoteChance": 0.10, - "QuoteTime": 30, + "QuoteChance": 0.75, + "QuoteTime": 20, "LogLength": 50, "Admins": ["flyngpngn1"], diff --git a/plugins/factoid.go b/plugins/factoid.go index 6aa9391..adafe20 100644 --- a/plugins/factoid.go +++ b/plugins/factoid.go @@ -394,10 +394,22 @@ func (p *FactoidPlugin) randomFact() *Factoid { // factTimer spits out a fact at a given interval and with given probability func (p *FactoidPlugin) factTimer(channel string) { + duration := time.Duration(p.Bot.Config.QuoteTime) * time.Minute + myLastMsg := time.Now() for { - time.Sleep(time.Duration(p.Bot.Config.QuoteTime) * time.Minute) - chance := 1.0 / p.Bot.Config.QuoteChance - if rand.Intn(int(chance)) == 0 { + time.Sleep(time.Duration(5) * time.Second) + + 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() if fact == nil { continue @@ -409,6 +421,7 @@ func (p *FactoidPlugin) factTimer(channel string) { Channel: channel, } p.sayFact(message, *fact) + myLastMsg = time.Now() } } }