mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -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())
|
await bank.deposit_credits(author, await self.config.PAYDAY_CREDITS())
|
||||||
next_payday = cur_time + await self.config.PAYDAY_TIME()
|
next_payday = cur_time + await self.config.PAYDAY_TIME()
|
||||||
await self.config.user(author).next_payday.set(next_payday)
|
await self.config.user(author).next_payday.set(next_payday)
|
||||||
await ctx.send(
|
|
||||||
_("{} Here, take some {}. Enjoy! (+{}"
|
pos = await bank.get_leaderboard_position(author)
|
||||||
" {}!)").format(
|
await ctx.send(_(
|
||||||
author.mention, credits_name,
|
"{0.mention} Here, take some {1}. Enjoy! (+{2}\n\n"
|
||||||
str(await self.config.PAYDAY_CREDITS()),
|
"You currently have {3} {1}.\n\n"
|
||||||
credits_name
|
"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:
|
else:
|
||||||
dtime = self.display_time(next_payday - cur_time)
|
dtime = self.display_time(next_payday - cur_time)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
@ -255,12 +258,15 @@ class Economy:
|
|||||||
await bank.deposit_credits(author, await self.config.guild(guild).PAYDAY_CREDITS())
|
await bank.deposit_credits(author, await self.config.guild(guild).PAYDAY_CREDITS())
|
||||||
next_payday = cur_time + await self.config.guild(guild).PAYDAY_TIME()
|
next_payday = cur_time + await self.config.guild(guild).PAYDAY_TIME()
|
||||||
await self.config.member(author).next_payday.set(next_payday)
|
await self.config.member(author).next_payday.set(next_payday)
|
||||||
await ctx.send(
|
pos = await bank.get_leaderboard_position(author)
|
||||||
_("{} Here, take some {}. Enjoy! (+{}"
|
await ctx.send(_(
|
||||||
" {}!)").format(
|
"{0.mention} Here, take some {1}. Enjoy! (+{2})\n\n"
|
||||||
author.mention, credits_name,
|
"You currently have {3} {1}.\n\n"
|
||||||
str(await self.config.guild(guild).PAYDAY_CREDITS()),
|
"You are currently #{4} on the leaderboard!"
|
||||||
credits_name))
|
).format(
|
||||||
|
author, credits_name, str(await self.config.PAYDAY_CREDITS()),
|
||||||
|
str(await bank.get_balance(author)), pos
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
dtime = self.display_time(next_payday - cur_time)
|
dtime = self.display_time(next_payday - cur_time)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
@ -269,7 +275,7 @@ class Economy:
|
|||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@guild_only_check()
|
@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
|
"""Prints out the leaderboard
|
||||||
|
|
||||||
Defaults to top 10"""
|
Defaults to top 10"""
|
||||||
@ -277,26 +283,23 @@ class Economy:
|
|||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if top < 1:
|
if top < 1:
|
||||||
top = 10
|
top = 10
|
||||||
if await bank.is_global():
|
if await bank.is_global() and show_global: # show_global is only applicable if bank is global
|
||||||
bank_sorted = sorted(await bank.get_global_accounts(),
|
guild = None
|
||||||
key=lambda x: x.balance, reverse=True)
|
bank_sorted = await bank.get_leaderboard(positions=top, guild=guild)
|
||||||
else:
|
|
||||||
bank_sorted = sorted(await bank.get_guild_accounts(guild),
|
|
||||||
key=lambda x: x.balance, reverse=True)
|
|
||||||
if len(bank_sorted) < top:
|
if len(bank_sorted) < top:
|
||||||
top = len(bank_sorted)
|
top = len(bank_sorted)
|
||||||
topten = bank_sorted[:top]
|
|
||||||
highscore = ""
|
highscore = ""
|
||||||
place = 1
|
for pos, acc in enumerate(bank_sorted, 1):
|
||||||
for acc in topten:
|
pos = pos
|
||||||
dname = str(acc.name)
|
poswidth = 2
|
||||||
if len(dname) >= 23 - len(str(acc.balance)):
|
name = acc[1]["name"]
|
||||||
dname = dname[:(23 - len(str(acc.balance))) - 3]
|
namewidth = 35
|
||||||
dname += "... "
|
balance = acc[1]["balance"]
|
||||||
highscore += str(place).ljust(len(str(top)) + 1)
|
balwidth = 2
|
||||||
highscore += dname.ljust(23 - len(str(acc.balance)))
|
highscore += "{pos: <{poswidth}} {name: <{namewidth}s} {balance: >{balwidth}}\n".format(
|
||||||
highscore += str(acc.balance) + "\n"
|
pos=pos, poswidth=poswidth, name=name, namewidth=namewidth,
|
||||||
place += 1
|
balance=balance, balwidth=balwidth
|
||||||
|
)
|
||||||
if highscore != "":
|
if highscore != "":
|
||||||
for page in pagify(highscore, shorten_by=12):
|
for page in pagify(highscore, shorten_by=12):
|
||||||
await ctx.send(box(page, lang="py"))
|
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):
|
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)
|
bal = await get_balance(member)
|
||||||
return await set_balance(member, amount + bal)
|
return await set_balance(member, amount + bal)
|
||||||
@ -287,62 +287,81 @@ async def wipe_bank():
|
|||||||
await _conf.clear_all_members()
|
await _conf.clear_all_members()
|
||||||
|
|
||||||
|
|
||||||
async def get_guild_accounts(guild: discord.Guild) -> List[Account]:
|
async def get_leaderboard(positions: int=None, guild: discord.Guild=None) -> List[tuple]:
|
||||||
"""Get all account data for the given guild.
|
"""
|
||||||
|
Gets the bank's leaderboard
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
positions : `int`
|
||||||
|
The number of positions to get
|
||||||
guild : discord.Guild
|
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
|
Returns
|
||||||
-------
|
-------
|
||||||
`list` of `Account`
|
`list` of `tuple`
|
||||||
A list of all guild accounts.
|
The sorted leaderboard in the form of :code:`(user_id, raw_account)`
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
RuntimeError
|
TypeError
|
||||||
If the bank is currently global.
|
If the bank is guild-specific and no guild was specified
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if await is_global():
|
if await is_global():
|
||||||
raise RuntimeError("The bank is currently global.")
|
raw_accounts = await _conf.all_users()
|
||||||
|
if guild is not None:
|
||||||
ret = []
|
tmp = raw_accounts.copy()
|
||||||
accs = await _conf.all_members(guild)
|
for acc in tmp:
|
||||||
for user_id, acc in accs.items():
|
if not guild.get_member(acc):
|
||||||
acc_data = acc.copy() # There ya go kowlin
|
del raw_accounts[acc]
|
||||||
acc_data['created_at'] = _decode_time(acc_data['created_at'])
|
else:
|
||||||
ret.append(Account(**acc_data))
|
if guild is None:
|
||||||
return ret
|
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]:
|
async def get_leaderboard_position(member: Union[discord.User, discord.Member]) -> Union[int, None]:
|
||||||
"""Get all global account data.
|
"""
|
||||||
|
Get the leaderboard position for the specified user
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
member : `discord.User` or `discord.Member`
|
||||||
|
The user to get the leaderboard position of
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
`list` of `Account`
|
`int`
|
||||||
A list of all global accounts.
|
The position of the user on the leaderboard
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
RuntimeError
|
TypeError
|
||||||
If the bank is currently guild specific.
|
If the bank is currently guild-specific and a `discord.User` object was passed in
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not await is_global():
|
if await is_global():
|
||||||
raise RuntimeError("The bank is not currently global.")
|
guild = None
|
||||||
|
else:
|
||||||
ret = []
|
guild = member.guild if hasattr(member, "guild") else None
|
||||||
accs = await _conf.all_users() # this is a dict of user -> acc
|
try:
|
||||||
for user_id, acc in accs.items():
|
leaderboard = await get_leaderboard(None, guild)
|
||||||
acc_data = acc.copy()
|
except TypeError:
|
||||||
acc_data['created_at'] = _decode_time(acc_data['created_at'])
|
raise
|
||||||
ret.append(Account(**acc_data))
|
else:
|
||||||
|
pos = discord.utils.find(lambda x: x[1][0] == member.id, enumerate(leaderboard, 1))
|
||||||
return ret
|
if pos is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return pos[0]
|
||||||
|
|
||||||
|
|
||||||
async def get_account(member: Union[discord.Member, discord.User]) -> Account:
|
async def get_account(member: Union[discord.Member, discord.User]) -> Account:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user