我正在使用 Python 和 Discord.py 库为我的 Discord 机器人创建每日 streak 命令。我使用的代码基于我在网上找到的示例,但我遇到了问题。
(代码取自 - Economy Bot Daily Streak)
import datetime
from datetime import datetime, timedelta
@client.command()
async def daily(ctx):
with open ("streak.json","r") as f:
data = json.load(f)
streak=data[f"{ctx.author.id}"]["streak"]
last_claim_stamp=data[f"{ctx.author.id}"]["last_claim"]
last_claim=datetime.fromtimestamp(float(last_claim_stamp))
now =datetime.now()
delta = now-last_claim
print(f"{streak}\n{last_claim_stamp}\n{last_claim}\n{now}\n{delta}")
if delta< timedelta(hours=24):
await ctx.send('YOU ALREADY CLAIMED YOUR DAILY in 24 hours')
return
if delta > timedelta(hours=48):
print('streak reset')
streak = 1
else:
streak+=1
daily = 45+(streak*5)
data[f'{ctx.author.id}']["streak"]=streak
data[f'{ctx.author.id}']["last_claim"]= str(now.timestamp())
with open("streak.json","w") as f:
json.dump(data,f,indent=2)
embed = discord.Embed(title="Daily", colour=random.randint(0, 0xffffff), description=f"You've claimed your daily of **{daily}** \n Not credited")
embed.set_footer(text=f"Your daily streak : {streak}")
await ctx.send(embed=embed)
我的问题是:当用户第一次使用 daily streak 命令时,如何自动将用户添加到 JSON 文件中?我尝试创建一个函数来处理这个问题,但遇到了一个错误,它在执行命令之前添加了时间戳,导致机器人即使在第一次尝试时也会说“您已经声明了您的日常”。
import json
import datetime
from datetime import datetime, timedelta
def initialize_json(filename):
"""
Initializes the JSON file, creating it and adding default values for new users if it doesn't exist.
Args:
filename (str): The name of the JSON file.
Returns:
dict: The data dictionary loaded from the JSON file, or an empty dictionary if the file is new.
"""
try:
with open(filename, 'r') as f:
data = json.load(f)
except FileNotFoundError: # File doesn't exist
with open(filename, 'w') as f:
data = {} # Create an empty dictionary (JSON object)
return data
def add_user_to_json(filename, user_id, streak=0, last_claim=None):
"""
Adds a new user to the JSON file if they don't already exist, with the specified default values.
Args:
filename (str): The name of the JSON file.
user_id (int/str): The user's unique identifier.
streak (int, optional): The user's initial streak (default: 0).
last_claim (datetime.datetime, optional): The user's last claim timestamp (default: None).
"""
data = initialize_json(filename)
if user_id not in data:
data[user_id] = {'streak': streak, 'last_claim': last_claim} # Add new user info
with open(filename, 'w') as f:
json.dump(data, f, indent=2)
@client.command()
async def daily(ctx):
"""
The daily command for the Discord bot, handling user streaks.
Args:
ctx (discord.ext.commands.Context): The context object containing command information.
"""
user_id = str(ctx.author.id)
with open("streak.json", "r") as f:
data = json.load(f)
# Check if user exists in data, add them if not
if user_id not in data:
add_user_to_json("streak.json", user_id)
data = initialize_json("streak.json") # Re-read data after adding
streak = data[user_id]["streak"]
last_claim_stamp = data[user_id]["last_claim"]
if last_claim_stamp is not None:
last_claim = datetime.fromtimestamp(float(last_claim_stamp))
else:
# Handle initial claim when there's no last_claim timestamp
last_claim = datetime.now() - timedelta(days=1) # Adjust for daily reset
now = datetime.now()
delta = now - last_claim
# Check if 24 hours have passed since the last claim
if delta < timedelta(hours=24):
await ctx.send('YOU ALREADY CLAIMED YOUR DAILY in 24 hours')
return
# Reset streak if more than 48 hours have passed since the last claim
if delta > timedelta(hours=48):
data[user_id]["streak"] = 1
streak = 1
else:
data[user_id]["streak"] += 1
streak += 1
# Calculate daily reward based on streak
daily = 45 + (streak * 5)
# Update user data in the JSON file
data[user_id]["last_claim"] = str(now.timestamp())
with open("streak.json", "w") as f:
json.dump(data, f, indent=2)
# Create and send the embed message
embed = discord.Embed(title="Daily", colour=random.randint(0, 0xffffff),
description=f"You've claimed your daily of **{daily}** \n Not credited")
embed.set_footer(text=f"Your daily streak : {streak}")
await ctx.send(embed=embed)
数据存储:
streak.json
的 JSON 格式的文件来存储用户信息。initialize_json
:检查文件是否存在。如果没有,它会创建一个新的。add_user_to_json
:将新用户添加到文件中,并使用其连续记录和最后声明时间戳的默认值(可选)。日常命令(
daily
):
streak.json
文件中检索用户数据。add_user_to_json
添加默认值。每日奖励资格:
奖励计算及数据更新:
streak.json
文件。回复消息并嵌入:
embed
对象来使用 discord.Embed
显示每日奖励信息。