Skip to content

Commit b6c88ae

Browse files
committed
2 parents 0a76cae + d4113b9 commit b6c88ae

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

admin_panel/settings/models.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,17 @@ def currency_enabled(self) -> bool:
119119

120120
# admin command control
121121
admin_channel_ids = models.TextField(
122-
help_text="Semicolon-delimited list of channel IDs where admin commands can be used. Ignored for owners. "
122+
help_text="Semicolon-delimited channel IDs where staff may bypass inventory privacy. Ignored for owners."
123123
"If empty, then admin commands can be used everywhere.",
124124
validators=(RegexValidator(COLON_IDS_RE, message="The IDs must be semicolon-separated"),),
125125
blank=True,
126126
default="",
127127
)
128+
129+
@cached_property
130+
def inv_privacy_bypass_ids(self) -> list[int]:
131+
return [] if self.admin_channel_ids is None else [int(x) for x in self.admin_channel_ids.split(";") if x]
132+
128133
webhook_logging = models.URLField(
129134
help_text="An optional Discord Webhook where admin events will be logged.",
130135
validators=(RegexValidator(DISCORD_WEBHOOK_RE, message="Only Discord webhooks are supported."),),

ballsdex/core/utils/utils.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from bd_models.enums import PrivacyPolicy
66
from bd_models.models import Player
7+
from settings.models import settings
78

89
from .checks import get_user_for_check
910

@@ -35,6 +36,7 @@ async def is_staff(interaction: discord.Interaction["BallsDexBot"], *perms: str)
3536
return user
3637
if not user.is_staff:
3738
return False
39+
3840
return await user.ahas_perms(perms)
3941

4042

@@ -70,7 +72,9 @@ async def inventory_privacy(
7072
if interaction.user.id == player.discord_id:
7173
return True
7274
if await is_staff(interaction):
73-
return True
75+
if settings.inv_privacy_bypass_ids and interaction.channel_id in settings.inv_privacy_bypass_ids:
76+
return True
77+
7478
if privacy_policy == PrivacyPolicy.DENY:
7579
await interaction.followup.send("This user has set their inventory to private.", ephemeral=True)
7680
return False

ballsdex/packages/balls/cog.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,14 @@ async def list(
190190
else:
191191
combined = ""
192192

193+
combined_txt = f"{combined} " if combined else ""
193194
if user_obj == interaction.user:
194195
await interaction.followup.send(
195-
f"You don't have any {combined} {settings.plural_collectible_name} yet."
196+
f"You don't have any {combined_txt}{settings.plural_collectible_name} yet."
196197
)
197198
else:
198199
await interaction.followup.send(
199-
f"{user_obj.name} doesn't have any {combined} {settings.plural_collectible_name} yet."
200+
f"{user_obj.name} doesn't have any {combined_txt}{settings.plural_collectible_name} yet."
200201
)
201202
return
202203
if reverse:

ballsdex/packages/trade/trade.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from ballsdex.core.discord import UNKNOWN_INTERACTION, Container, LayoutView, Modal
2222
from ballsdex.core.utils.buttons import ConfirmChoiceView
2323
from ballsdex.core.utils.menus import CountryballFormatter, Menu, ModelSource, TextFormatter, TextSource
24+
from bd_models.enums import TradeCooldownPolicy
2425
from bd_models.models import BallInstance, Player, Trade, TradeObject
2526
from settings.models import settings
2627
from settings.utils import format_currency
@@ -49,6 +50,7 @@
4950
log = logging.getLogger(__name__)
5051

5152
TRADE_TIMEOUT = 60 * 30
53+
COOLDOWN_BYPASS_TIMEOUT = 10
5254

5355

5456
class SetMoneyModal(Modal, title="Set money offering"):
@@ -423,6 +425,7 @@ def __init__(self, cog: "TradeCog"):
423425
self.confirmation_lock = asyncio.Lock()
424426
self.edit_lock = asyncio.Lock()
425427
self.next_edit_interaction: Interaction | None = None
428+
self.confirmation_phase_start: datetime | None = None
426429

427430
self.timeout_task = asyncio.create_task(self._timeout(), name=f"trade-timeout-{id(self)}")
428431

@@ -465,6 +468,8 @@ async def lock_button(self, interaction: Interaction, button: Button):
465468
except TradeError as e:
466469
await interaction.followup.send(e.error_message, ephemeral=True)
467470
else:
471+
if self.confirmation_phase and self.confirmation_phase_start is None:
472+
self.confirmation_phase_start = datetime.now()
468473
await self.edit_message(interaction)
469474

470475
@buttons.button(label="Reset", emoji="\N{DASH SYMBOL}", style=discord.ButtonStyle.secondary)
@@ -517,6 +522,18 @@ async def cancel_button(self, interaction: Interaction, button: Button):
517522
)
518523
async def confirm_button(self, interaction: Interaction, button: Button):
519524
trader = {self.trader1.user.id: self.trader1, self.trader2.user.id: self.trader2}[interaction.user.id]
525+
both_bypass = (
526+
self.trader1.player.trade_cooldown_policy == TradeCooldownPolicy.BYPASS
527+
and self.trader2.player.trade_cooldown_policy == TradeCooldownPolicy.BYPASS
528+
)
529+
if not both_bypass and self.confirmation_phase_start is not None:
530+
elapsed = (datetime.now() - self.confirmation_phase_start).total_seconds()
531+
remaining = COOLDOWN_BYPASS_TIMEOUT - elapsed
532+
if remaining > 0:
533+
await interaction.response.send_message(
534+
f"Please wait {remaining:.0f} more second(s) before confirming.", ephemeral=True
535+
)
536+
return
520537
await interaction.response.defer()
521538
try:
522539
await trader.confirm()

0 commit comments

Comments
 (0)