所以我试图在某人执行“/logstart”和“/logstop”时为他们创建一个秒表,但我希望多个人能够在不受干扰的情况下启动和停止自己的秒表。
@bot.command(name='logstart')
async def logstart(ctx, arg1):
await ctx.message.delete()
await ctx.send('Log has Started')
@bot.command(name='logstop')
async def logstop(ctx):
await ctx.message.delete()
await ctx.send('FLIGHT LOG\nDuration: stopwatch time\nFlight Plan: argument1')
User does "/logstart EGCC(DEP) EGLL(ARR)":
Bot: Log Started
User does "/logstop"
Bot: **FLIGHT LOG**
Duration: %stopwatch time%
Flight Plan: EGCC(DEP) EGLL(ARR)
我尝试在文档中搜索如何创建局部变量,但没有找到太多
我假设问题是您希望这些数据在多次重新启动后保持不变(因为您可以使用常规的旧字典来存储
ctx
的 ID 及其各自的开始时间!)。
假设您能够读取/写入托管机器人的任何位置,我将使用
sqlite3
作为伪字典。创建一个表,其中包含用户 ID、开始时间和 arg1
的列。如果大小/内存使用是数据库或字典的问题,您可以在 logstart()
或 logstop()
方法内进行清理。也许有最大数量的并发计时器(阻止新计时器启动)或剔除很久以前不合理启动的任何未完成的计时器。
所以基本上是这样的:
import sqlite3
# blah blah blah
MAX_TIMER = 259200 # 3 day limit
DATABASE_PATH = 'whatever.db'
conn = sqlite3.connect(DATABASE_PATH)
cur = conn.cursor() # a cursor to simplify fetching/executing
# create table, ignoring error if it already exists
try: # (remove "PRIMARY KEY NOT NULL" if you want multiple timers per user)
conn.execute('CREATE TABLE timers (user_id TEXT PRIMARY KEY NOT NULL, time_started TEXT, arg1 TEXT);')
except sqlite3.OperationalError:
pass
@bot.command(name='logstart')
async def logstart(ctx, arg1):
id = ctx.message.author.id
await ctx.message.delete()
# if you only allow one timer per user ("PRIMARY KEY NOT NULL"), you can do the following:
try:
cur.execute('INSERT INTO timers (user_id, time_started, arg1) VALUES(?,?,?)',
(id, time.time(), arg1))
await ctx.send('Log has Started')
except sqlite3.IntegrityError:
await ctx.send('You already have a timer started')
# maybe handle cleanup here? in this example, i delete all rows older than 3 days
cur.execute('SELECT user_id, time_started FROM timers')
for id, time_started in cur.fetchall():
if time.time() - float(time_started) > MAX_TIMER:
# maybe send a message/whisper to the affected user?
cur.execute('DELETE FROM timers WHERE user_id=?', (id,))
@bot.command(name='logstop')
async def logstop(ctx):
id = ctx.message.author.id
await ctx.message.delete()
# ---
# if you only allow one timer per user:
cur.execute('SELECT time_started, arg1 FROM timers WHERE user_id=?', (id,))
data = cur.fetchone()
if data: # `fetchone()` returns None if no such row exists
time_started, arg1 = data # `time_started` is text, so make sure to cast it to a float
duration = time.time() - float(time_started)
await ctx.send(f'FLIGHT LOG\nDuration: {duration}\nFlight Plan: {arg1}')
cur.execute('DELETE FROM timers WHERE user_id=?', (id,))
else: # ^ delete row once we're done with it
await ctx.send('You haven\'t started a timer')
# ---
# if you allow multiple timers per user (they'd need to pass `arg1` again):
cur.execute('SELECT time_started FROM timers WHERE user_id=? AND arg1=?', (id, arg1))
time_started = cur.fetchone()
if time_started:
duration = time.time() - float(time_started)
await ctx.send(f'FLIGHT LOG\nDuration: {duration}\nFlight Plan: {arg1}')
cur.execute('DELETE FROM timers WHERE user_id=? AND arg1=?', (id, arg1))
else:
await ctx.send('You haven\'t started a timer')
一些注意事项:
len(cur.execute('SELECT * FROM timers WHERE user_id=?', (id,)).fetchall())
而不是 fetchone()