Discord Bot 多次运行

Posted

技术标签:

【中文标题】Discord Bot 多次运行【英文标题】:Discord Bot running multiple times 【发布时间】:2021-07-13 03:10:20 【问题描述】:

所以我正在构建这个不和谐机器人,它从 Minecraft 服务器读取 latest.log 文件并在特定频道中发送用户、进度和死亡消息。现在的问题是,过了一会儿,机器人开始发送多条消息,我真的不知道为什么。我尝试添加已经发送到文件中的行并交叉检查新行以查看它们是否重复。这大约是我的朋友(在他的计算机上运行我的机器人)向我发送他的 python.exe 窗口的屏幕截图的时候,该窗口多次显示“机器人在线”消息。我最好的猜测是多个机器人实例同时运行,但我无法弄清楚它是如何做到的。有人可以帮我吗?。这是我的代码:

from discord.ext import commands

client = commands.Bot(command_prefix='.')
deth_msgs = ['was shot', 'was pummeled by', 'was pricked to death',
             'walked into a cactus whilst trying to escape', 'drowned', 'experienced kinetic energy whilst trying to escape', 'blew up', 'was blown up by',
             'was killed by', 'hit the ground too hard', 'hit the ground too hard whilst trying to escape',
             'fell from a high place', 'fell off', 'was impaled', 'was squashed by', 'was skewered by', 'went up in flames', 'walked into fire whilst fighting',
             'burned to death',
             'was burnt to a crisp whilst fighting', 'went off with a bang', 'tried to swim in lava', 'was struck by lightning', 'discovered the floor was lava',
             'walked into danger zone due to', 'was killed', 'froze to death', 'was frozen to death by', 'was slain by', 'was fireballed by', 'was stung to death',
             'was shot by a skull from', 'starved to death', 'suffocated in a wall', 'was squished too much', 'was poked to death', 'was impaled by',
             'fell out of the world', "didn't want to live in the same world as"]

players = []

with open('usercache.json') as u_file:
    details = json.load(u_file)
    for dict in details:
        players.append(dict['name'])

try:
    f = open("dupli_lines.txt")
except FileNotFoundError:
    f = open('dupli_lines.txt', 'w+')
finally:
    f_stats = os.stat('dupli_lines.txt')
    f.close()
    if f_stats.st_size > 1000000:
        os.remove('dupli_lines.txt')
        f = open('dupli_lines.txt', 'w+')
    f.close()

#------------------------------------------------ Events -----------------------------------------------------------------------


@client.event
async def on_ready():
    print('Bot is Online')
    channel = client.get_channel(id)
    pos = 0
    while True:

        with open('dupli_lines.txt','r') as f:
            logs = f.read()
        
        with open(absolutepath) as file:
            file.seek(pos)
            line = file.readline()
            if line not in logs:
                # if 'joined the game\n' in line:
                #     string = line[33:]
                #     player = string.replace(' joined the game\n', '')
                #     if check_dup(player) == False:
                #         players.append(player) 

                if '!coords' in line:
                    if line not in logs:
                        with open('dupli_lines.txt', 'a+') as f:
                            if line not in logs:
                                f.write(line)
                        string = line[33:].replace('!coords', '')
                        words = string.split()
                        for player in players:
                            for word in words:
                                if player in word:
                                    embed = discord.Embed(
                                        title=player,
                                        colour=discord.Colour.from_rgb(57, 255, 20)
                                    )
                                    words.pop(0)
                                    tup_words = tuple(words[1:])
                                    msg = ' '.join(tup_words)
                                    embed.add_field(
                                        name=words[0], value=msg, inline = False)
                                    embed.set_thumbnail(
                                        url='http://static.wikia.nocookie.net/minecraft_gamepedia/images/2/2c/Compass_JE3.gif/revision/latest/scale-to-width-down/150?cb=20201125191224')
                                    
                                    await channel.send(embed=embed)
                                break
                    time.sleep(1)
                    break

                if line[33:].startswith('<'):
                    await channel.send(line[33:])
                    with open('dupli_lines.txt', 'a+') as f:
                        f.write(line)
                    time.sleep(1)

                if 'made the advancement' in line:
                    embed = discord.Embed(
                        title = line[33:],
                        colour=discord.Colour.from_rgb(255,215,0)
                        )
                    embed.set_thumbnail(
                        url='https://www.pikpng.com/pngl/b/456-4569150_michael-rosen-noice-png-brian-rosen-clipart.png')
                    await channel.send(embed=embed)
                    with open('dupli_lines.txt', 'a+') as f:
                        f.write(line)
                    time.sleep(1)
            
                else:
                    for msg in deth_msgs:
                        if msg in line:
                            await channel.send(line[33:])
                            with open('dupli_lines.txt', 'a+') as f:
                                f.write(line)
                            break
                    time.sleep(1)
                    
            pos = file.tell()

client.run('TOKEN')

这就是 python 窗口中显示的内容: Bot is Online x 6

PS:我知道我所有的代码都写在 on_ready() 函数中,但我打算使用这个机器人只是出于这个特定的原因,即阅读游戏中的消息并将它们呈现在 discord 频道中。

【问题讨论】:

我认为您不希望您的 Discord API 密钥出现在问题中。您可能想要禁用那个并生成一个新的。在你的代码中——如果命令是!coords,你打破了内部循环并且不更新文件pos。也没有说on_ready 只会被调用一次;如果客户端必须重新连接到 Discord,它将再次被调用:discordpy.readthedocs.io/en/stable/api.html#discord.on_ready 这个函数不能保证是第一个被调用的事件。同样,这个函数也不能保证只被调用一次。该库实现了重新连接逻辑,因此每当 RESUME 请求失败时都会调用此事件。 如果你已经运行了这个函数,添加一个检查,然后返回。您可能希望重组代码以仅在 on_ready 内部进行检查,然后在外部调用一个单独的函数以清楚起见。 on_ready在bot重新建立连接时调用,可以多次调用。我建议您为此使用tasks。 您的带有文件绑定 IO 的 while True 循环被阻塞。你试过tasks(如上所述)吗? 【参考方案1】:

如果有多个实例正在运行,您可以随时更改机器人令牌以撤销任何正在运行的实例的访问权限。

你可以通过https://discord.com/developers/applications来做到这一点

【讨论】:

以上是关于Discord Bot 多次运行的主要内容,如果未能解决你的问题,请参考以下文章

Discord bot 运行命令两次 discord.py

我如何获得由 discord bot maker 创建的 Discord Bot 在 Heroku 上工作

Discord 机器人命令执行多次

Heroku Discord Bot“没有运行 Web 进程”

Bot 上线,但嵌入不会发布到 discord

Discord bot 不会运行启动序列