Add initial flood prevention
This commit is contained in:
parent
8e16575d3b
commit
85a7967888
3 changed files with 39 additions and 2 deletions
|
@ -29,6 +29,10 @@ templates:
|
|||
default_flags:
|
||||
- ignorecase
|
||||
|
||||
antispam:
|
||||
max: 2
|
||||
delay: 60
|
||||
|
||||
rules:
|
||||
twim_cookies:
|
||||
rooms: ["!FPUfgzXYWTKgIrwKxW:matrix.org"]
|
||||
|
|
|
@ -13,9 +13,12 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from typing import Type, Tuple
|
||||
from typing import Type, Tuple, Dict
|
||||
import time
|
||||
|
||||
from mautrix.types import EventType, MessageType
|
||||
from attr import dataclass
|
||||
|
||||
from mautrix.types import EventType, MessageType, UserID, RoomID
|
||||
from mautrix.util.config import BaseProxyConfig
|
||||
|
||||
from maubot import Plugin, MessageEvent
|
||||
|
@ -24,8 +27,27 @@ from maubot.handlers import event
|
|||
from .config import Config, ConfigError
|
||||
|
||||
|
||||
@dataclass
|
||||
class FloodInfo:
|
||||
rb: 'ReactBot'
|
||||
count: int
|
||||
last_message: int
|
||||
|
||||
def bump(self) -> bool:
|
||||
now = int(time.time())
|
||||
if self.last_message + self.rb.config["antispam.delay"] < now:
|
||||
self.count = 0
|
||||
self.count += 1
|
||||
if self.count > self.rb.config["antispam.max"]:
|
||||
return True
|
||||
self.last_message = now
|
||||
return False
|
||||
|
||||
|
||||
class ReactBot(Plugin):
|
||||
allowed_msgtypes: Tuple[MessageType, ...] = (MessageType.TEXT, MessageType.EMOTE)
|
||||
user_flood: Dict[UserID, FloodInfo]
|
||||
room_flood: Dict[RoomID, FloodInfo]
|
||||
|
||||
@classmethod
|
||||
def get_config_class(cls) -> Type[BaseProxyConfig]:
|
||||
|
@ -33,6 +55,8 @@ class ReactBot(Plugin):
|
|||
|
||||
async def start(self) -> None:
|
||||
await super().start()
|
||||
self.user_flood = {}
|
||||
self.room_flood = {}
|
||||
self.on_external_config_update()
|
||||
|
||||
def on_external_config_update(self) -> None:
|
||||
|
@ -42,6 +66,11 @@ class ReactBot(Plugin):
|
|||
except ConfigError:
|
||||
self.log.exception("Failed to load config")
|
||||
|
||||
def is_flood(self, evt: MessageEvent) -> bool:
|
||||
uf = self.user_flood.setdefault(evt.sender, FloodInfo(rb=self, count=0, last_message=0))
|
||||
rf = self.room_flood.setdefault(evt.room_id, FloodInfo(rb=self, count=0, last_message=0))
|
||||
return uf.bump() or rf.bump()
|
||||
|
||||
@event.on(EventType.ROOM_MESSAGE)
|
||||
async def event_handler(self, evt: MessageEvent) -> None:
|
||||
if evt.sender == self.client.mxid or evt.content.msgtype not in self.allowed_msgtypes:
|
||||
|
@ -49,6 +78,8 @@ class ReactBot(Plugin):
|
|||
for name, rule in self.config.rules.items():
|
||||
match = rule.match(evt)
|
||||
if match is not None:
|
||||
if self.is_flood(evt):
|
||||
return
|
||||
try:
|
||||
await rule.execute(evt, match)
|
||||
except Exception:
|
||||
|
|
|
@ -37,6 +37,8 @@ class Config(BaseProxyConfig):
|
|||
helper.copy("rules")
|
||||
helper.copy("templates")
|
||||
helper.copy("default_flags")
|
||||
helper.copy("antispam.max")
|
||||
helper.copy("antispam.delay")
|
||||
|
||||
def parse_data(self) -> None:
|
||||
self.default_flags = re.RegexFlag(0)
|
||||
|
|
Loading…
Reference in a new issue