Esempio n. 1
0
// Recursively resolve pointers to other factoids
func recurse(fact *factoids.Factoid, keys map[string]bool) {
	val := fact.Value
	key, start, end := util.FactPointer(val)
	if key == "" {
		return
	}
	if _, ok := keys[key]; ok || len(keys) > 20 {
		fact.Value = val[:start] + "[circular reference]" + val[end:]
		return
	}
	keys[key] = true
	if f2 := fc.GetPseudoRand(key); f2 != nil {
		fact.Value = val[:start] + f2.Value + val[end:]
		if start == 0 && fact.Type != f2.Type {
			// Propagate change of factoid type when the pointer
			// is at the beginning of the string.
			fact.Type = f2.Type
		}
		recurse(fact, keys)
		return
	}
	// if we get here, we found a pointer key but no matching factoid
	// so recurse on the stuff after that key *only* to avoid loops.
	fact.Value = val[end:]
	recurse(fact, keys)
	fact.Value = val[:end] + fact.Value
}
Esempio n. 2
0
func lookup(line *base.Line) {
	// Only perform extra prefix removal if we weren't addressed directly
	key := ToKey(line.Args[1], !line.Addressed)
	var fact *factoids.Factoid

	if fact = fc.GetPseudoRand(key); fact == nil && line.Cmd == "ACTION" {
		// Support sp0rkle's habit of stripping off it's own nick
		// but only for actions, not privmsgs.
		if strings.HasSuffix(key, bot.Nick()) {
			key = strings.TrimSpace(key[:len(key)-len(bot.Nick())])
			fact = fc.GetPseudoRand(key)
		}
	}
	if fact == nil {
		return
	}
	// Chance is used to limit the rate of factoid replies for things
	// people say a lot, like smilies, or 'lol', or 'i love the peen'.
	chance := fact.Chance
	if key == "" {
		// This is doing a "random" lookup, triggered by someone typing in
		// something entirely composed of the chars stripped by ToKey().
		// To avoid making this too spammy, forcibly limit the chance to 40%.
		chance = 0.4
	}
	if rand.Float64() < chance {
		// Store this as the last seen factoid
		LastSeen(line.Args[0], fact.Id)
		// Update the Accessed field
		// TODO(fluffle): fd should take care of updating Accessed internally
		fact.Access(line.Storable())
		// And store the new factoid data
		if err := fc.Update(bson.M{"_id": fact.Id}, fact); err != nil {
			bot.ReplyN(line, "I failed to update '%s' (%s): %s ",
				fact.Key, fact.Id, err)
		}
		keys := map[string]bool{key: true}
		val := recurse(fact.Value, keys)
		switch fact.Type {
		case factoids.F_ACTION:
			bot.Do(line, "%s", val)
		default:
			bot.Reply(line, "%s", val)
		}
	}
}