mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[V3 Economy] Expand payday output (#1386)
* [V3 Economy] implement suggestions from #1371 * Fix a typo * Add functions for getting leaderboard and leaderboard position * Use the new functions to get leaderboard position and leaderboard (overrides https://github.com/Cog-Creators/Red-DiscordBot/pull/1435) * Actually implement showing only guild members on leaderboard when bank is global * get_leaderboard_position needs to be awaited * For global bank, pass None for guild to get_leaderboard when trying to find position * Remove some unneeded code * Wrong index... * Combine 3 messages into 1 * Fix guild leaderboard while bank is global * add missing parentheses * Modify the leaderboard formatting * More work on leaderboard formatting * no subtraction
This commit is contained in:
parent
a8f4659552
commit
f83e3cc3e7
@ -235,14 +235,17 @@ class Economy:
|
||||
await bank.deposit_credits(author, await self.config.PAYDAY_CREDITS())
|
||||
next_payday = cur_time + await self.config.PAYDAY_TIME()
|
||||
await self.config.user(author).next_payday.set(next_payday)
|
||||
await ctx.send(
|
||||
_("{} Here, take some {}. Enjoy! (+{}"
|
||||
" {}!)").format(
|
||||
author.mention, credits_name,
|
||||
str(await self.config.PAYDAY_CREDITS()),
|
||||
credits_name
|
||||
)
|
||||
)
|
||||
|
||||
pos = await bank.get_leaderboard_position(author)
|
||||
await ctx.send(_(
|
||||
"{0.mention} Here, take some {1}. Enjoy! (+{2}\n\n"
|
||||
"You currently have {3} {1}.\n\n"
|
||||
"You are currently #{4} on the leaderboard!"
|
||||
).format(
|
||||
author, credits_name, str(await self.config.PAYDAY_CREDITS()),
|
||||
str(await bank.get_balance(author)), pos
|
||||
))
|
||||
|
||||
else:
|
||||
dtime = self.display_time(next_payday - cur_time)
|
||||
await ctx.send(
|
||||
@ -255,12 +258,15 @@ class Economy:
|
||||
await bank.deposit_credits(author, await self.config.guild(guild).PAYDAY_CREDITS())
|
||||
next_payday = cur_time + await self.config.guild(guild).PAYDAY_TIME()
|
||||
await self.config.member(author).next_payday.set(next_payday)
|
||||
await ctx.send(
|
||||
_("{} Here, take some {}. Enjoy! (+{}"
|
||||
" {}!)").format(
|
||||
author.mention, credits_name,
|
||||
str(await self.config.guild(guild).PAYDAY_CREDITS()),
|
||||
credits_name))
|
||||
pos = await bank.get_leaderboard_position(author)
|
||||
await ctx.send(_(
|
||||
"{0.mention} Here, take some {1}. Enjoy! (+{2})\n\n"
|
||||
"You currently have {3} {1}.\n\n"
|
||||
"You are currently #{4} on the leaderboard!"
|
||||
).format(
|
||||
author, credits_name, str(await self.config.PAYDAY_CREDITS()),
|
||||
str(await bank.get_balance(author)), pos
|
||||
))
|
||||
else:
|
||||
dtime = self.display_time(next_payday - cur_time)
|
||||
await ctx.send(
|
||||
@ -269,7 +275,7 @@ class Economy:
|
||||
|
||||
@commands.command()
|
||||
@guild_only_check()
|
||||
async def leaderboard(self, ctx: commands.Context, top: int = 10):
|
||||
async def leaderboard(self, ctx: commands.Context, top: int = 10, show_global: bool=False):
|
||||
"""Prints out the leaderboard
|
||||
|
||||
Defaults to top 10"""
|
||||
@ -277,26 +283,23 @@ class Economy:
|
||||
guild = ctx.guild
|
||||
if top < 1:
|
||||
top = 10
|
||||
if await bank.is_global():
|
||||
bank_sorted = sorted(await bank.get_global_accounts(),
|
||||
key=lambda x: x.balance, reverse=True)
|
||||
else:
|
||||
bank_sorted = sorted(await bank.get_guild_accounts(guild),
|
||||
key=lambda x: x.balance, reverse=True)
|
||||
if await bank.is_global() and show_global: # show_global is only applicable if bank is global
|
||||
guild = None
|
||||
bank_sorted = await bank.get_leaderboard(positions=top, guild=guild)
|
||||
if len(bank_sorted) < top:
|
||||
top = len(bank_sorted)
|
||||
topten = bank_sorted[:top]
|
||||
highscore = ""
|
||||
place = 1
|
||||
for acc in topten:
|
||||
dname = str(acc.name)
|
||||
if len(dname) >= 23 - len(str(acc.balance)):
|
||||
dname = dname[:(23 - len(str(acc.balance))) - 3]
|
||||
dname += "... "
|
||||
highscore += str(place).ljust(len(str(top)) + 1)
|
||||
highscore += dname.ljust(23 - len(str(acc.balance)))
|
||||
highscore += str(acc.balance) + "\n"
|
||||
place += 1
|
||||
for pos, acc in enumerate(bank_sorted, 1):
|
||||
pos = pos
|
||||
poswidth = 2
|
||||
name = acc[1]["name"]
|
||||
namewidth = 35
|
||||
balance = acc[1]["balance"]
|
||||
balwidth = 2
|
||||
highscore += "{pos: <{poswidth}} {name: <{namewidth}s} {balance: >{balwidth}}\n".format(
|
||||
pos=pos, poswidth=poswidth, name=name, namewidth=namewidth,
|
||||
balance=balance, balwidth=balwidth
|
||||
)
|
||||
if highscore != "":
|
||||
for page in pagify(highscore, shorten_by=12):
|
||||
await ctx.send(box(page, lang="py"))
|
||||
|
||||
@ -243,7 +243,7 @@ async def deposit_credits(member: discord.Member, amount: int) -> int:
|
||||
|
||||
"""
|
||||
if _invalid_amount(amount):
|
||||
raise ValueError("Invalid withdrawal amount {} <= 0".format(amount))
|
||||
raise ValueError("Invalid deposit amount {} <= 0".format(amount))
|
||||
|
||||
bal = await get_balance(member)
|
||||
return await set_balance(member, amount + bal)
|
||||
@ -287,62 +287,81 @@ async def wipe_bank():
|
||||
await _conf.clear_all_members()
|
||||
|
||||
|
||||
async def get_guild_accounts(guild: discord.Guild) -> List[Account]:
|
||||
"""Get all account data for the given guild.
|
||||
async def get_leaderboard(positions: int=None, guild: discord.Guild=None) -> List[tuple]:
|
||||
"""
|
||||
Gets the bank's leaderboard
|
||||
|
||||
Parameters
|
||||
----------
|
||||
positions : `int`
|
||||
The number of positions to get
|
||||
guild : discord.Guild
|
||||
The guild to get accounts for.
|
||||
The guild to get the leaderboard of. If the bank is global and this
|
||||
is provided, get only guild members on the leaderboard
|
||||
|
||||
Returns
|
||||
-------
|
||||
`list` of `Account`
|
||||
A list of all guild accounts.
|
||||
`list` of `tuple`
|
||||
The sorted leaderboard in the form of :code:`(user_id, raw_account)`
|
||||
|
||||
Raises
|
||||
------
|
||||
RuntimeError
|
||||
If the bank is currently global.
|
||||
TypeError
|
||||
If the bank is guild-specific and no guild was specified
|
||||
|
||||
"""
|
||||
if await is_global():
|
||||
raise RuntimeError("The bank is currently global.")
|
||||
|
||||
ret = []
|
||||
accs = await _conf.all_members(guild)
|
||||
for user_id, acc in accs.items():
|
||||
acc_data = acc.copy() # There ya go kowlin
|
||||
acc_data['created_at'] = _decode_time(acc_data['created_at'])
|
||||
ret.append(Account(**acc_data))
|
||||
return ret
|
||||
raw_accounts = await _conf.all_users()
|
||||
if guild is not None:
|
||||
tmp = raw_accounts.copy()
|
||||
for acc in tmp:
|
||||
if not guild.get_member(acc):
|
||||
del raw_accounts[acc]
|
||||
else:
|
||||
if guild is None:
|
||||
raise TypeError("Expected a guild, got NoneType object instead!")
|
||||
raw_accounts = await _conf.all_members(guild)
|
||||
sorted_acc = sorted(raw_accounts.items(), key=lambda x: x[1]['balance'], reverse=True)
|
||||
if positions is None:
|
||||
return sorted_acc
|
||||
else:
|
||||
return sorted_acc[:positions]
|
||||
|
||||
|
||||
async def get_global_accounts() -> List[Account]:
|
||||
"""Get all global account data.
|
||||
async def get_leaderboard_position(member: Union[discord.User, discord.Member]) -> Union[int, None]:
|
||||
"""
|
||||
Get the leaderboard position for the specified user
|
||||
|
||||
Parameters
|
||||
----------
|
||||
member : `discord.User` or `discord.Member`
|
||||
The user to get the leaderboard position of
|
||||
|
||||
Returns
|
||||
-------
|
||||
`list` of `Account`
|
||||
A list of all global accounts.
|
||||
`int`
|
||||
The position of the user on the leaderboard
|
||||
|
||||
Raises
|
||||
------
|
||||
RuntimeError
|
||||
If the bank is currently guild specific.
|
||||
TypeError
|
||||
If the bank is currently guild-specific and a `discord.User` object was passed in
|
||||
|
||||
"""
|
||||
if not await is_global():
|
||||
raise RuntimeError("The bank is not currently global.")
|
||||
|
||||
ret = []
|
||||
accs = await _conf.all_users() # this is a dict of user -> acc
|
||||
for user_id, acc in accs.items():
|
||||
acc_data = acc.copy()
|
||||
acc_data['created_at'] = _decode_time(acc_data['created_at'])
|
||||
ret.append(Account(**acc_data))
|
||||
|
||||
return ret
|
||||
if await is_global():
|
||||
guild = None
|
||||
else:
|
||||
guild = member.guild if hasattr(member, "guild") else None
|
||||
try:
|
||||
leaderboard = await get_leaderboard(None, guild)
|
||||
except TypeError:
|
||||
raise
|
||||
else:
|
||||
pos = discord.utils.find(lambda x: x[1][0] == member.id, enumerate(leaderboard, 1))
|
||||
if pos is None:
|
||||
return None
|
||||
else:
|
||||
return pos[0]
|
||||
|
||||
|
||||
async def get_account(member: Union[discord.Member, discord.User]) -> Account:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user