From 64394b90f909ee5ca8839731c95656a054b459d7 Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Sun, 19 Aug 2012 21:28:25 -0400 Subject: [PATCH] Added remember plugin to remember quotes from IRC users. This has several serious flaws: * Things can be re-remembered. There needs to be safeies on checking for past remembered items * This works across all channels that the bot is enabled in * This allows users to remember themselves * Probably something I forgot. --- config.json | 2 + config/config.go | 2 + main.go | 1 + plugins/remember.go | 140 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 plugins/remember.go diff --git a/config.json b/config.json index c988cb4..4c87bed 100644 --- a/config.json +++ b/config.json @@ -8,6 +8,8 @@ "Nick": "AlePaleTest", "Pass": "AlePaleTest:test", "CommandChar": "!", + "QuoteChance": 0.10, + "LogLength": 50, "comment": "Follows is the old bot", diff --git a/config/config.go b/config/config.go index 8c31d57..ff26c64 100644 --- a/config/config.go +++ b/config/config.go @@ -15,6 +15,8 @@ type Config struct { Nick, Server, Pass string Version string CommandChar string + QuoteChance float64 + LogLength int } // Readconfig loads the config data out of a JSON file located in cfile diff --git a/main.go b/main.go index c423417..c773081 100644 --- a/main.go +++ b/main.go @@ -46,6 +46,7 @@ func main() { b.AddHandler("skeleton", plugins.NewSkeletonPlugin(b)) b.AddHandler("talker", plugins.NewTalkerPlugin(b)) b.AddHandler("beers", plugins.NewBeersPlugin(b)) + b.AddHandler("remember", plugins.NewRememberPlugin(b)) c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { b.MsgRecieved(conn, line) diff --git a/plugins/remember.go b/plugins/remember.go new file mode 100644 index 0000000..9f8dd27 --- /dev/null +++ b/plugins/remember.go @@ -0,0 +1,140 @@ +package plugins + +import ( + "bitbucket.org/phlyingpenguin/godeepintir/bot" + "fmt" + "labix.org/v2/mgo" + "labix.org/v2/mgo/bson" + "math/rand" + "strings" + "time" +) + +// This is a skeleton plugin to serve as an example and quick copy/paste for new plugins. + +type userRemember struct { + Nick string + Message string + Date time.Time +} + +type RememberPlugin struct { + Bot *bot.Bot + Coll *mgo.Collection + Log map[string][]bot.Message +} + +// NewRememberPlugin creates a new RememberPlugin with the Plugin interface +func NewRememberPlugin(b *bot.Bot) *RememberPlugin { + p := RememberPlugin{ + Bot: b, + Log: make(map[string][]bot.Message), + } + p.LoadData() + for _, channel := range b.Config.Channels { + go p.quoteTimer(channel) + } + return &p +} + +// Message responds to the bot hook on recieving messages. +// This function returns true if the plugin responds in a meaningful way to the users message. +// Otherwise, the function returns false and the bot continues execution of other plugins. +func (p *RememberPlugin) Message(message bot.Message) bool { + // This bot does not reply to anything + + if message.Body == "quote" && message.Command { + q := p.randQuote() + p.Bot.SendMessage(message.Channel, q) + return true + } + + parts := strings.Fields(message.Body) + if len(parts) < 3 || parts[0] != "remember" { + p.Log[message.Channel] = append(p.Log[message.Channel], message) + return false + } else { + // we have a remember! + // look through the logs and find parts[1] as a user, if not, fuck this hoser + nick := parts[1] + snip := strings.Join(parts[2:], " ") + for _, entry := range p.Log[message.Channel] { + // find the entry we want + if entry.User.Name == nick && strings.Contains(entry.Body, snip) { + // insert new remember entry + u := userRemember{ + Nick: entry.User.Name, + Message: fmt.Sprintf("<%s> %s", entry.User.Name, entry.Body), + Date: time.Now(), + } + p.Coll.Insert(u) + msg := fmt.Sprintf("Okay, %s, remembering '<%s> %s'.", + message.User.Name, entry.User.Name, entry.Body) + p.Bot.SendMessage(message.Channel, msg) + return true + } + } + p.Bot.SendMessage(message.Channel, "Sorry, I don't know that phrase.") + return true + } + return false +} + +// LoadData imports any configuration data into the plugin. This is not strictly necessary other +// than the fact that the Plugin interface demands it exist. This may be deprecated at a later +// date. +func (p *RememberPlugin) LoadData() { + p.Coll = p.Bot.Db.C("remember") + if p.Coll == nil { + panic("FUCK ME") + } + rand.Seed(time.Now().Unix()) +} + +// Help responds to help requests. Every plugin must implement a help function. +func (p *RememberPlugin) Help(channel string, parts []string) { + msg := "!remember will let you quote your idiot friends. Just type !remember " + + " to remember what they said. Snippet can be any part of their message. " + + "Later on, you can ask for a random !quote." + p.Bot.SendMessage(channel, msg) +} + +func (p *RememberPlugin) record(nick, msg string) { + message := userRemember{ + Nick: nick, + Message: msg, + Date: time.Now(), + } + p.Coll.Insert(message) +} + +// deliver a random quote out of the db. +// Note: this is the same cache for all channels joined. This plugin needs to be expanded +// to have this function execute a quote for a particular channel +func (p *RememberPlugin) randQuote() string { + var quotes []userRemember + if p.Coll == nil { + panic("FUCK ME HARD") + } + iter := p.Coll.Find(bson.M{}).Iter() + err := iter.All("es) + if err != nil { + panic(iter.Err()) + } + + // rand quote idx + nquotes := len(quotes) + quote := quotes[rand.Intn(nquotes)] + return quote.Message +} + +func (p *RememberPlugin) quoteTimer(channel string) { + for { + time.Sleep(30 * time.Minute) + chance := 1.0 / p.Bot.Config.QuoteChance + if rand.Intn(int(chance)) == 0 { + msg := p.randQuote() + p.Bot.SendMessage(channel, msg) + } + } +}