Discord机器人休假管理命令CSV读写异常排查及优化方案咨询
代码异常的核心原因
你现有代码存在4个关键逻辑错误,直接导致权限溢出和读写异常:
- 文件写入模式错误:休假命令使用
w模式打开CSV文件,每次写入会直接覆盖整个文件内容,仅会保留最后一个休假用户的ID,之前的所有休假记录都会被清空。同时你写入ID时没有添加换行符,多个用户休假时ID会拼接成一个字符串,读取时无法正确拆分。 - 记录对象错误:休假命令支持传入
member参数为其他用户办理休假,但写入CSV的是执行命令的ctx.author.id(操作者ID),而非实际休假的member.id,记录完全错位。 - 销假判断逻辑完全写反:现有逻辑是
found == False(用户不在当前职级的休假记录里)时,直接给用户发放对应职级的身份组,完全没有校验用户的原始身份,这就是Moderator可以用Admin销假命令获取Admin权限的核心原因。 - 销假命令无权限校验:销假命令没有加角色限制,任何用户都可以随意调用,只要不在对应职级的休假记录中就能拿到高权限身份组,属于严重的权限漏洞。
修复后的Moderator职级命令示例
import csv import os @client.command() @commands.has_role('Moderator') async def slm(ctx, member: discord.Member = None): if not member: member = ctx.author loa = ctx.guild.get_role(848032714715561985) mod = ctx.guild.get_role(848032880709074944) await member.add_roles(loa) await member.remove_roles(mod) # 改用a模式追加写入,加换行符避免ID拼接 with open("modRecord.csv", "a", newline="") as file: writer = csv.writer(file) writer.writerow([str(member.id)]) await ctx.send("I have filed your Leave, take care, we look forward to your return!") @client.command() @commands.has_role('Leave of Absence') # 仅休假状态用户可调用,也可自定义其他校验规则 async def srm(ctx, member: discord.Member = None): if not member: member = ctx.author mod = ctx.guild.get_role(848032880709074944) loa = ctx.guild.get_role(848032714715561985) found = False # 先读取所有记录 records = [] if os.path.exists("modRecord.csv"): with open('modRecord.csv', 'r') as file: reader = csv.reader(file) for row in reader: if row and row[0] == str(member.id): found = True else: records.append(row) # 逻辑修正:只有在记录里找到才恢复身份 if found: # 销假后删除对应记录 with open("modRecord.csv", "w", newline="") as file: writer = csv.writer(file) writer.writerows(records) await member.add_roles(mod) await member.remove_roles(loa) await ctx.send("Welcome back!") else: await ctx.send("We do not have history of you having a Moderator role.")
更优的存储方案
- 单CSV统一存储:不用为每个职级单独创建存储文件,统一用一个CSV记录三列内容:
用户ID、原职级身份组ID、休假时间,避免多文件读写的混淆问题,维护成本更低。 - SQLite轻量数据库:比CSV更稳定,支持结构化查询,不需要手动处理文件覆盖、换行、重复记录等问题,并发读写安全性更高,非常适合这类小数据量的业务场景。
- JSON文件存储:结构比CSV清晰,可以用字典结构存储,key为用户ID,value存储对应的原职级、休假时间等信息,读写代码更简洁,不需要处理行遍历逻辑。
内容的提问来源于stack exchange,提问作者Booker5677
相关产品推荐
相关产品推荐

