Merge branch 'master' of git.slipstreamm.dev:slipstream/discordbot
This commit is contained in:
commit
15f8c91baf
@ -9,16 +9,35 @@ import json
|
||||
import os
|
||||
import aiofiles # Import aiofiles
|
||||
import aiofiles.os
|
||||
import discord_oauth
|
||||
|
||||
GIVEAWAY_DATA_FILE = "data/giveaways.json"
|
||||
DATA_DIR = "data"
|
||||
|
||||
|
||||
# --- Helper Functions ---
|
||||
async def get_nitro_status_oauth(user: discord.User | discord.Member) -> bool | None:
|
||||
"""Return True if user has Nitro according to OAuth info, False if not, None if unknown."""
|
||||
token = await discord_oauth.get_token(str(user.id))
|
||||
if not token:
|
||||
return None
|
||||
try:
|
||||
user_info = await discord_oauth.get_user_info(token)
|
||||
except Exception:
|
||||
return None
|
||||
return user_info.get("premium_type", 0) in (1, 2)
|
||||
|
||||
|
||||
# --- Additional Helper Functions ---
|
||||
async def is_user_nitro_like(
|
||||
user: discord.User | discord.Member, bot: commands.Bot = None
|
||||
) -> bool:
|
||||
"""Checks if a user has an animated avatar or a banner, indicating Nitro."""
|
||||
"""Heuristically check if a user has Nitro, falling back to OAuth if available."""
|
||||
|
||||
nitro_oauth = await get_nitro_status_oauth(user)
|
||||
if nitro_oauth is not None:
|
||||
return nitro_oauth
|
||||
|
||||
# Fetch the full user object to get banner information
|
||||
if bot:
|
||||
try:
|
||||
@ -59,10 +78,23 @@ class GiveawayEnterButton(ui.Button["GiveawayEnterView"]):
|
||||
await interaction.message.edit(view=self.view)
|
||||
return
|
||||
|
||||
if giveaway["is_nitro_giveaway"]:
|
||||
if not await is_user_nitro_like(interaction.user, bot=self.cog.bot):
|
||||
if giveaway["is_nitro_giveaway"] or giveaway.get("exclude_nitro_users"):
|
||||
nitro_status = await get_nitro_status_oauth(interaction.user)
|
||||
if nitro_status is None:
|
||||
await interaction.response.send_message(
|
||||
"This is a Nitro-exclusive giveaway. You don't appear to have Nitro (animated avatar or banner).",
|
||||
"Please authenticate with /auth so I can verify your Nitro status before entering.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
||||
if giveaway["is_nitro_giveaway"] and not nitro_status:
|
||||
await interaction.response.send_message(
|
||||
"This is a Nitro-exclusive giveaway, and your account does not appear to have Nitro.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
||||
if giveaway.get("exclude_nitro_users") and nitro_status:
|
||||
await interaction.response.send_message(
|
||||
"Nitro users are excluded from this giveaway.",
|
||||
ephemeral=True,
|
||||
)
|
||||
return
|
||||
@ -150,11 +182,16 @@ class GiveawayRerollButton(ui.Button["GiveawayEndView"]):
|
||||
except discord.NotFound:
|
||||
continue # Skip if user cannot be found
|
||||
if user and not user.bot:
|
||||
# Apply Nitro check again if it was a nitro giveaway
|
||||
if giveaway_data.get(
|
||||
"is_nitro_giveaway", False
|
||||
) and not is_user_nitro_like(user):
|
||||
continue
|
||||
if giveaway_data.get("is_nitro_giveaway") or giveaway_data.get(
|
||||
"exclude_nitro_users"
|
||||
):
|
||||
nitro_status = await get_nitro_status_oauth(user)
|
||||
if nitro_status is None:
|
||||
continue
|
||||
if giveaway_data.get("is_nitro_giveaway") and not nitro_status:
|
||||
continue
|
||||
if giveaway_data.get("exclude_nitro_users") and nitro_status:
|
||||
continue
|
||||
entrants_users.append(user)
|
||||
|
||||
if not entrants_users:
|
||||
@ -228,6 +265,7 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
# "creator_id": int,
|
||||
# "participants": set(), # Store user_ids. Stored as list in JSON.
|
||||
# "is_nitro_giveaway": bool,
|
||||
# "exclude_nitro_users": bool,
|
||||
# "ended": bool
|
||||
# }
|
||||
# Ensure data directory exists before loading/saving
|
||||
@ -325,6 +363,7 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
)
|
||||
gw_data["participants"] = set(gw_data.get("participants", []))
|
||||
gw_data.setdefault("is_nitro_giveaway", False)
|
||||
gw_data.setdefault("exclude_nitro_users", False)
|
||||
gw_data.setdefault(
|
||||
"ended", gw_data["end_time"] <= now
|
||||
) # Set ended if time has passed
|
||||
@ -432,7 +471,8 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
prize="What is the prize?",
|
||||
duration="How long should the giveaway last? (e.g., 10m, 1h, 2d, 1w)",
|
||||
winners="How many winners? (default: 1)",
|
||||
nitro_giveaway="Is this a Nitro-only giveaway? (checks for animated avatar/banner)",
|
||||
nitro_giveaway="Is this a Nitro-only giveaway? (OAuth verification)",
|
||||
exclude_nitro="Exclude Nitro users from entering?",
|
||||
)
|
||||
@app_commands.checks.has_permissions(manage_guild=True)
|
||||
async def create_giveaway_slash(
|
||||
@ -442,6 +482,7 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
duration: str,
|
||||
winners: int = 1,
|
||||
nitro_giveaway: bool = False,
|
||||
exclude_nitro: bool = False,
|
||||
):
|
||||
"""Slash command to create a giveaway using buttons."""
|
||||
parsed_duration = self.parse_duration(duration)
|
||||
@ -469,6 +510,8 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
)
|
||||
if nitro_giveaway:
|
||||
embed.description += "\n*This is a Nitro-exclusive giveaway!*"
|
||||
if exclude_nitro:
|
||||
embed.description += "\n*Users with Nitro are excluded from entering.*"
|
||||
embed.set_footer(
|
||||
text=f"Giveaway started by {interaction.user.display_name}. Entries: 0"
|
||||
) # Initial entry count
|
||||
@ -488,6 +531,7 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
"creator_id": interaction.user.id,
|
||||
"participants": set(),
|
||||
"is_nitro_giveaway": nitro_giveaway,
|
||||
"exclude_nitro_users": exclude_nitro,
|
||||
"ended": False,
|
||||
}
|
||||
self.active_giveaways.append(giveaway_data)
|
||||
@ -559,10 +603,16 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
if user_to_check.bot:
|
||||
continue
|
||||
|
||||
if giveaway_data["is_nitro_giveaway"] and not is_user_nitro_like(
|
||||
user_to_check
|
||||
if giveaway_data["is_nitro_giveaway"] or giveaway_data.get(
|
||||
"exclude_nitro_users"
|
||||
):
|
||||
continue # Skip non-nitro users for nitro giveaways
|
||||
nitro_status = await get_nitro_status_oauth(user_to_check)
|
||||
if nitro_status is None:
|
||||
continue
|
||||
if giveaway_data["is_nitro_giveaway"] and not nitro_status:
|
||||
continue
|
||||
if giveaway_data.get("exclude_nitro_users") and nitro_status:
|
||||
continue
|
||||
entrants_users.append(user_to_check)
|
||||
|
||||
winners_list = []
|
||||
@ -685,10 +735,16 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
user_id
|
||||
) or await self.bot.fetch_user(user_id)
|
||||
if user and not user.bot:
|
||||
if giveaway_info.get(
|
||||
"is_nitro_giveaway", False
|
||||
) and not is_user_nitro_like(user):
|
||||
continue
|
||||
if giveaway_info.get("is_nitro_giveaway") or giveaway_info.get(
|
||||
"exclude_nitro_users"
|
||||
):
|
||||
nitro_status = await get_nitro_status_oauth(user)
|
||||
if nitro_status is None:
|
||||
continue
|
||||
if giveaway_info.get("is_nitro_giveaway") and not nitro_status:
|
||||
continue
|
||||
if giveaway_info.get("exclude_nitro_users") and nitro_status:
|
||||
continue
|
||||
entrants.add(user)
|
||||
if not entrants:
|
||||
await interaction.followup.send(
|
||||
@ -704,8 +760,23 @@ class GiveawaysCog(commands.Cog, name="Giveaways"):
|
||||
reaction_found = True
|
||||
async for user in reaction.users():
|
||||
if not user.bot:
|
||||
# For manual reaction roll, we might not know if it was nitro_giveaway
|
||||
# Consider adding a parameter to manual_roll for this if needed
|
||||
if giveaway_info and (
|
||||
giveaway_info.get("is_nitro_giveaway")
|
||||
or giveaway_info.get("exclude_nitro_users")
|
||||
):
|
||||
nitro_status = await get_nitro_status_oauth(user)
|
||||
if nitro_status is None:
|
||||
continue
|
||||
if (
|
||||
giveaway_info.get("is_nitro_giveaway")
|
||||
and not nitro_status
|
||||
):
|
||||
continue
|
||||
if (
|
||||
giveaway_info.get("exclude_nitro_users")
|
||||
and nitro_status
|
||||
):
|
||||
continue
|
||||
entrants.add(user)
|
||||
break
|
||||
if not reaction_found:
|
||||
|
Loading…
x
Reference in New Issue
Block a user