如何创建整合扫雷与掷币命令的Discord机器人main.py文件
解决Discord机器人同时运行扫雷和掷币命令的问题
问题根源
mines_game.py末尾的bot.run(BOTTOKEN)会在被导入时直接执行,导致运行gambling_bot.py时实际启动的是扫雷的Bot实例- 两个文件各自创建独立的Bot/Client实例,无法同时运行,正确做法是使用Discord.py的Cog系统整合所有命令
步骤1:修改mines_game.py为Cog格式
移除独立的Bot实例和bot.run,将命令封装到Cog类中:
import discord import random from discord.ext import commands from keys import * class MinesGame(commands.Cog): def __init__(self, bot): self.bot = bot self.games = {} # 游戏状态存储到类内部 @commands.command() async def mines(self, ctx): message_data = self.games.get(ctx.author.id) if message_data: if message_data.get('game_over', False): grid_message = ':black_large_square: A B C D E\n' for number in ['1', '2', '3', '4', '5']: row = [f'{number} '] for letter in ['A', 'B', 'C', 'D', 'E']: row.append(':blue_square:') grid_message += ' '.join(row) + '\n' message = await ctx.send(grid_message) self.games[ctx.author.id] = { 'message_id': message.id, 'grid': {}, 'game_over': False } for letter in ['A', 'B', 'C', 'D', 'E']: for number in ['1', '2', '3', '4', '5']: self.games[ctx.author.id]['grid'][letter + number] = { 'status': ':blue_square:', 'updated': False } else: message = await ctx.channel.fetch_message(message_data['message_id']) grid_message = ':black_large_square: A B C D E\n' for number in ['1', '2', '3', '4', '5']: row = [f'{number} '] for letter in ['A', 'B', 'C', 'D', 'E']: row.append(message_data['grid'][letter + number]['status']) grid_message += ' '.join(row) + '\n' await message.edit(content=grid_message) else: grid_message = ':black_large_square: A B C D E\n' for number in ['1', '2', '3', '4', '5']: row = [f'{number} '] for letter in ['A', 'B', 'C', 'D', 'E']: row.append(':blue_square:') grid_message += ' '.join(row) + '\n' message = await ctx.send(grid_message) self.games[ctx.author.id] = { 'message_id': message.id, 'grid': {}, 'game_over': False } for letter in ['A', 'B', 'C', 'D', 'E']: for number in ['1', '2', '3', '4', '5']: self.games[ctx.author.id]['grid'][letter + number] = { 'status': ':blue_square:', 'updated': False } @commands.command(aliases=['u']) async def update(self, ctx, *squares: str): if self.games.get(ctx.author.id, {}).get('game_over', False): await ctx.send(f"{ctx.author.mention} 游戏已结束!使用 !mines 重新开始。") return message_data = self.games.get(ctx.author.id) if not message_data or 'message_id' not in message_data: await ctx.send(f"{ctx.author.mention} 你还未启动扫雷游戏!") return if 'grid' not in message_data: message_data['grid'] = {} for letter in ['A', 'B', 'C', 'D', 'E']: for number in ['1', '2', '3', '4', '5']: message_data['grid'][letter + number] = { 'status': ':blue_square:', 'updated': False } for square in squares: square = square.upper() if len(square) < 2 or square[0] not in ['A', 'B', 'C', 'D', 'E'] or square[1] not in ['1', '2', '3', '4', '5']: await ctx.send(f"{ctx.author.mention} 无效格子 '{square}'!") continue if message_data['grid'][square]['updated']: await ctx.send(f"{ctx.author.mention} 每个格子只能操作一次!") continue message_data['grid'][square]['updated'] = True if random.random() < 0.2: message_data['grid'][square]['status'] = ':bomb:' message_data['game_over'] = True await ctx.send(f"{ctx.author.mention} 踩到炸弹了 ): 使用 !mines 重新开始") else: message_data['grid'][square]['status'] = ':green_square:' message = await ctx.channel.fetch_message(message_data['message_id']) grid_message = ':black_large_square: A B C D E\n' for number in ['1', '2', '3', '4', '5']: row = [f'{number} '] for letter in ['A', 'B', 'C', 'D', 'E']: row.append(message_data['grid'][letter + number]['status']) grid_message += ' '.join(row) + '\n' await message.edit(content=grid_message) async def setup(bot): await bot.add_cog(MinesGame(bot))
步骤2:修改gambling_bot.py为Cog格式
移除独立的Client实例和client.run,将掷币命令封装到Cog类中:
import discord import random from discord.ext import commands from keys import * class GamblingGame(commands.Cog): def __init__(self, bot): self.bot = bot @commands.command() async def flip(self, ctx, odds: float = 0.1): if not 0 <= odds <= 1: await ctx.send("概率值必须在0到1之间!") return result = 'heads' if random.random() < odds else 'tails' await ctx.send(f"The coin landed on {result}!") async def setup(bot): await bot.add_cog(GamblingGame(bot))
步骤3:创建main.py作为唯一启动入口
这是机器人的核心启动文件,负责加载所有游戏模块:
import discord from discord.ext import commands from keys import * # 配置Intents(必须开启消息内容权限) intents = discord.Intents.all() intents.message_content = True # 创建唯一的Bot实例 bot = commands.Bot(command_prefix='!', intents=intents) @bot.event async def on_ready(): print(f'Logged in as {bot.user}') # 加载所有游戏模块 await bot.load_extension('mines_game') await bot.load_extension('gambling_bot') print("所有游戏模块已加载完成") # 启动机器人 bot.run(BOTTOKEN)
注意事项
- 确保Discord开发者平台中,你的机器人已开启Message Content Intent权限
- 三个文件需放在同一目录下,
keys.py文件包含正确的BOTTOKEN - 运行时仅需执行
python main.py,不要单独运行mines_game.py或gambling_bot.py
内容的提问来源于stack exchange,提问作者brainpower515
相关产品推荐
相关产品推荐

