soccer-bot/manager/antiflood.go

87 lines
2.2 KiB
Go
Raw Normal View History

2017-08-08 16:32:45 +00:00
package manager
import (
"crypto/sha512"
"fmt"
"log"
"strings"
"time"
"github.com/thoj/go-ircevent"
cache "github.com/patrickmn/go-cache"
)
func (m *Manager) initAntiflood() {
m.cache = cache.New(1*time.Minute, 5*time.Second)
}
func (m *Manager) TrackOutput(target, t string) (shouldNotSend bool) {
key := normalizeTextAntiflood(target, t)
if _, ok := m.cache.Get(key); ok {
// The URL has been used recently, should ignore
shouldNotSend = true
} else {
m.cache.Add(key, nil, cache.DefaultExpiration)
}
return
}
func (m *Manager) AntifloodIrcConn(c *irc.Connection) *ircConnectionProxy {
return &ircConnectionProxy{Connection: c, m: m}
}
func normalizeTextAntiflood(target, text string) string {
s := sha512.New()
s.Write([]byte(text))
return fmt.Sprintf("TEXT/%s/%X", strings.ToUpper(target), s.Sum([]byte{}))
}
// Proxies several methods of the IRC connection in order to drop repeated messages
type ircConnectionProxy struct {
*irc.Connection
m *Manager
}
func (proxy *ircConnectionProxy) Action(target, message string) {
if proxy.m.TrackOutput(target, message) {
log.Printf("WARNING: Output antiflood triggered, dropping message for %s: %s", target, message)
return
}
proxy.Connection.Action(target, message)
}
func (proxy *ircConnectionProxy) Actionf(target, format string, a ...interface{}) {
proxy.Action(target, fmt.Sprintf(format, a...))
}
func (proxy *ircConnectionProxy) Privmsg(target, message string) {
if proxy.m.TrackOutput(target, message) {
log.Printf("WARNING: Output antiflood triggered, dropping message for %s: %s", target, message)
return
}
proxy.Connection.Privmsg(target, message)
}
func (proxy *ircConnectionProxy) Privmsgf(target, format string, a ...interface{}) {
proxy.Privmsg(target, fmt.Sprintf(format, a...))
}
func (proxy *ircConnectionProxy) Notice(target, message string) {
if proxy.m.TrackOutput(target, message) {
log.Printf("WARNING: Output antiflood triggered, dropping message for %s: %s", target, message)
return
}
proxy.Connection.Notice(target, message)
}
func (proxy *ircConnectionProxy) Noticef(target, format string, a ...interface{}) {
proxy.Notice(target, fmt.Sprintf(format, a...))
}