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

如何使用Discord.py开发积分系统,解决触发违规词后积分不更新问题

问题成因
  • score是定义在on_message事件回调函数内的局部变量:每次有新消息触发on_message事件时,都会执行score = 30把分数重置为初始值,之前的扣分修改完全不会被保留。
  • 逻辑顺序错误:查询分数的代码写在了扣分逻辑的前面,就算单次消息触发里包含违规词,也会先返回还未扣分的分数,再执行扣分操作,查询结果自然不符合预期。
  • 没有做用户维度隔离:当前代码所有用户共用同一个分数变量,实际使用时不同用户的分数会互相干扰。
修复方案
  1. 把分数存储改为全局字典结构,键为用户ID,值为对应用户的分数,实现多用户分数隔离;如果需要重启Bot后分数不丢失,可以额外增加JSON文件持久化逻辑。
  2. 调整on_message内的逻辑顺序,先处理违规词扣分逻辑,再处理查询类指令。
  3. 初始化用户分数时优先从字典中读取,不存在该用户记录时再赋值默认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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:45:01