Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
131 views
in Technique[技术] by (71.8m points)

windows - Discord Python Time Bot Bug

I recently programmed a python bot to track the time a user spends in a voice channel on a discord. The bot seems to be working at first glance but over time the tracked times get more and more inaccurate. For example one time a friend of mine had 25 hours tracked, when the bot had only been running for about 20 hours. Any help is appreciated.


import asyncio
import discord
import datetime
from discord.utils import get
from discord.ext import commands
from secrets import *


leaderboard = dict()
userjoindict = dict()
userjoineddict = dict()
userdurationdict = dict()
intents = discord.Intents.all()

client = commands.Bot(command_prefix='/', intents=intents)


@client.event
async def on_ready():
    print('ready')


@client.event
async def on_voice_state_update(member, before, after):
    for guild in client.guilds:
        if guild.name == GUILD:
            break

    channelid = [channel.id for channel in guild.channels]

    if before.channel and after.channel:
        if (before.channel.id not in channelid or before.channel.id == guild.afk_channel.id) and (
                after.channel.id in channelid and after.channel.id != guild.afk_channel.id):
            await start_tracking(member)
        if before.channel.id in channelid and (after.channel.id not in channelid or after.channel.id == guild.afk_channel.id):
            await stop_tracking(member)

    if not before.channel and (after.channel and after.channel.id != guild.afk_channel.id):
        await start_tracking(member)

    if before.channel and not after.channel:
        if before.channel.id != guild.afk_channel.id:
            await stop_tracking(member)


@client.event
async def start_tracking(member: discord.Member):
    print('startedtracking')
    userjoineddict.update({member: '1'})
    userjoindict.update({member: datetime.datetime.now().time()})
    print(type(userjoindict.get(member)))

@client.command()
async def time(cxt, *, member: discord.Member = None):
    if member is None:
        author = cxt.message.author
    else:
        author = member

    if userdurationdict.get(author) is None and userjoineddict.get(author) is None:
        time = 0
        await cxt.send('no time amk')

    elif userdurationdict.get(author) is not None and userjoineddict.get(author) == '0':
        time = userdurationdict.get(author)
        await cxt.send('{} has spent {} in a channel on this discord'.format(author.name, str(time)))

    elif userdurationdict.get(author) is not None and userjoineddict.get(author) == '1':
        t1 = datetime.datetime.now().time() - userjoindict.get(author)
        time = userdurationdict.get(author) + t1
        await cxt.send('{} has {} in a channel on this discord'.format(author.name, str(time)))

    elif userdurationdict.get(author) is None and userjoineddict.get(author) == '1':
        time = datetime.datetime.now().time() - userjoindict.get(author)
        await cxt.send('{} has spent {} in a channel on this discord'.format(author.name, str(time)))


@client.command()
async def place(cxt, *, place: discord.Member = None):
    for guild in client.guilds:
        if guild == GUILD:
            break
    for member in guild.members:
        if userdurationdict.get(member) is None and userjoineddict.get(member) is None:
            leaderboard.update({member.name: 0})
        elif userdurationdict.get(member) is not None and userjoineddict.get(member) == '0':
            time = userdurationdict.get(member)
            leaderboard.update({member.name: time.total_seconds()})
        elif userdurationdict.get(member) is not None and userjoineddict.get(member) == '1':
            t1 = datetime.datetime.now().time() - userjoindict.get(member)
            time = userdurationdict.get(member) + t1
            leaderboard.update({member.name: time.total_seconds()})
        elif userdurationdict.get(member) is None and userjoineddict.get(member) == '1':
            time = datetime.datetime.now().time() - userjoindict.get(member)
            leaderboard.update({member.name: time.total_seconds()})
    sorted_lb = sorted(leaderboard.items(), key=lambda x: x[1], reverse=True)
    if place is None:
        search = cxt.message.author.name
    else:
        search = str(place.name)
    i = 0
    for x in sorted_lb:
        i += 1
        if x[0] == search:
            t = int(x[1])
            time = str(datetime.timedelta(seconds=t))
            await cxt.send('Your searched member is place {} with a time of {}'.format(i, time))
            break
    sorted_lb.clear()
    leaderboard.clear()


@client.command()
async def top(cxt, *, num: int = None):
    if num is None:
        await cxt.send('Please enter a number. For example "top 10" to se the top 10')
        return
    for guild in client.guilds:
        if guild == GUILD:
            break
    for member in guild.members:
        if userdurationdict.get(member) is None and userjoineddict.get(member) is None:
            leaderboard.update({member.name: 0})
        elif userdurationdict.get(member) is not None and userjoineddict.get(member) == '0':
            time = userdurationdict.get(member)
            leaderboard.update({member.name: time.total_seconds()})
        elif userdurationdict.get(member) is not None and userjoineddict.get(member) == '1':
            t1 = datetime.datetime.now().time() - userjoindict.get(member)
            time = userdurationdict.get(member) + t1
            leaderboard.update({member.name: time.total_seconds()})
        elif userdurationdict.get(member) is None and userjoineddict.get(member) == '1':
            time = datetime.datetime.now().time() - userjoindict.get(member)
            leaderboard.update({member.name: time.total_seconds()})
    sorted_lb = sorted(leaderboard.items(), key=lambda x: x[1], reverse=True)
    i = 0
    for x in sorted_lb:
        i += 1
        time = datetime.timedelta(seconds=int(x[1]))
        await cxt.send('{}. {} with a time of {}'.format(i, x[0], time))
        if i == num:
            return





@client.event
async def checking():
    while True:
        if datetime.datetime.now().minute == 30:
            with open('save.txt', 'w') as f:
                f.write(str(userdurationdict))
                f.close()
        await asyncio.sleep(2)


@client.event
async def stop_tracking(member: discord.Member):
    userjoineddict.update({member: '0'})
    if datetime.datetime.now().time() < userjoindict.get(member):
        pass
    duration = datetime.datetime.now().time() - userjoindict.get(member)
    if member in userdurationdict:
        newduration = userdurationdict.get(member) + duration
        userdurationdict.update({member: newduration})
    elif member not in userdurationdict:
        userdurationdict.update({member: duration})
    print('stoppedtracking')
    print(userdurationdict.get(member))


client.run(TOKEN)
client.loop.create_task(checking())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...