如何使用Discord.py开发积分系统,解决触发违规词后积分不更新问题
问题成因
score是定义在on_message事件回调函数内的局部变量:每次有新消息触发on_message事件时,都会执行score = 30把分数重置为初始值,之前的扣分修改完全不会被保留。- 逻辑顺序错误:查询分数的代码写在了扣分逻辑的前面,就算单次消息触发里包含违规词,也会先返回还未扣分的分数,再执行扣分操作,查询结果自然不符合预期。
- 没有做用户维度隔离:当前代码所有用户共用同一个分数变量,实际使用时不同用户的分数会互相干扰。
修复方案
- 把分数存储改为全局字典结构,键为用户ID,值为对应用户的分数,实现多用户分数隔离;如果需要重启Bot后分数不丢失,可以额外增加JSON文件持久化逻辑。
- 调整
on_message内的逻辑顺序,先处理违规词扣分逻辑,再处理查询类指令。 - 初始化用户分数时优先从字典中读取,不存在该用户记录时再赋值默认30分。
修复后的代码示例:
import discord import os import json client = discord.Client() insulte = ["noob", "shut up", "ur mom", "ez"] # 全局分数字典,存储每个用户的信用分 user_scores = {} # 取消下面注释即可实现分数持久化,重启Bot也不会丢失历史分数 # def load_scores(): # global user_scores # if os.path.exists('scores.json'): # with open('scores.json', 'r', encoding='utf-8') as f: # user_scores = json.load(f) # def save_scores(): # with open('scores.json', 'w', encoding='utf-8') as f: # json.dump(user_scores, f, ensure_ascii=False, indent=2) @client.event async def on_ready(): # load_scores() # 启动时加载历史分数 print('已成功登录为 {0.user}'.format(client)) @client.event async def on_message(message): if message.author == client.user: return # 获取当前用户的分数,不存在则初始化为30 user_id = str(message.author.id) if user_id not in user_scores: user_scores[user_id] = 30 score = user_scores[user_id] msg = message.content # 先处理违规词扣分逻辑 if any(word in msg for word in insulte): score -= 10 user_scores[user_id] = score # save_scores() # 扣分后保存到文件,实现持久化 await message.channel.send('您被扣了10点信用分。') if msg.startswith('$cs hello'): await message.channel.send('hello!') if msg.startswith('$cs cs'): await message.channel.send('您当前的信用分为:' + str(score)) client.run(os.getenv('TOKEN'))
内容的提问来源于stack exchange,提问作者ENDERastronaute
相关产品推荐
相关产品推荐

