]> jfr.im git - irc/rizon/acid.git/blob - pyva/pyva/src/main/python/pseudoclient/sys_antiflood.py
Split pyva plugin into pyva.core and pyva.pyva
[irc/rizon/acid.git] / pyva / pyva / src / main / python / pseudoclient / sys_antiflood.py
1 import time
2 import threading
3 from sys_base import *
4 import istring
5
6 class AntiFloodManager(Subsystem):
7 def __init__(self, module):
8 Subsystem.__init__(self, module, module.options, 'antiflood')
9 self.lock_user = threading.Lock()
10 self.users = {}
11
12 def on_reload(self):
13 self.delay_base_user = self.get_option('delay_base_user', int, 1)
14 self.delay_mult_pre_warn_user = self.get_option('delay_mult_pre_warn_user', int, 3)
15 self.delay_mult_post_warn_user = self.get_option('delay_mult_post_warn_user', int, 10)
16 self.ban_duration_user = self.get_option('ban_duration_user', int, 5 * 24 * 60 * 60)
17 self.score_ban_user = self.get_option('score_ban_user', int, 6)
18 self.score_warn_user = self.get_option('score_warn_user', int, 3)
19 self.points_user = self.get_option('points_user', int, 1)
20 self.points_repeat_user = self.get_option('points_repeat_user', int, 2)
21 self.warning_message_user = self.get_option('warning_message_user', unicode, 'Slow down, wait @timeout seconds! If you continue flooding the bot you will be banned.')
22
23 def get_delay_user(self, score):
24 score_pre_warn = score
25 score_post_warn = 0
26
27 if score > self.score_warn_user:
28 score_post_warn = score - self.score_warn_user
29 score_pre_warn = self.score_warn_user
30
31 return self.delay_base_user + (score_pre_warn * self.delay_mult_pre_warn_user) + (score_post_warn * self.delay_mult_post_warn_user)
32
33 def check_user(self, username, command, argument):
34 command = command.lower().strip()
35 argument = argument.lower().strip()
36 now = int(time.time())
37
38 try:
39 self.lock_user.acquire()
40
41 if not username in self.users:
42 self.users[username] = [now, 0, command, argument]
43 return False
44
45 user = self.users[username]
46
47 if now - user[0] <= self.get_delay_user(user[1]):
48 if user[2] == command and user[3] == argument:
49 user[1] += self.points_repeat_user
50 else:
51 user[2] = command
52 user[3] = argument
53 user[1] += self.points_user
54 else:
55 user[1] = 0
56 user[2] = command
57 user[3] = argument
58
59 user[0] = now
60 finally:
61 self.lock_user.release()
62
63 if user[1] >= self.score_ban_user:
64 self.module.users.ban(username, "anti-flood", "flooding", now, now + self.ban_duration_user)
65 self.module.elog.warning('Banned @b%s@b for flooding.' % username)
66 user[0] = -1
67 return True
68
69 if user[1] >= self.score_warn_user:
70 self.module.notice(username, self.warning_message_user.replace('@timeout', istring(self.get_delay_user(user[1]))))
71
72 return False
73
74 def commit(self):
75 new_users = {}
76 now = int(time.time())
77 self.lock_user.acquire()
78
79 for username in self.users:
80 user = self.users[username]
81
82 if now - user[0] <= self.get_delay_user(user[1]):
83 new_users[username] = user
84
85 self.users = new_users
86 self.lock_user.release()