162 lines
7.3 KiB
Python
162 lines
7.3 KiB
Python
import calendar
|
|
import json
|
|
import logging
|
|
from datetime import datetime, timedelta, timezone
|
|
from typing import NamedTuple, Union
|
|
|
|
import discord
|
|
from redbot.core import bank, commands, errors
|
|
from redbot.core.i18n import Translator
|
|
from redbot.core.utils.chat_formatting import humanize_number
|
|
|
|
from ..abc import MixinMeta
|
|
|
|
log = logging.getLogger("red.vrt.bankevents")
|
|
_ = Translator("BankEvents", __file__)
|
|
|
|
|
|
class PaydayClaimInformation(NamedTuple):
|
|
member: discord.Member
|
|
channel: Union[discord.TextChannel, discord.Thread, discord.ForumChannel]
|
|
message: discord.Message
|
|
amount: int
|
|
old_balance: int
|
|
new_balance: int
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"member": self.member.id,
|
|
"channel": self.channel.id,
|
|
"message": self.message.id,
|
|
"amount": self.amount,
|
|
"old_balance": self.old_balance,
|
|
"new_balance": self.new_balance,
|
|
}
|
|
|
|
def to_json(self) -> str:
|
|
return json.dumps(self.to_dict())
|
|
|
|
|
|
class PaydayOverride(MixinMeta):
|
|
@commands.command(hidden=True)
|
|
@commands.guild_only()
|
|
async def payday_override(self, ctx: commands.Context):
|
|
cog = self.bot.get_cog("Economy")
|
|
if cog is None:
|
|
raise commands.ExtensionError("Economy cog is not loaded.")
|
|
|
|
author = ctx.author
|
|
guild = ctx.guild
|
|
|
|
cur_time = calendar.timegm(ctx.message.created_at.utctimetuple())
|
|
credits_name = await bank.get_currency_name(guild)
|
|
old_balance = await bank.get_balance(author)
|
|
if await bank.is_global():
|
|
next_payday = await cog.config.user(author).next_payday() + await cog.config.PAYDAY_TIME()
|
|
if cur_time >= next_payday:
|
|
credit_amount = await cog.config.PAYDAY_CREDITS()
|
|
try:
|
|
new_balance = await bank.deposit_credits(author, credit_amount)
|
|
except errors.BalanceTooHigh as exc:
|
|
new_balance = await bank.set_balance(author, exc.max_balance)
|
|
await ctx.send(
|
|
_(
|
|
"You've reached the maximum amount of {currency}! "
|
|
"Please spend some more \N{GRIMACING FACE}\n\n"
|
|
"You currently have {new_balance} {currency}."
|
|
).format(currency=credits_name, new_balance=humanize_number(exc.max_balance))
|
|
)
|
|
payload = PaydayClaimInformation(
|
|
author, ctx.channel, ctx.message, exc.max_balance - credit_amount, old_balance, new_balance
|
|
)
|
|
self.bot.dispatch("red_economy_payday_claim", payload)
|
|
return
|
|
|
|
await cog.config.user(author).next_payday.set(cur_time)
|
|
|
|
pos = await bank.get_leaderboard_position(author)
|
|
await ctx.send(
|
|
_(
|
|
"{author.mention} Here, take some {currency}. "
|
|
"Enjoy! (+{amount} {currency}!)\n\n"
|
|
"You currently have {new_balance} {currency}.\n\n"
|
|
"You are currently #{pos} on the global leaderboard!"
|
|
).format(
|
|
author=author,
|
|
currency=credits_name,
|
|
amount=humanize_number(credit_amount),
|
|
new_balance=humanize_number(await bank.get_balance(author)),
|
|
pos=humanize_number(pos) if pos else pos,
|
|
)
|
|
)
|
|
payload = PaydayClaimInformation(
|
|
author, ctx.channel, ctx.message, credit_amount, new_balance, old_balance
|
|
)
|
|
self.bot.dispatch("red_economy_payday_claim", payload)
|
|
else:
|
|
relative_time = discord.utils.format_dt(
|
|
datetime.now(timezone.utc) + timedelta(seconds=next_payday - cur_time), "R"
|
|
)
|
|
await ctx.send(
|
|
_("{author.mention} Too soon. Your next payday is {relative_time}.").format(
|
|
author=author, relative_time=relative_time
|
|
)
|
|
)
|
|
else:
|
|
# Gets the users latest successfully payday and adds the guilds payday time
|
|
next_payday = await cog.config.member(author).next_payday() + await cog.config.guild(guild).PAYDAY_TIME()
|
|
if cur_time >= next_payday:
|
|
credit_amount = await cog.config.guild(guild).PAYDAY_CREDITS()
|
|
for role in author.roles:
|
|
role_credits = await cog.config.role(role).PAYDAY_CREDITS() # Nice variable name
|
|
if role_credits > credit_amount:
|
|
credit_amount = role_credits
|
|
try:
|
|
new_balance = await bank.deposit_credits(author, credit_amount)
|
|
except errors.BalanceTooHigh as exc:
|
|
new_balance = await bank.set_balance(author, exc.max_balance)
|
|
await ctx.send(
|
|
_(
|
|
"You've reached the maximum amount of {currency}! "
|
|
"Please spend some more \N{GRIMACING FACE}\n\n"
|
|
"You currently have {new_balance} {currency}."
|
|
).format(currency=credits_name, new_balance=humanize_number(exc.max_balance))
|
|
)
|
|
payload = PaydayClaimInformation(
|
|
author, ctx.channel, ctx.message, exc.max_balance - credit_amount, new_balance, old_balance
|
|
)
|
|
self.bot.dispatch("red_economy_payday_claim", payload)
|
|
return
|
|
|
|
# Sets the latest payday time to the current time
|
|
next_payday = cur_time
|
|
|
|
await cog.config.member(author).next_payday.set(next_payday)
|
|
pos = await bank.get_leaderboard_position(author)
|
|
await ctx.send(
|
|
_(
|
|
"{author.mention} Here, take some {currency}. "
|
|
"Enjoy! (+{amount} {currency}!)\n\n"
|
|
"You currently have {new_balance} {currency}.\n\n"
|
|
"You are currently #{pos} on the global leaderboard!"
|
|
).format(
|
|
author=author,
|
|
currency=credits_name,
|
|
amount=humanize_number(credit_amount),
|
|
new_balance=humanize_number(await bank.get_balance(author)),
|
|
pos=humanize_number(pos) if pos else pos,
|
|
)
|
|
)
|
|
payload = PaydayClaimInformation(
|
|
author, ctx.channel, ctx.message, credit_amount, new_balance, old_balance
|
|
)
|
|
self.bot.dispatch("red_economy_payday_claim", payload)
|
|
else:
|
|
relative_time = discord.utils.format_dt(
|
|
datetime.now(timezone.utc) + timedelta(seconds=next_payday - cur_time), "R"
|
|
)
|
|
await ctx.send(
|
|
_("{author.mention} Too soon. Your next payday is {relative_time}.").format(
|
|
author=author, relative_time=relative_time
|
|
)
|
|
)
|