You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nextcord机器人开发:JSON存储读取怪物信息并生成Embed命令问题求解

Nextcord机器人怪物信息管理功能修复方案

现有代码存在的问题

  • 变量未定义:addskillset命令中判断怪物是否存在时使用的monster_name变量未提前声明,应该使用存储用户输入的answers[0]作为怪物名
  • JSON写入逻辑错误:新增怪物时错误地先给内层字段monster_name赋值空字典,正确写法是先给外层怪物名对应的键赋值空字典
  • 反应校验逻辑错误:校验用户反应的check函数判断条件写错误,原写法会让任意非作者用户的❌反应也能通过校验
  • 数据读取逻辑错误:skilltest命令中命中怪物后直接从外层JSON字典取属性,正确应该从对应怪物名的内层字典中读取属性
  • 字段名不统一:预期JSON结构的描述、图片字段首字母大写,代码中使用的是全小写,会导致读取时找不到对应字段
  • 文件操作不规范:skilltest中读取文件后未主动关闭,缺少JSON文件不存在时的兜底处理

修复后的完整代码

前置依赖与工具函数

import nextcord
from nextcord.ext import commands
import json
import asyncio

client = commands.Bot(command_prefix="!", intents=nextcord.Intents.all())

# 修复工具函数,增加文件不存在的兜底处理
async def get_skillsets_data():
    try:
        with open('skillsets.json','r', encoding='utf-8') as f:
            monsters = json.load(f)
    except FileNotFoundError:
        # 文件不存在时返回空字典
        monsters = {}
    return monsters

新增怪物信息命令

@client.command()
async def addskillset(ctx):
    await ctx.send("Let's add this skillset!")
    questions = ["What is the monster name?","What is the monster description?","what is the monster image link?"]
    answers = []

    # 补充收集用户回答的逻辑(原代码缺失部分)
    for q in questions:
        await ctx.send(q)
        def check_msg(m):
            return m.author == ctx.author and m.channel == ctx.channel
        try:
            msg = await client.wait_for('message', timeout=120.0, check=check_msg)
            answers.append(msg.content)
        except asyncio.TimeoutError:
            await ctx.send("操作超时,已取消添加")
            return

    embedkra = nextcord.Embed(title = f"{answers[0]}", description = f"{answers[1]}",color=ctx.author.color)
    embedkra.set_image(url = f"{answers[2]}")
    mess = await ctx.reply(embed=embedkra,mention_author=False)
    
    await mess.add_reaction('✅')
    await mess.add_reaction('❌')

    # 修复反应校验逻辑
    def check(reaction, user):
        return user == ctx.author and str(reaction.emoji) in ["✅", "❌"]
    try:
        reaction, user = await client.wait_for('reaction_add', timeout=1000.0, check=check)
    except asyncio.TimeoutError:
        await ctx.send("确认超时,已取消添加")
    else:
        if reaction.emoji == "✅":
            monsters = await get_skillsets_data()
            monster_name = answers[0].lower() # 统一用小写作为键,避免大小写不同导致重复添加
            if monster_name in monsters:
                await ctx.reply("该怪物已存在")
            else:
                # 修复JSON写入逻辑,先给外层键赋值空字典
                monsters[monster_name] = {}
                monsters[monster_name]["monster_name"] = answers[0]
                monsters[monster_name]["monster_description"] = answers[1]
                monsters[monster_name]["monster_image"] = answers[2]

                with open('skillsets.json','w', encoding='utf-8') as f:
                    json.dump(monsters,f, ensure_ascii=False, indent=2)

                await mess.delete()
                await ctx.reply(f"{answers[0]} 已成功添加到列表")
        else:
            await mess.delete()
            await ctx.send("已取消添加操作")

查询怪物信息命令

@client.command()
async def skilltest(ctx,*,monster_name):
    monsters = await get_skillsets_data()
    search_key = monster_name.lower()
    if search_key in monsters:
        # 修复取值逻辑,从对应怪物的内层字典取属性
        monster_data = monsters[search_key]
        name = monster_data["monster_name"]
        description = monster_data["monster_description"]
        link = monster_data["monster_image"]

        embedkra = nextcord.Embed(title = f"{name}", description = f"{description}",color=ctx.author.color)
        embedkra.set_image(url = f"{link}")
        await ctx.reply(embed=embedkra,mention_author=False)        

    else:
        await ctx.reply("未找到该怪物",mention_author=False)

额外优化说明

  • 统一使用怪物名的小写形式作为JSON的键,避免用户输入大小写不同导致重复添加同一怪物
  • 增加了JSON读写时的UTF-8编码指定,避免中文乱码
  • 补充了原代码缺失的用户回答收集逻辑
  • 增加了JSON文件不存在时的兜底处理,首次运行无需手动创建空文件
  • 写入JSON时增加了缩进格式化,方便手动查看修改文件内容

内容的提问来源于stack exchange,提问作者RainbowGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:45:01