39 lines
1.7 KiB
Python
39 lines
1.7 KiB
Python
import asyncio,discord
|
|
from discord.ext import commands
|
|
from core.ctx import Ctx
|
|
from core.limiter import Limiter
|
|
async def setup(bot):
|
|
lim=Limiter()
|
|
async def run(ctx,st,wait,uid):
|
|
try:
|
|
if wait>0:await asyncio.sleep(wait)
|
|
st.tasks.discard(asyncio.current_task())
|
|
await bot.invoke(ctx)
|
|
except asyncio.CancelledError:pass
|
|
except Exception as e:bot.hook.put(f"dispatch failed for {uid}: {e!r}"[:1900])
|
|
async def handler(m):
|
|
if m.author.bot or not m.content.startswith(await bot.get_prefix(m)):return
|
|
uid=m.author.id
|
|
if uid!=bot.user.id and uid not in bot.wl:return
|
|
ctx=await bot.get_context(m,cls=Ctx)
|
|
if ctx.command is None:return
|
|
st,wait,full=lim.admit(uid)
|
|
if full:
|
|
n=lim.flush(st)
|
|
bot.hook.put(f"{m.author} ({uid}) flooded, {n} pending commands dropped")
|
|
try:await m.add_reaction("\u274c")
|
|
except Exception:pass
|
|
try:await m.reply(f"too many pending commands, {n} dropped",mention_author=False)
|
|
except Exception:pass
|
|
return
|
|
ctx.limited=wait>0
|
|
where=f"#{getattr(m.channel,'name',None) or 'dm'} ({m.guild.name if m.guild else 'dm'})"
|
|
bot.hook.put(f"{m.author} ({uid}) ran `{m.content[:200]}` in {where}")
|
|
lim.track(uid,st,asyncio.create_task(run(ctx,st,wait,uid)))
|
|
async def on_command_error(ctx,e):
|
|
if isinstance(e,(commands.CommandNotFound,commands.CheckFailure)):return
|
|
bot.hook.put(f"error in `{ctx.command}` by {ctx.author.id}: `{e!r}`"[:1900])
|
|
try:await ctx.send(f"error: `{e}`"[:1900])
|
|
except Exception:pass
|
|
bot.on_message=handler;bot.on_command_error=on_command_error
|