Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[currency] add commands to admin and player cog for currency #555

Open
wants to merge 4 commits into
base: currency/base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions ballsdex/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,22 @@ async def is_friend(self, other_player: "Player") -> bool:
async def is_blocked(self, other_player: "Player") -> bool:
return await Block.filter((Q(player1=self) & Q(player2=other_player))).exists()

async def add_money(self, amount: int) -> int:
if amount <= 0:
raise ValueError("Amount to add must be positive")
self.money += amount
await self.save(update_fields=("money",))
return self.money

async def remove_money(self, amount: int) -> None:
if self.money < amount:
raise ValueError("Not enough money")
self.money -= amount
await self.save(update_fields=("money",))

async def can_afford(self, amount: int) -> bool:
return self.money >= amount

@property
def can_be_mentioned(self) -> bool:
return self.mention_policy == MentionPolicy.ALLOW
Expand Down
2 changes: 2 additions & 0 deletions ballsdex/packages/admin/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .history import History as HistoryGroup
from .info import Info as InfoGroup
from .logs import Logs as LogsGroup
from .money import Money as MoneyGroup

if TYPE_CHECKING:
from ballsdex.core.bot import BallsDexBot
Expand All @@ -41,6 +42,7 @@ def __init__(self, bot: "BallsDexBot"):
self.__cog_app_commands_group__.add_command(HistoryGroup())
self.__cog_app_commands_group__.add_command(LogsGroup())
self.__cog_app_commands_group__.add_command(InfoGroup())
self.__cog_app_commands_group__.add_command(MoneyGroup())

@app_commands.command()
@app_commands.checks.has_any_role(*settings.root_role_ids)
Expand Down
154 changes: 154 additions & 0 deletions ballsdex/packages/admin/money.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import discord
from discord import app_commands

from ballsdex.core.bot import BallsDexBot
from ballsdex.core.models import Player
from ballsdex.core.utils.logging import log_action
from ballsdex.settings import settings


class Money(app_commands.Group):
"""
Commands to manipulate user's currency.
"""

@app_commands.command()
async def balance(self, interaction: discord.Interaction[BallsDexBot], user: discord.User):
"""
Show the balance of the user provided

Parameters
----------
user: discord.User
The user you want to get information about.
"""
await interaction.response.defer(ephemeral=True, thinking=True)
player = await Player.get_or_none(discord_id=user.id)
if not player:
await interaction.followup.send(
f"This user does not have a {settings.bot_name} account.", ephemeral=True
)
return

await interaction.followup.send(
f"{user.mention} currently has {player.money:,} coins.", ephemeral=True
)

@app_commands.command()
async def add(
self, interaction: discord.Interaction[BallsDexBot], user: discord.User, amount: int
):
"""
Add coins to the user provided

Parameters
----------
user: discord.User
The user you want to add coins to.
amount: int
The amount of coins to add.
"""
await interaction.response.defer(ephemeral=True, thinking=True)
player = await Player.get_or_none(discord_id=user.id)
if not player:
await interaction.followup.send(
f"This user does not have a {settings.bot_name} account.", ephemeral=True
)
return

if amount <= 0:
await interaction.followup.send(
"The amount must be greater than zero.", ephemeral=True
)
return

await player.add_money(amount)
await interaction.followup.send(
f"{amount:,} coins have been added to {user.mention}.", ephemeral=True
)
await log_action(
f"{interaction.user} ({interaction.user.id}) added {amount:,} coins to "
f"{user} ({user.id})",
interaction.client,
)

@app_commands.command()
async def remove(
self, interaction: discord.Interaction[BallsDexBot], user: discord.User, amount: int
):
"""
Remove coins from the user provided

Parameters
----------
user: discord.User
The user you want to remove coins from.
amount: int
The amount of coins to remove.
"""
await interaction.response.defer(ephemeral=True, thinking=True)
player = await Player.get_or_none(discord_id=user.id)
if not player:
await interaction.followup.send(
f"This user does not have a {settings.bot_name} account.", ephemeral=True
)
return

if amount <= 0:
await interaction.followup.send(
"The amount must be greater than zero.", ephemeral=True
)
return
if not await player.can_afford(amount):
await interaction.followup.send(
"This user does not have enough coins to remove.", ephemeral=True
)
return
await player.remove_money(amount)
await interaction.followup.send(
f"{amount:,} coins have been removed from {user.mention}.", ephemeral=True
)
await log_action(
f"{interaction.user} ({interaction.user.id}) removed {amount:,} coins from "
f"{user} ({user.id})",
interaction.client,
)

@app_commands.command()
async def set(
self, interaction: discord.Interaction[BallsDexBot], user: discord.User, amount: int
):
"""
Set the balance of the user provided

Parameters
----------
user: discord.User
The user you want to set the balance of.
amount: int
The amount of coins to set.
"""
await interaction.response.defer(ephemeral=True, thinking=True)
player = await Player.get_or_none(discord_id=user.id)
if not player:
await interaction.followup.send(
f"This user has does not have a {settings.bot_name} account.", ephemeral=True
)
return

if amount < 0:
await interaction.followup.send(
"The amount must be greater than or equal to zero.", ephemeral=True
)
return

player.money = amount
await player.save()
await interaction.followup.send(
f"{user.mention} now has {amount:,} coins.", ephemeral=True
)
await log_action(
f"{interaction.user} ({interaction.user.id}) set the balance of "
f"{user} ({user.id}) to {amount:,} coins",
interaction.client,
)
54 changes: 53 additions & 1 deletion ballsdex/packages/players/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self, bot: "BallsDexBot"):
friend = app_commands.Group(name="friend", description="Friend commands")
blocked = app_commands.Group(name="block", description="Block commands")
policy = app_commands.Group(name="policy", description="Policy commands")
money = app_commands.Group(name="money", description="Money commands")

@policy.command()
@app_commands.choices(
Expand Down Expand Up @@ -559,12 +560,63 @@ async def info(self, interaction: discord.Interaction):
f"**{settings.collectible_name.title()}s Owned:** {len(balls_owned):,}\n"
f"**Caught {settings.collectible_name.title()}s Owned**: {len(caught_owned):,}\n"
f"**Special {settings.collectible_name.title()}s:** {len(special):,}\n"
f"**Trades Completed:** {trades:,}"
f"**Trades Completed:** {trades:,}\n"
f"**Current Balance:** {player.money:,}"
)
embed.set_footer(text="Keep collecting and trading to improve your stats!")
embed.set_thumbnail(url=user.display_avatar) # type: ignore
await interaction.followup.send(embed=embed, ephemeral=True)

@money.command()
async def balance(self, interaction: discord.Interaction):
"""
Check your balance.
"""
player, _ = await PlayerModel.get_or_create(discord_id=interaction.user.id)
await interaction.response.send_message(
f"Your balance is **{player.money:,}**.", ephemeral=True
)

@money.command()
async def give(self, interaction: discord.Interaction, user: discord.User, amount: int):
"""
Give coins to another user.

Parameters
----------
user: discord.User
The user you want to give coins to.
amount: int
The amount of coins to give.
"""
player, _ = await PlayerModel.get_or_create(discord_id=interaction.user.id)
if not player.can_afford(amount):
await interaction.response.send_message(
"You do not have enough coins to give.", ephemeral=True
)
return
if amount <= 0:
await interaction.response.send_message(
"The amount must be greater than zero.", ephemeral=True
)
return
if user.bot:
await interaction.response.send_message(
"You cannot give coins to a bot.", ephemeral=True
)
return
if user.id == interaction.user.id:
await interaction.response.send_message(
"You cannot give coins to yourself.", ephemeral=True
)
return
other_player, _ = await PlayerModel.get_or_create(discord_id=user.id)
await player.remove_money(amount)
await other_player.add_money(amount)
await interaction.response.send_message(
f"{amount:,} coins have been given to {user.mention}.", ephemeral=True
)

@app_commands.command()
@app_commands.choices(
type=[
Expand Down