From a0c782f83d7349cb5abda92647545e9a78b41502 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 6 Jul 2019 20:06:11 +0200 Subject: autoban --- internal/fix/fix.go | 27 +++++++++++++++++++-------- internal/flood/flood.go | 30 ++++++++++++++++++++++++++++-- internal/title/href.go | 18 ++++++++++++++---- main.go | 4 ++++ 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/internal/fix/fix.go b/internal/fix/fix.go index 2a83a28..a1c1c2d 100644 --- a/internal/fix/fix.go +++ b/internal/fix/fix.go @@ -13,23 +13,34 @@ import ( var errNotRE = errors.New("not re") type Fix struct { - last *lru.Cache - w io.Writer + cache *lru.Cache + w io.Writer +} + +func (f Fix) get(nick string) (string, bool) { + if text, ok := f.cache.Get(nick); ok { + return text.(string), true + } + return "", false +} + +func (f Fix) set(nick, text string) { + f.cache.Add(nick, text) } func New(w io.Writer) *Fix { - last, _ := lru.New(100) - return &Fix{last: last, w: w} + cache, _ := lru.New(100) + return &Fix{cache: cache, w: w} } -func (f *Fix) Fix(text, nick string) { - defer f.last.Add(nick, text) +func (f Fix) Fix(text, nick string) { + defer f.set(nick, text) if !strings.HasPrefix(text, "s") { return } - if tofix, ok := f.last.Get(nick); ok { + if tofix, ok := f.get(nick); ok { global := strings.HasSuffix(text, "g") - fixed, err := replace(tofix.(string), text[1:], global) + fixed, err := replace(tofix, text[1:], global) if err == nil && fixed != tofix { fmt.Fprintf(f.w, "%v meant to say: %s", nick, fixed) } diff --git a/internal/flood/flood.go b/internal/flood/flood.go index fce81ae..c737e8f 100644 --- a/internal/flood/flood.go +++ b/internal/flood/flood.go @@ -5,6 +5,8 @@ import ( "sort" "strings" "unicode/utf8" + + lru "github.com/hashicorp/golang-lru" ) const ( @@ -15,18 +17,42 @@ const ( type Kicker interface { Kick(nick string, message ...string) + Ban(nick string) } type Check struct { - k Kicker + k Kicker + cache *lru.Cache } func New(k Kicker) *Check { - return &Check{k: k} + cache, _ := lru.New(100) + return &Check{k: k, cache: cache} +} + +func (c Check) get(nick string) (int, bool) { + if n, ok := c.cache.Get(nick); ok { + return n.(int), true + } + return 0, false +} + +func (c Check) del(nick string) { + c.cache.Remove(nick) +} + +func (c Check) set(nick string, n int) { + c.cache.Add(nick, n) } func (c Check) Check(text, nick string) { if isFlood(text) { + count, _ := c.get(nick) + c.set(nick, count+1) + if count >= 3 { + c.k.Ban(nick) + c.del(nick) + } c.k.Kick(nick) } } diff --git a/internal/title/href.go b/internal/title/href.go index cae1a18..2b6b89f 100644 --- a/internal/title/href.go +++ b/internal/title/href.go @@ -35,19 +35,29 @@ func New(w io.Writer) *Titles { return &Titles{cache: cache, w: w} } -func (t *Titles) Parse(text string) { +func (t Titles) get(url string) (string, bool) { + if title, ok := t.cache.Get(url); ok { + return title.(string), true + } + return "", false +} + +func (t Titles) set(url, title string) { + t.cache.Add(url, title) +} + +func (t Titles) Parse(text string) { for _, v := range parseLinks(text) { if v == "" { continue } - title, ok := t.cache.Get(v) - if ok { + if title, ok := t.get(v); ok { fmt.Fprintf(t.w, "Title: %v (cached)", title) continue } title, err := fetch(v) if err == nil { - t.cache.Add(v, title) + t.set(v, title) fmt.Fprintf(t.w, "Title: %v", title) } } diff --git a/main.go b/main.go index c9ce13f..6e0ca34 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,10 @@ func (n *room) Kick(nick string, message ...string) { n.conn.Kick(n.target, nick, message...) } +func (n *room) Ban(nick string) { + n.conn.Mode(n.target, "+b", nick+"!*@*") +} + type message struct { title *title.Titles flood *flood.Check -- cgit v1.2.3