add user concurrency locks
from discord.ext import commands, tasks
+from collections import defaultdict
import functools
import discord
import asyncio
@@ -36,11 +37,19 @@ class Econ(commands.Cog):
):
command._max_concurrency = self.max_concurrency_dummy._max_concurrency
+ self._user_locks = defaultdict(asyncio.Lock)
+
def cog_unload(self):
self.d.honey_buckets = self.honey._buckets
self.pillage_cap_reset.cancel()
+ async def lock_author(self, ctx):
+ await self._user_locks[ctx.author.id].acquire()
+
+ async def unlock_author(self, ctx):
+ self._user_locks[ctx.author.id].release()
+
@tasks.loop(hours=12)
async def pillage_cap_reset(self):
self.d.pillagers = {}
@@ -778,6 +787,8 @@ class Econ(commands.Cog):
)
@commands.command(name="give", aliases=["gift", "share", "gib"])
+ @commands.before_invoke(lock_author)
+ @commands.after_invoke(unlock_author)
@commands.guild_only()
@commands.cooldown(1, 10, commands.BucketType.user)
@commands.max_concurrency(1, commands.BucketType.user)
@@ -795,6 +806,7 @@ class Econ(commands.Cog):
await self.bot.send(ctx, ctx.l.econ.give.stupid_1)
return
+ async with self._user_locks[user.id]:
amount_item = amount_item.lower()
try:
# to be given is emeralds
@@ -854,7 +866,7 @@ class Econ(commands.Cog):
await self.db.remove_item(ctx.author.id, item, amount)
await self.db.add_item(user.id, db_item["name"], db_item["sell_price"], amount)
- await self.db.log_transaction(db_item["name"], amount, arrow.utcnow().timestamp(), ctx.author.id, user.id)
+ self.bot.loop.create_task(self.db.log_transaction(db_item["name"], amount, arrow.utcnow().timestamp(), ctx.author.id, user.id))
await self.bot.send(ctx, ctx.l.econ.give.gave.format(ctx.author.mention, amount, db_item["name"], user.mention))
@@ -1103,6 +1115,8 @@ class Econ(commands.Cog):
await self.db.update_user(ctx.author.id, "vault_max", db_user["vault_max"] + 1)
@commands.command(name="pillage", aliases=["rob", "mug"])
+ @commands.before_invoke(lock_author)
+ @commands.after_invoke(unlock_author)
@commands.guild_only()
@commands.cooldown(1, 300, commands.BucketType.user)
@commands.max_concurrency(1, commands.BucketType.user)
@@ -1122,6 +1136,7 @@ class Econ(commands.Cog):
await self.bot.send(ctx, ctx.l.econ.pillage.stupid_2)
return
+ async with self._user_locks[victim.id]:
db_user = await self.db.fetch_user(ctx.author.id)
if db_user["emeralds"] < 64:
