如何显示用户正在玩的游戏而非其自定义状态?
解决Discord.py机器人误将自定义状态识别为游戏的问题
问题出在你只取了用户的第一个活动(after.activity),而用户手动设置的自定义"正在玩"状态会排在真正的游戏活动前面,同时自定义状态和游戏活动的类型都是ActivityType.playing,导致机器人把自定义内容当成了游戏名。
要正确识别真正的游戏,需要:
- 遍历用户的所有活动(
after.activities)而非只取第一个 - 区分系统检测的游戏活动和用户自定义的playing活动:
- 系统检测的游戏属于
discord.Game类(Activity的子类) - 自定义的playing活动是普通
Activity对象,没有官方游戏的标识(比如application_id)
- 系统检测的游戏属于
修改后的代码
import discord from discord.abc import GuildChannel intents = discord.Intents.default() intents.message_content = True intents.presences = True intents.members = True client = discord.Client(intents=intents) gameCheck = True @client.event async def on_ready(): print(f'We have logged in as {client.user}') @client.event async def on_presence_update(before, after): if not gameCheck: return # 检查开关状态,关闭时不执行通知 # 筛选出after中所有真正的游戏活动(Game实例) after_games = [activity for activity in after.activities if isinstance(activity, discord.Game)] # 筛选出before中已有的游戏活动名称 before_game_names = {game.name for game in before.activities if isinstance(game, discord.Game)} # 找出用户新开始玩的游戏 new_games = [game for game in after_games if game.name not in before_game_names] for game in new_games: game_name = game.name print(f"{after.name} is now playing {game_name}") system_channel = client.guilds[0].system_channel if system_channel is not None: await system_channel.send(f"{after.name} is now playing {game_name}") @client.event async def on_message(message): global gameCheck if message.author == client.user: return if message.content.startswith('$toggle'): gameCheck = not gameCheck await message.channel.send(f'Game check toggled to {gameCheck}') client.run('TOKEN')
额外优化(针对小众游戏)
如果有些小众游戏不被识别为Game实例,可以通过检查application_id来补充判断(自定义活动没有该属性):
after_games = [ activity for activity in after.activities if activity.type == discord.ActivityType.playing and hasattr(activity, 'application_id') and activity.application_id is not None ]
内容的提问来源于stack exchange,提问作者Gianmichael Romano
相关产品推荐
相关产品推荐

