我不确定代码是否因为 on_message(ctx)
而无法工作,无论哪种方式,都是我所做的:
import discord
from discord.ext import commands
import pymongo
import os
from pymongo import MongoClient
mango_url = "mongodb+srv://<usernamehere>:<password>@discordbot.kllv6.mongodb.net/discordbot?
retryWrites=true&w=majority"
cluster = MongoClient(mango_url)
db = cluster["discordbot"]
collection = db["discordbot"]
client = commands.Bot(command_prefix = '$')
@client.event
async def on_ready():
print("bot is online")
@client.command()
async def _ping(ctx):
await ctx.send('discord sucks :(')
@client.event
async def on_message(ctx):
author_id = ctx.author.id
guild_id = ctx.guild.id
author = ctx.author
user_id = {"_id": author_id}
if ctx.author == client.user:
return
if ctx.author.bot:
return
if(collection.count_documents({}) == 0):
user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
collection.insert_one(user_info)
if(collection.count_documents(user_id) == 0):
user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
collection.insert_one(user_info)
exp = collection.find(user_id)
for xp in exp:
cur_xp = xp["XP"]
new_xp = cur_xp + 1
collection.update_one({"_id": author_id}, {"$set":{"XP":new_xp}}, upsert=True)
#await ctx.channel.send("1 xp up")
lvl = collection.find(user_id)
for levl in lvl:
lvl_start = levl["Level"]
new_level = lvl_start + 1
if cur_xp >= round(5 * (lvl_start ** 4 / 5)):
collection.update_one({"_id": author_id}, {"$set":{"Level":new_level}}, upsert=True)
await ctx.channel.send(f"{author.name} has leveled up to {new_level}!")
await bot.process_commands(ctx)
client.run("token")
如果我删除 on_message(ctx)
中的所有内容(也是事件),那么它就可以工作了。
我已经尝试了所有方法,但它不起作用。
示例:
await bot.process_commands(message)
这也不起作用,因为我使用的是 ctx
而不是 message
。我觉得……
如果您对此有答案,请帮助我。
答案 0 :(得分:1)
您的 on_message
活动有几个问题:
on_message
带有 message
,而不是 ctx
client
,而不是 bot
process_commands
行缩进太多。它需要在事件定义的最外层缩进层上,否则它最终可能不会被每条消息触发,这会导致机器人忽略部分或全部命令(在您的情况下,机器人识别命令的唯一时间是如果用户在同一条消息中升级)您可以通过如下方式修复您的代码:
@client.event
async def on_message(message):
author_id = message.author.id
guild_id = message.guild.id
author = message.author
user_id = {"_id": author_id}
if message.author.bot:
return
# rest of your code goes here
# notice the indentation layer. This needs to be at the top layer of your function
await client.process_commands(message)
旁注:您不需要单独检查消息作者是否是您的机器人,因为 message.author.bot
检查无论如何都会忽略它
答案 1 :(得分:0)
您的代码显示了一个直接错误。
当我们使用 event
时,使用参数:message
,然后使用 command()
时使用参数:ctx
。
您正在为机器人中的事件使用 ctx
参数。它不会简单地工作。
您需要将其更改为 message
。
还有声明:
await bot.process_command(ctx)
这里的 ctx
也必须改为 message
并且它应该与 else
一起使用,而不是在 if
内使用。
您的机器人不是 bot
变量而是 client
。因此将 bot
中的 on_message
替换为 client
经过上述所有更改后,代码为:
@client.event
async def on_message(message):
author_id = message.author.id
guild_id = message.guild.id
author = message.author
user_id = {"_id": author_id}
if message.author == client.user:
return
if message.author.bot:
return
if(collection.count_documents({}) == 0):
user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
collection.insert_one(user_info)
if(collection.count_documents(user_id) == 0):
user_info = {"_id": author_id, "GuildID": guild_id, "Level": 1, "XP": 0}
collection.insert_one(user_info)
exp = collection.find(user_id)
for xp in exp:
cur_xp = xp["XP"]
new_xp = cur_xp + 1
collection.update_one({"_id": author_id}, {"$set":{"XP":new_xp}}, upsert=True)
await message.channel.send("1 xp up")
lvl = collection.find(user_id)
for levl in lvl:
lvl_start = levl["Level"]
new_level = lvl_start + 1
if cur_xp >= round(5 * (lvl_start ** 4 / 5)):
collection.update_one({"_id": author_id}, {"$set":{"Level":new_level}}, upsert=True)
await message.channel.send(f"{author.name} has leveled up to {new_level}!")
await client.process_commands(message)
希望这会有所帮助。谢谢! :D