#python #discord #discord.py #bots
Вопрос:
Я создаю бота discord, который отправляет сообщение, когда другое пользователь вводит определенное слово, и оно работает нормально, но мне нужно, чтобы бот мог остановить свой процесс и игнорировать команды в течение короткого периода времени, если слово, необходимое для его активации, набирается много за короткий промежуток времени.
Я проделал некоторую работу над своим кодом для обнаружения спама, но все еще не могу понять, как его остановить.
import os
import discord
import datetime
import time
from keep_on import keep_on
bot_token = os.environ['TOKEN']
client = discord.Client()
@client.event
async def on_ready():
print('{0.user} is online'.format(client))
print('###########################################')
enabled = True
time_storage = int(datetime.datetime.utcnow().timestamp())
@client.event
async def on_message(message):
global enabled
global time_storage
sentWord = message.content
CSentWord = sentWord.upper()
if message.content == "!start":
enabled = True
await message.channel.send("Having Trouble?")
await message.channel.send(file=discord.File('Having trouble.png'))
elif message.content == "!stop":
enabled = False
await message.channel.send("Ok Ill Stop.")
await message.channel.send(file=discord.File('Joey will stop.png'))
elif enabled == True:
if message.author == client.user:
return
if "SORRY" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "S_O_R_R_Y" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "S.O.R.R.Y" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "S|O|R|R|Y" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "S/O/R/R/Y" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "SORRY" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "FEEL BAD" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if ".F.E.E.L. .B.A.D." in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if ".F.E.E.L.B.A.D." in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "FEELBAD" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "F_E_E_L_B_A_D" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
if "F|E|E|L B|A|D" in CSentWord:
time.sleep(0.5)
time_delay = int(datetime.datetime.utcnow().timestamp())
time_difference = time_delay - time_storage
print('time since last stored:',time_storage)
print('time now:',time_delay)
print('time difference:',time_difference)
print('###########################################')
if time_difference < 5:
await message.channel.send("You are moving too fast")
await message.channel.send(file=discord.File('Bruh what.png'))
time.sleep(2)
return
await message.channel.send("'We're Very Sorry' - Joey Tribbiani")
await message.channel.send(file=discord.File('Joey Is Sorry.png'))
time_storage = int(datetime.datetime.utcnow().timestamp())
keep_on()
client.run(os.getenv('TOKEN'))
Комментарии:
1. Может быть, добавить флаг операции, который не входит в ваши дела, не связанные со спамом? Установите его при вводе и снимите, когда закончите операцию? Или другим способом было бы использовать ваш асинхронный ввод в очередь с максимальным размером. Если с ФИФО должно быть довольно просто справиться.
2. не могли бы вы объяснить это с помощью какого-нибудь кода?
Ответ №1:
Есть декоратор в discord.py перепишите, чтобы установить время восстановления для команды.
@commands.cooldown(1, 30, commands.BucketType.user)
Но для этого вам нужно переписать своего бота для работы с командами discord.ext.
from discord.ext import commands # you need this
import discord
bot = commands.Bot(command_prefix=";", intents=intents)
В противном случае вы могли бы взять текущую метку времени, когда команда была запущена с помощью datetime.datetime (), и сохранить ее в переменной. Затем в следующий раз, когда он будет запущен, вы можете проверить, достаточно ли времени текущей даты-времени с момента переменной before
Комментарии:
1. здравствуйте, я провел последнее время, работая над этим, и мне удалось заставить работать отметку времени, и когда появляется спам, он отправляет другое сообщение, но оно все равно будет спамом. например, если вы отправили 3 сообщения за короткий промежуток времени, он распознает, что вы отправляете спам, и отправит другое сообщение, но он отправляет одно и то же сообщение 3 раза, и я бы хотел, чтобы он отправил 1 сообщение и забыл об остальном. Я использовал вашу рекомендацию для datetime.datetime, но после некоторых исследований я использовал int(datetime.datetime.utcnow().отметка времени ()), которая работала лучше
Ответ №2:
Я думал о чем-то подобном для флага операции, так как у вас уже есть флаг включения. Просто добавьте еще один глобальный флаг для работы.
enabled = True
busy = False
@client.event
async def on_message(message):
global enabled, busy
if busy:
pass #do nothing or you can show that something is spamming
else:
if case1:
busy = True
#do stuff
busy = False
else:
busy = True
#do another thing
busy = False
Я думаю, что вышесказанное вынудит только к единичным действиям. так что на самом деле это не асинхронно, а только 1 ввод за раз. Вы можете разрешить ему не прерывать определенные действия, так что это простой способ защитить ваш код.
Другим методом может быть использование очереди. Этот способ потребует сравнения входящих сообщений в соответствии с определенными правилами, чтобы они были спамом. Как только вы определите правила для спама, вы сможете создать небольшую проверку перед выполнением, чтобы определить, следует ли выполнять команду или нет. https://docs.python.org/3/library/asyncio-queue.html
Вы можете использовать очередь, чтобы поставить свои команды в очередь, а затем вставить их и проверить. При максимальном ограничении очереди вы можете получить сообщение об ошибке, если очередь заполнена. Может быть:
command_queue = Queue(maxsize = 5)#maximum number of items in the queue
@client.event
async def on_message(message):
global command_queue
if command_queue.full():
print("We are being spammed")
#we dont put anything more into the queue
else:
command_queue.put((message,datetime.datetime.now())) #you now have the message, and the time it was input.
#You will have to determine the rules of what should be ignored or not.
#Maybe you can even include the sender.
#example may be, any set of messages sent by the same sender within 3 seconds of the previous message should be ignored.
#your stuff here
#Depending on what is available on the discord api, you can even group your commands by sender and content and insert your rules here before entering your main processing logic.
Комментарии:
1. нужно ли мне что-либо импортировать, чтобы использовать очередь?
2. Смотрите страницу python, на которую я ссылался. Это библиотека.