- Добавить bot_ready = threading.Event() для синхронизации - Переместить bot_ready.set() после цикла загрузки команд - Добавить bot_ready.wait() в console_input() - Меню появляется только после 'Бот вошёл' и 'Загружен: ...'
98 lines
2.9 KiB
Python
98 lines
2.9 KiB
Python
import asyncio
|
|
import os
|
|
import sys
|
|
import threading
|
|
|
|
import discord
|
|
from discord.ext import commands
|
|
from discord.ext.commands import CommandNotFound
|
|
from dotenv import load_dotenv
|
|
|
|
from commands import ALL_COMMANDS
|
|
from console_commands import ALL_CONSOLE_COMMANDS
|
|
|
|
load_dotenv()
|
|
|
|
intents = discord.Intents.default()
|
|
intents.message_content = True
|
|
|
|
bot = commands.Bot(command_prefix="!", intents=intents)
|
|
stop_event = threading.Event()
|
|
bot_ready = threading.Event()
|
|
|
|
|
|
@bot.event
|
|
async def on_ready():
|
|
print(f"Бот вошёл как {bot.user}")
|
|
for cog_class in ALL_COMMANDS:
|
|
cog = cog_class()
|
|
await bot.add_cog(cog)
|
|
for cog in bot.cogs:
|
|
print(f" Загружен: {cog}")
|
|
bot_ready.set()
|
|
|
|
|
|
@bot.event
|
|
async def on_command_error(ctx, error):
|
|
if isinstance(error, CommandNotFound):
|
|
return
|
|
print(f"Ошибка команды: {error}")
|
|
|
|
|
|
@bot.command(name="msg")
|
|
async def msg(ctx, *, text: str):
|
|
"""Повторяет текст после !msg"""
|
|
await ctx.send(text)
|
|
|
|
|
|
def console_input():
|
|
bot_ready.wait()
|
|
print("Доступные команды:")
|
|
available = {k: v for k, v in ALL_CONSOLE_COMMANDS.items() if k != "stop"}
|
|
for idx, (name, func) in enumerate(available.items(), 1):
|
|
print(f" {idx}. {name}")
|
|
print(" 0. stop")
|
|
|
|
while not stop_event.is_set():
|
|
try:
|
|
choice = input("\nВыберите команду (номер): ").strip()
|
|
if choice == "0":
|
|
print("\nОстановка бота...")
|
|
stop_event.set()
|
|
break
|
|
try:
|
|
idx = int(choice)
|
|
if 0 < idx <= len(available):
|
|
cmd_name = list(available.keys())[idx - 1]
|
|
ALL_CONSOLE_COMMANDS[cmd_name](stop_event, bot)
|
|
else:
|
|
print(f"Неизвестная команда: {choice}")
|
|
except (ValueError, IndexError):
|
|
print(f"Неизвестная команда: {choice}")
|
|
except (EOFError, KeyboardInterrupt):
|
|
stop_event.set()
|
|
try:
|
|
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5)
|
|
except Exception as e:
|
|
print(f"Ошибка при остановке бота: {e}")
|
|
break
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("Введите 'stop' для остановки бота")
|
|
|
|
thread = threading.Thread(target=console_input, daemon=True)
|
|
thread.start()
|
|
|
|
try:
|
|
token = os.getenv("DISCORD_TOKEN")
|
|
if not token:
|
|
print("Ошибка: токен не найден в .env")
|
|
sys.exit(1)
|
|
bot.run(token)
|
|
except KeyboardInterrupt:
|
|
print("\nОстановка бота...")
|
|
stop_event.set()
|
|
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result()
|
|
sys.exit(0)
|