Add anti-flooding settings (irc). See #40

This commit is contained in:
Wim 2016-11-01 22:52:28 +01:00
parent 6f309f2108
commit be513622ac
2 changed files with 30 additions and 3 deletions

View File

@ -34,6 +34,8 @@ type Protocol struct {
Password string // IRC,mattermost,XMPP Password string // IRC,mattermost,XMPP
PrefixMessagesWithNick bool // mattemost, slack PrefixMessagesWithNick bool // mattemost, slack
Protocol string //all protocols Protocol string //all protocols
MessageQueue int // IRC, size of message queue for flood control
MessageDelay int // IRC, time in millisecond to wait between messages
RemoteNickFormat string // all protocols RemoteNickFormat string // all protocols
Server string // IRC,mattermost,XMPP,discord Server string // IRC,mattermost,XMPP,discord
ShowJoinPart bool // all protocols ShowJoinPart bool // all protocols

View File

@ -23,6 +23,7 @@ type Birc struct {
protocol string protocol string
Remote chan config.Message Remote chan config.Message
connected chan struct{} connected chan struct{}
Local chan config.Message // local queue for flood control
} }
var flog *log.Entry var flog *log.Entry
@ -32,15 +33,22 @@ func init() {
flog = log.WithFields(log.Fields{"module": protocol}) flog = log.WithFields(log.Fields{"module": protocol})
} }
func New(config config.Protocol, origin string, c chan config.Message) *Birc { func New(cfg config.Protocol, origin string, c chan config.Message) *Birc {
b := &Birc{} b := &Birc{}
b.Config = &config b.Config = &cfg
b.Nick = b.Config.Nick b.Nick = b.Config.Nick
b.Remote = c b.Remote = c
b.names = make(map[string][]string) b.names = make(map[string][]string)
b.origin = origin b.origin = origin
b.protocol = protocol b.protocol = protocol
b.connected = make(chan struct{}) b.connected = make(chan struct{})
if b.Config.MessageDelay == 0 {
b.Config.MessageDelay = 1300
}
if b.Config.MessageQueue == 0 {
b.Config.MessageQueue = 30
}
b.Local = make(chan config.Message, b.Config.MessageQueue+10)
return b return b
} }
@ -81,6 +89,7 @@ func (b *Birc) Connect() error {
return fmt.Errorf("connection timed out") return fmt.Errorf("connection timed out")
} }
i.Debug = false i.Debug = false
go b.doSend()
return nil return nil
} }
@ -115,11 +124,27 @@ func (b *Birc) Send(msg config.Message) error {
return nil return nil
} }
for _, text := range strings.Split(msg.Text, "\n") { for _, text := range strings.Split(msg.Text, "\n") {
b.i.Privmsg(msg.Channel, msg.Username+text) if len(b.Local) < b.Config.MessageQueue {
if len(b.Local) == b.Config.MessageQueue-1 {
text = text + " <message clipped>"
}
b.Local <- config.Message{Text: text, Username: msg.Username, Channel: msg.Channel}
} else {
flog.Debugf("flooding, dropping message (queue at %d)", len(b.Local))
}
} }
return nil return nil
} }
func (b *Birc) doSend() {
rate := time.Millisecond * time.Duration(b.Config.MessageDelay)
throttle := time.Tick(rate)
for msg := range b.Local {
<-throttle
b.i.Privmsg(msg.Channel, msg.Username+msg.Text)
}
}
func (b *Birc) endNames(event *irc.Event) { func (b *Birc) endNames(event *irc.Event) {
channel := event.Arguments[1] channel := event.Arguments[1]
sort.Strings(b.names[channel]) sort.Strings(b.names[channel])