First Commit
This commit is contained in:
Executable
Executable
+129
@@ -0,0 +1,129 @@
|
||||
import discord
|
||||
import datetime
|
||||
|
||||
from discord.ext import commands, tasks
|
||||
from utils.sql_commands import DatabaseManager
|
||||
from dotenv import dotenv_values
|
||||
|
||||
|
||||
|
||||
|
||||
def check(author):
|
||||
def inner_check(message):
|
||||
return message.author == author
|
||||
|
||||
return inner_check
|
||||
|
||||
|
||||
class Birthday(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
self.db = DatabaseManager("")
|
||||
self.birthday_checks = {}
|
||||
|
||||
async def cog_load(self):
|
||||
self.check_birthdays.start()
|
||||
|
||||
async def cog_unload(self):
|
||||
self.check_birthdays.cancel()
|
||||
|
||||
@tasks.loop(seconds=60*60*24) # daily
|
||||
async def check_birthdays(self):
|
||||
today = datetime.date.today()
|
||||
for guild in self.client.guilds:
|
||||
guild_id = guild.id
|
||||
for member in guild.members:
|
||||
user_id = member.id
|
||||
user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
|
||||
if user_data is None or user_data.get("birthday") is None:
|
||||
continue
|
||||
|
||||
birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
|
||||
if birthday.month == today.month and birthday.day == today.day:
|
||||
# send birthday message
|
||||
try:
|
||||
channel = guild.text_channels[0]
|
||||
await channel.send(f"Happy birthday, {member.mention}! 🎉")
|
||||
except discord.Forbidden:
|
||||
continue
|
||||
except discord.HTTPException:
|
||||
continue
|
||||
# give birthday reward
|
||||
reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'")
|
||||
if reward is not None:
|
||||
try:
|
||||
await self.client.get_cog("Economy").add_points(user_id, guild_id, reward.get("amount"), "birthday reward")
|
||||
except Exception as e:
|
||||
print(f"Error giving birthday reward: {e}")
|
||||
# give birthday star role
|
||||
role = discord.utils.get(guild.roles, name="Birthday Star")
|
||||
if role is not None:
|
||||
try:
|
||||
await member.add_roles(role)
|
||||
except discord.Forbidden:
|
||||
continue
|
||||
except discord.HTTPException:
|
||||
continue
|
||||
# log birthday reward
|
||||
try:
|
||||
self.db.execute_query("INSERT INTO logs (guild_id, user_id, type, message) VALUES (%s, %s, 'birthday_reward', 'claimed birthday reward')", (guild_id, user_id))
|
||||
except Exception as e:
|
||||
print(f"Error logging birthday reward: {e}")
|
||||
|
||||
@check_birthdays.before_loop
|
||||
async def before_check_birthdays(self):
|
||||
await self.client.wait_until_ready()
|
||||
|
||||
@commands.command(name="setbirthday", aliases=["sb"])
|
||||
async def setbirthday(self, ctx, month: int, day: int):
|
||||
if month < 1 or month > 12 or day < 1 or day > 31:
|
||||
return await ctx.send("Invalid date")
|
||||
|
||||
user_id = ctx.author.id
|
||||
user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
|
||||
|
||||
if user_data is not None and user_data.get("birthday") is not None:
|
||||
return await ctx.send("You've already set your birthday")
|
||||
|
||||
self.db.execute_query("UPDATE users SET birthday = %s WHERE ID = %s", (f"{datetime.date.today().year}-{month}-{day}", user_id))
|
||||
await ctx.send("Your birthday has been set")
|
||||
|
||||
@commands.command(name="claimbirthday", aliases=["cb"])
|
||||
async def claimbirthday(self, ctx):
|
||||
user_id = ctx.author.id
|
||||
user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
|
||||
|
||||
if user_data is None or user_data.get("birthday") is None:
|
||||
return await ctx.send("You haven't set your birthday")
|
||||
|
||||
today = datetime.date.today()
|
||||
birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
|
||||
if birthday.month != today.month or birthday.day != today.day:
|
||||
return await ctx.send("It's not your birthday")
|
||||
|
||||
reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'")
|
||||
if reward is None:
|
||||
return await ctx.send("No birthday reward set")
|
||||
|
||||
await self.client.get_cog("Economy").add_points(user_id, ctx.guild.id, reward.get("amount"), "birthday reward")
|
||||
await ctx.send("You've claimed your birthday reward")
|
||||
|
||||
@commands.command(name="listbirthdays", aliases=["lb"])
|
||||
async def listbirthdays(self, ctx):
|
||||
today = datetime.date.today()
|
||||
birthdays = []
|
||||
for guild in self.client.guilds:
|
||||
for member in guild.members:
|
||||
user_id = member.id
|
||||
user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,))
|
||||
if user_data is None or user_data.get("birthday") is None:
|
||||
continue
|
||||
|
||||
birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date()
|
||||
if birthday.month == today.month and birthday.day == today.day:
|
||||
birthdays.append(member.mention)
|
||||
|
||||
if not birthdays:
|
||||
await ctx.send("No birthdays today")
|
||||
else:
|
||||
await ctx.send(f"Happy birthday to {', '.join(birthdays)}! 🎉")
|
||||
Executable
+174
@@ -0,0 +1,174 @@
|
||||
# blush cry dance lewd pout shrug sleepy smile smug thumbsup wag thinking triggered teehee deredere thonking scoff happy thumbs grin
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from utils import sql_commands as mydb
|
||||
from random import choice
|
||||
|
||||
|
||||
class Emotes(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
self.emotes = {
|
||||
"blush": ["https://media.giphy.com/media/3o6Zt6ML6BklcajjsA/giphy.gif"],
|
||||
"cry": ["https://media.giphy.com/media/ROF8OQvDmxytW/giphy.gif"],
|
||||
"dance": ["https://media.giphy.com/media/l0MYt5jPR6QX5pnqM/giphy.gif"],
|
||||
# ...add more emotes...
|
||||
}
|
||||
self.emote_packs = {
|
||||
"happy": ["smile", "grin", "thumbsup"],
|
||||
"sleepy": ["sleepy", "yawn"],
|
||||
# ...add more packs...
|
||||
}
|
||||
self.cooldowns = {} # {user_id: {emote: timestamp}}
|
||||
self.emote_usage = {} # {user_id: {emote: count}}
|
||||
self.unlocked_emotes = {} # {user_id: set(emote_names)}
|
||||
self.pending_emotes = [] # [(user_id, emote_name, url)]
|
||||
|
||||
# --- Emote Command for Each Emote ---
|
||||
@commands.command(name="emote")
|
||||
async def emote(self, ctx, emote_name: str, member: discord.Member = None):
|
||||
"""Send an emote GIF, optionally mentioning a user."""
|
||||
emote = emote_name.lower()
|
||||
# Economy/level check
|
||||
if emote not in self.emotes and emote not in self.get_custom_emotes():
|
||||
await ctx.send("Unknown emote.")
|
||||
return
|
||||
if not self.has_unlocked(ctx.author.id, emote):
|
||||
await ctx.send("You haven't unlocked this emote yet!")
|
||||
return
|
||||
|
||||
# Cooldown check (10s per emote per user)
|
||||
import time
|
||||
|
||||
now = time.time()
|
||||
user_cooldowns = self.cooldowns.setdefault(ctx.author.id, {})
|
||||
if emote in user_cooldowns and now - user_cooldowns[emote] < 10:
|
||||
await ctx.send("You're using that emote too quickly!")
|
||||
return
|
||||
user_cooldowns[emote] = now
|
||||
|
||||
# Usage tracking
|
||||
user_usage = self.emote_usage.setdefault(ctx.author.id, {})
|
||||
user_usage[emote] = user_usage.get(emote, 0) + 1
|
||||
|
||||
url = choice(self.emotes.get(emote, self.get_custom_emotes().get(emote, [""])))
|
||||
mention = member.mention if member else ""
|
||||
await ctx.send(
|
||||
f"{ctx.author.mention} {mention}", embed=discord.Embed().set_image(url=url)
|
||||
)
|
||||
|
||||
# --- Individual Emote Commands (e.g., !blush, !cry, !dance) ---
|
||||
# Dynamically add a command for each emote
|
||||
def __init_subclass__(cls):
|
||||
def make_emote_cmd(emote):
|
||||
async def _cmd(self, ctx, member: discord.Member = None):
|
||||
await self.emote(ctx, emote, member)
|
||||
|
||||
return _cmd
|
||||
|
||||
for emote in ["blush", "cry", "dance"]: # Add all your emote names here
|
||||
setattr(cls, emote, commands.command(name=emote)(make_emote_cmd(emote)))
|
||||
|
||||
# --- Emote Combos ---
|
||||
@commands.command(name="emotecombo")
|
||||
async def emote_combo(self, ctx, *emotes):
|
||||
"""Send multiple emotes in one message."""
|
||||
urls = []
|
||||
for emote in emotes:
|
||||
if self.has_unlocked(ctx.author.id, emote) and (
|
||||
emote in self.emotes or emote in self.get_custom_emotes()
|
||||
):
|
||||
urls.append(
|
||||
choice(
|
||||
self.emotes.get(
|
||||
emote, self.get_custom_emotes().get(emote, [""])
|
||||
)
|
||||
)
|
||||
)
|
||||
if not urls:
|
||||
await ctx.send("No valid emotes found.")
|
||||
return
|
||||
for url in urls:
|
||||
embed = discord.Embed().set_image(url=url)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
# --- Emote Packs ---
|
||||
@commands.command(name="emotepack")
|
||||
async def emote_pack(self, ctx, pack_name: str):
|
||||
"""Send all emotes from a pack."""
|
||||
pack = self.emote_packs.get(pack_name.lower())
|
||||
if not pack:
|
||||
await ctx.send("Unknown emote pack.")
|
||||
return
|
||||
for emote in pack:
|
||||
if self.has_unlocked(ctx.author.id, emote) and (
|
||||
emote in self.emotes or emote in self.get_custom_emotes()
|
||||
):
|
||||
url = choice(
|
||||
self.emotes.get(emote, self.get_custom_emotes().get(emote, [""]))
|
||||
)
|
||||
await ctx.send(embed=discord.Embed().set_image(url=url))
|
||||
|
||||
# --- Emote Leaderboard ---
|
||||
@commands.command(name="emoteleaderboard")
|
||||
async def emote_leaderboard(self, ctx):
|
||||
"""Show top emote users."""
|
||||
leaderboard = sorted(
|
||||
((uid, sum(uses.values())) for uid, uses in self.emote_usage.items()),
|
||||
key=lambda x: x[1],
|
||||
reverse=True,
|
||||
)[:10]
|
||||
desc = ""
|
||||
for i, (uid, count) in enumerate(leaderboard, 1):
|
||||
user = self.client.get_user(uid)
|
||||
desc += f"{i}. {user.mention if user else uid}: {count} emotes\n"
|
||||
await ctx.send(
|
||||
embed=discord.Embed(
|
||||
title="Emote Leaderboard", description=desc or "No data."
|
||||
)
|
||||
)
|
||||
|
||||
# --- Emote Reactions ---
|
||||
@commands.command(name="react")
|
||||
async def react(self, ctx, emote_name: str, message_id: int):
|
||||
"""React to a message with an emote (as emoji if available)."""
|
||||
emote = emote_name.lower()
|
||||
try:
|
||||
msg = await ctx.channel.fetch_message(message_id)
|
||||
# If you have custom emoji, use them; else, fallback to unicode or skip
|
||||
await msg.add_reaction("😄") # Replace with actual emoji logic
|
||||
await ctx.send("Reacted!")
|
||||
except Exception:
|
||||
await ctx.send("Could not react to that message.")
|
||||
|
||||
# --- Custom Emotes Submission ---
|
||||
@commands.command(name="submit_emote")
|
||||
async def submit_emote(self, ctx, emote_name: str, url: str):
|
||||
"""Submit a custom emote for approval."""
|
||||
self.pending_emotes.append((ctx.author.id, emote_name, url))
|
||||
await ctx.send(
|
||||
f"Emote `{emote_name}` submitted for approval! (Admins: review pending list)"
|
||||
)
|
||||
|
||||
def get_custom_emotes(self):
|
||||
# In production, load from DB or approved list
|
||||
return {}
|
||||
|
||||
# --- Unlock Emotes with Level/Economy ---
|
||||
@commands.command(name="unlock_emote")
|
||||
async def unlock_emote(self, ctx, emote_name: str):
|
||||
"""Unlock an emote using currency or level."""
|
||||
# Example: check user balance/level, deduct cost, unlock emote
|
||||
# Replace with your actual economy/level logic
|
||||
user_id = ctx.author.id
|
||||
unlocked = self.unlocked_emotes.setdefault(user_id, set())
|
||||
unlocked.add(emote_name)
|
||||
await ctx.send(f"Emote `{emote_name}` unlocked!")
|
||||
|
||||
def has_unlocked(self, user_id, emote_name):
|
||||
# Always unlocked for now, add logic for locked emotes
|
||||
return True
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Emotes(client))
|
||||
Executable
+281
@@ -0,0 +1,281 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from random import choice
|
||||
import requests
|
||||
from dotenv import dotenv_values
|
||||
|
||||
# Initialize responses for eightball command
|
||||
eightball_responses = [
|
||||
"Yes, definitely.",
|
||||
"No, not at all.",
|
||||
"Ask again later.",
|
||||
"Outlook not so good.",
|
||||
"Most likely.",
|
||||
"Don't count on it.",
|
||||
"Signs point to yes.",
|
||||
"Very doubtful.",
|
||||
"Without a doubt.",
|
||||
"My sources say no.",
|
||||
"Outlook is good.",
|
||||
"It is certain.",
|
||||
"Cannot predict now.",
|
||||
"Better not tell you now.",
|
||||
"Yes, in due time.",
|
||||
"No, never.",
|
||||
"Concentrate and ask again.",
|
||||
"Very likely.",
|
||||
"My reply is no.",
|
||||
"Outlook not good.",
|
||||
"Yes, for sure.",
|
||||
"Don't hold your breath.",
|
||||
"As I see it, yes.",
|
||||
"It is decidedly so.",
|
||||
"My sources say yes.",
|
||||
"Definitely not.",
|
||||
"Yes, definitely.",
|
||||
"Very unlikely.",
|
||||
"Ask again another time.",
|
||||
"Cannot foretell now.",
|
||||
"The outlook is bleak.",
|
||||
"Not in a million years.",
|
||||
"It is certain.",
|
||||
"Outlook not good.",
|
||||
"Signs point to yes.",
|
||||
"Without a doubt.",
|
||||
"My sources say no.",
|
||||
"Yes, in due time.",
|
||||
"Definitely not.",
|
||||
"Ask again later.",
|
||||
"Better not tell you now.",
|
||||
"Very likely.",
|
||||
"Yes, for sure.",
|
||||
"No, not at all.",
|
||||
"Don't count on it.",
|
||||
"As I see it, yes.",
|
||||
"My reply is no.",
|
||||
"Concentrate and ask again.",
|
||||
"Outlook is good.",
|
||||
"It is decidedly so.",
|
||||
"My sources say yes.",
|
||||
"Very unlikely.",
|
||||
"Cannot predict now.",
|
||||
"Yes, definitely.",
|
||||
"Not in a million years.",
|
||||
"Ask again another time.",
|
||||
"Without a doubt.",
|
||||
"Signs point to yes.",
|
||||
"The outlook is bleak.",
|
||||
"Definitely not.",
|
||||
"Outlook not good.",
|
||||
"Yes, for sure.",
|
||||
"Better not tell you now.",
|
||||
"My sources say no.",
|
||||
"It is certain.",
|
||||
"Very likely.",
|
||||
"Don't count on it.",
|
||||
"Concentrate and ask again.",
|
||||
"No, not at all.",
|
||||
"Ask again later.",
|
||||
"Yes, definitely.",
|
||||
"Without a doubt.",
|
||||
"Outlook is good.",
|
||||
"My sources say yes.",
|
||||
"Not in a million years.",
|
||||
"Very unlikely.",
|
||||
"Definitely not.",
|
||||
"Better not tell you now.",
|
||||
"As I see it, yes.",
|
||||
"The outlook is bleak.",
|
||||
"Concentrate and ask again.",
|
||||
"Yes, for sure.",
|
||||
"Signs point to yes.",
|
||||
"My reply is no.",
|
||||
"Cannot predict now.",
|
||||
"Ask again another time.",
|
||||
"No, not at all.",
|
||||
"Don't count on it.",
|
||||
"Outlook not so good.",
|
||||
"It is certain.",
|
||||
"Without a doubt.",
|
||||
"Very likely.",
|
||||
"Yes, definitely.",
|
||||
"My sources say no.",
|
||||
"Better not tell you now.",
|
||||
"Definitely not.",
|
||||
"Ask again later.",
|
||||
"Concentrate and ask again.",
|
||||
"The outlook is bleak.",
|
||||
"Not in a million years.",
|
||||
"Yes, for sure.",
|
||||
"As I see it, yes.",
|
||||
"Don't count on it.",
|
||||
"Very unlikely.",
|
||||
"My reply is no.",
|
||||
"Ask again another time.",
|
||||
"Signs point to yes.",
|
||||
"Outlook is good.",
|
||||
"Without a doubt.",
|
||||
"It is certain.",
|
||||
"Yes, definitely.",
|
||||
"Definitely not.",
|
||||
"Better not tell you now.",
|
||||
"Concentrate and ask again.",
|
||||
"No, not at all.",
|
||||
"My sources say yes.",
|
||||
"The outlook is bleak.",
|
||||
"Very likely.",
|
||||
"Ask again later.",
|
||||
"Don't count on it.",
|
||||
"As I see it, yes.",
|
||||
"Yes, for sure.",
|
||||
"Not in a million years.",
|
||||
"Cannot predict now.",
|
||||
"Outlook not good.",
|
||||
"Without a doubt.",
|
||||
"My reply is no.",
|
||||
"Yes, definitely.",
|
||||
"Better not tell you now.",
|
||||
"Concentrate and ask again.",
|
||||
"Definitely not.",
|
||||
"Ask again another time.",
|
||||
"Signs point to yes.",
|
||||
"It is certain.",
|
||||
"Very unlikely.",
|
||||
"Outlook is good.",
|
||||
"No, not at all.",
|
||||
"The outlook is bleak.",
|
||||
"As I see it, yes.",
|
||||
"My sources say no.",
|
||||
"Without a doubt.",
|
||||
"Better not tell you now.",
|
||||
"Concentrate and ask again.",
|
||||
"Yes, for sure.",
|
||||
"Not in a million years.",
|
||||
"Ask again later.",
|
||||
"Definitely not.",
|
||||
"My reply is no.",
|
||||
"Outlook not so good.",
|
||||
"Very likely.",
|
||||
"It is certain.",
|
||||
"Signs point to yes.",
|
||||
"Don't count on it.",
|
||||
"Yes, definitely.",
|
||||
"Better not tell you now.",
|
||||
"Concentrate and ask again.",
|
||||
"Without a doubt.",
|
||||
"Ask again another time.",
|
||||
"Definitely not.",
|
||||
"Outlook is good.",
|
||||
"No, not at all.",
|
||||
"The outlook is bleak.",
|
||||
"As I see it, yes.",
|
||||
"Very unlikely.",
|
||||
"My sources say yes.",
|
||||
"Yes, for sure.",
|
||||
"Cannot predict now.",
|
||||
"Better not tell you now.",
|
||||
"Concentrate and ask again.",
|
||||
"It is certain.",
|
||||
"Ask again later.",
|
||||
"Signs point to yes.",
|
||||
"Outlook not good.",
|
||||
"Without a doubt.",
|
||||
"Definitely not.",
|
||||
"Don't count on it.",
|
||||
"My reply is no.",
|
||||
"The outlook is bleak.",
|
||||
"Very likely.",
|
||||
"Yes, for sure.",
|
||||
"As I see it, yes.",
|
||||
"No, not at all.",
|
||||
"Concentrate and ask again.",
|
||||
"Better not tell you now.",
|
||||
"Ask again another time.",
|
||||
"My sources say yes.",
|
||||
"It is certain.",
|
||||
"Outlook is good.",
|
||||
"Yes, definitely.",
|
||||
"Without a doubt.",
|
||||
"Definitely not.",
|
||||
"Very unlikely.",
|
||||
"The outlook is bleak.",
|
||||
"Concentrate and ask again.",
|
||||
"Signs point to yes.",
|
||||
"No, not at all.",
|
||||
"Ask again later.",
|
||||
"Better not tell you now.",
|
||||
"As I see it, yes.",
|
||||
"My reply is no.",
|
||||
"Yes, for sure.",
|
||||
]
|
||||
|
||||
|
||||
class Fun(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
# Load environment variables for API keys
|
||||
config = dotenv_values(".env")
|
||||
self.tenor_api_key = config.get("TENORAPI")
|
||||
|
||||
@commands.command(
|
||||
name="eightball",
|
||||
aliases=["eb", "8ball", "8b"],
|
||||
brief="Ask a question and I shall answer.",
|
||||
description="I will predict the answer to any and all of your questions.",
|
||||
)
|
||||
async def eight_ball(self, ctx, *, question: str):
|
||||
"""Respond with a random answer to a yes/no question."""
|
||||
if question:
|
||||
response = choice(eightball_responses)
|
||||
await ctx.send(f"Answer: {response}")
|
||||
else:
|
||||
await ctx.send("Please ask a question for the 8ball to answer.")
|
||||
|
||||
@commands.command()
|
||||
async def randomgif(self, ctx, *query):
|
||||
"""Fetch and display a random GIF based on a search query."""
|
||||
if not self.tenor_api_key:
|
||||
await ctx.send("Tenor API key is not configured.")
|
||||
return
|
||||
|
||||
search_query = "%20".join(query) if query else "funny"
|
||||
api_url = f"https://tenor.googleapis.com/v2/search?q={search_query}&key={self.tenor_api_key}&limit=10"
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
gif_data = response.json()
|
||||
|
||||
if gif_data.get("results"):
|
||||
gif_url = choice(gif_data["results"])["media_formats"]["gif"]["url"]
|
||||
embed = discord.Embed(title="Here's a random GIF!")
|
||||
embed.set_image(url=gif_url)
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
await ctx.send("No GIFs found for your query.")
|
||||
|
||||
except requests.RequestException as error:
|
||||
await ctx.send(f"Error fetching Tenor GIF: {error}")
|
||||
|
||||
@commands.command()
|
||||
async def meme(self, ctx):
|
||||
"""Fetch and display a random meme."""
|
||||
api_url = "https://meme-api.com/memes/random"
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
meme_data = response.json()
|
||||
|
||||
meme_url = meme_data.get("url")
|
||||
if meme_url:
|
||||
await ctx.send(meme_url)
|
||||
else:
|
||||
await ctx.send("Couldn't fetch a meme at the moment.")
|
||||
|
||||
except requests.RequestException:
|
||||
await ctx.send("Error fetching meme.")
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Fun(client))
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from utils import sql_commands as mydb
|
||||
from random import choice
|
||||
|
||||
slap = ["https://media1.tenor.com/m/tfu-SnLkaP4AAAAC/alarm-clock.gif", "https://media1.tenor.com/m/yCC2nXLRPBgAAAAC/utku-tokat.gif", "https://media.tenor.com/fZQYHVUDfckAAAAi/slap.gif", "https://media.tenor.com/TVPYqh_E1JYAAAAi/peach-goma-peach-and-goma.gif"]
|
||||
sad = ["https://media1.tenor.com/m/a-ooSHLa2lsAAAAC/im-sad.gif","https://media1.tenor.com/m/M_V1fbsCEbAAAAAd/sad-om-nom.gif", "https://media1.tenor.com/m/bwtBRKlfEzgAAAAC/sad-crying.gif", "https://media1.tenor.com/m/5t-iIxnzE8MAAAAC/sad-bear-cry.gif", "https://media1.tenor.com/m/CKez5CfynccAAAAd/looking-out-the-window-om-nom.gif"]
|
||||
hug = ["https://media1.tenor.com/m/2qjVr7KUQKgAAAAC/hug.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/hug.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/hug-cute.gif", "https://media1.tenor.com/m/KkO5IjxVQKMAAAAC/hug.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/hug.gif", "https://media1.tenor.com/m/4yPv5fJiHf4AAAAC/hug.gif", "https://media1.tenor.com/m/2qjVr7KUQKgAAAAC/hug.gif", ]
|
||||
kiss = ["https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/kiss.gif", "https://media1.tenor.com/m/KkO5IjxVQKMAAAAC/kiss.gif", "https://media1.tenor.com/m/4yPv5fJiHf4AAAAC/kiss.gif", "https://media1.tenor.com/m/2qjVr7KUQKgAAAAC/kiss.gif", ]
|
||||
pat = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/head-pat.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/head-pat.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/head-pat.gif", ]
|
||||
wave = ["https://media1.tenor.com/m/a-ooSHLa2lsAAAAC/bye.gif", "https://media1.tenor.com/m/a-ooSHLa2lsAAAAC/bye.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/wave.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/wave.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/wave.gif", ]
|
||||
poke = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/poke.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/poke.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/poke.gif", ]
|
||||
dance = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/dance.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/dance.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/dance.gif", ]
|
||||
cry = ["https://media1.tenor.com/m/2qjVr7KUQKgAAAAC/cry.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/cry.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/cry.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/cry.gif", ]
|
||||
laugh = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/laugh.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/laugh.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/laugh.gif", ]
|
||||
highfive = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/highfive.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/highfive.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/highfive.gif", ]
|
||||
punch = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/punch.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/punch.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/punch.gif", ]
|
||||
blush = ["https://media1.tenor.com/m/EiIiIiIiIiIiIiIi.gif", "https://media1.tenor.com/m/7yTtTtTtTtTtTtTt.gif", "https://media1.tenor.com/m/8v4XfJiHf4AAAAAC/blush.gif", "https://media1.tenor.com/m/9Vj8kHt3n4wAAAAC/blush.gif", "https://media1.tenor.com/m/0qJj8kVb8nQAAAAC/blush.gif", ]
|
||||
class Interactions(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.command(name="slap")
|
||||
async def _slap_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(slap))
|
||||
embed.add_field(name=f"{ctx.author.name} slaps {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="sad")
|
||||
async def _sad_gif(self, ctx, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(sad))
|
||||
embed.add_field(name=f"{ctx.author.name} is Sad", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="hug")
|
||||
async def _hug_gif(self, ctx, member:discord.Member, *reason):
|
||||
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(hug))
|
||||
embed.add_field(name=f"{ctx.author.name} hugs {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="kiss")
|
||||
async def _kiss_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(kiss))
|
||||
embed.add_field(name=f"{ctx.author.name} kisses {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="pat")
|
||||
async def _pat_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(pat))
|
||||
embed.add_field(name=f"{ctx.author.name} pats {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="wave")
|
||||
async def _wave_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(wave))
|
||||
embed.add_field(name=f"{ctx.author.name} waves at {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="poke")
|
||||
async def _poke_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(poke))
|
||||
embed.add_field(name=f"{ctx.author.name} pokes {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="dance")
|
||||
async def _dance_gif(self, ctx, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(dance))
|
||||
embed.add_field(name=f"{ctx.author.name} dances", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="cry")
|
||||
async def _cry_gif(self, ctx, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(cry))
|
||||
embed.add_field(name=f"{ctx.author.name} cries", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="laugh")
|
||||
async def _laugh_gif(self, ctx, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(laugh))
|
||||
embed.add_field(name=f"{ctx.author.name} laughs", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="highfive")
|
||||
async def _highfive_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(highfive))
|
||||
embed.add_field(name=f"{ctx.author.name} highfives {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="punch")
|
||||
async def _punch_gif(self, ctx, member:discord.Member, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(punch))
|
||||
embed.add_field(name=f"{ctx.author.name} punches {member.name}", value=" ".join(reason))
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(name="blush")
|
||||
async def _blush_gif(self, ctx, *reason):
|
||||
embed = discord.Embed()
|
||||
embed.set_image(url=choice(blush))
|
||||
embed.add_field(name=f"{ctx.author.name} blushes", value=" ".join(reason) or "No reason provided")
|
||||
await ctx.reply(embed=embed)
|
||||
|
||||
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Interactions(client))
|
||||
|
||||
Executable
+509
@@ -0,0 +1,509 @@
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
from utils.sql_commands import DatabaseManager
|
||||
from utils.bank_functions import bank_data, update_money
|
||||
from random import choice
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
|
||||
TICKET_TYPES = {
|
||||
"standard": {"price": 500, "weight": 1},
|
||||
"premium": {"price": 2000, "weight": 5},
|
||||
}
|
||||
LOTTERY_INTERVAL_HOURS = 24 # Draw every 24 hours
|
||||
MAX_TICKETS_PER_USER = 10
|
||||
ROLLOVER_BONUS = 500
|
||||
|
||||
|
||||
class Lottery(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
self.db = DatabaseManager()
|
||||
self.lottery_draw.start()
|
||||
|
||||
def cog_unload(self):
|
||||
self.lottery_draw.cancel()
|
||||
|
||||
def get_jackpot(self) -> int:
|
||||
try:
|
||||
result = self.db.fetch_one("SELECT jackpot FROM lottery_state WHERE id = 1")
|
||||
return int(result["jackpot"]) if result else 0
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching jackpot: {e}")
|
||||
return 0
|
||||
|
||||
def set_jackpot(self, amount: int) -> None:
|
||||
try:
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_state SET jackpot = %s WHERE id = 1", (amount,)
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error setting jackpot: {e}")
|
||||
|
||||
def add_to_jackpot(self, amount: int) -> None:
|
||||
try:
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_state SET jackpot = jackpot + %s WHERE id = 1",
|
||||
(amount,),
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error adding to jackpot: {e}")
|
||||
|
||||
def get_last_draw_time(self) -> datetime:
|
||||
try:
|
||||
result = self.db.fetch_one(
|
||||
"SELECT last_draw FROM lottery_draw_time WHERE id = 1"
|
||||
)
|
||||
last_draw = result["last_draw"] if result and result["last_draw"] else None
|
||||
if last_draw is None:
|
||||
# Set to now if missing and update DB
|
||||
now = datetime.utcnow()
|
||||
self.set_last_draw_time(now)
|
||||
return now
|
||||
if isinstance(last_draw, str):
|
||||
try:
|
||||
last_draw = datetime.fromisoformat(last_draw)
|
||||
except Exception:
|
||||
last_draw = datetime.strptime(last_draw, "%Y-%m-%d %H:%M:%S")
|
||||
return last_draw
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching last draw time: {e}")
|
||||
now = datetime.utcnow()
|
||||
self.set_last_draw_time(now)
|
||||
return now
|
||||
|
||||
def set_last_draw_time(self, draw_time: datetime) -> None:
|
||||
try:
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_draw_time SET last_draw = %s WHERE id = 1", (draw_time,)
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error setting last draw time: {e}")
|
||||
|
||||
def notify_lottery_result(self, user_id: int):
|
||||
try:
|
||||
result = self.db.fetch_one(
|
||||
"SELECT * FROM lottery_results WHERE WINNER_ID = %s AND CLAIMED = 0 ORDER BY DRAW_TIME DESC LIMIT 1",
|
||||
(user_id,),
|
||||
)
|
||||
if not result:
|
||||
return None
|
||||
# Remove the result after notifying
|
||||
self.db.execute_query(
|
||||
"DELETE FROM lottery_results WHERE ID = %s", (result["ID"],)
|
||||
)
|
||||
return (True, result["AMOUNT"])
|
||||
except Exception as e:
|
||||
logging.error(f"Error notifying lottery result: {e}")
|
||||
return None
|
||||
|
||||
@commands.command(
|
||||
name="buyticket",
|
||||
help=f"Buy one or more lottery tickets for yourself or a group.",
|
||||
)
|
||||
async def buy_ticket(
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
ticket_type: str = "standard",
|
||||
amount: int = 1,
|
||||
group_id: str | None = None,
|
||||
member: discord.Member | None = None,
|
||||
):
|
||||
ticket_type = ticket_type.lower()
|
||||
if ticket_type not in TICKET_TYPES:
|
||||
await ctx.reply(
|
||||
f"Invalid ticket type. Choose from: {', '.join(TICKET_TYPES)}"
|
||||
)
|
||||
return
|
||||
if amount < 1 or amount > MAX_TICKETS_PER_USER:
|
||||
await ctx.reply(
|
||||
f"You can only buy between 1 and {MAX_TICKETS_PER_USER} tickets at once."
|
||||
)
|
||||
return
|
||||
user = member or ctx.author
|
||||
price = TICKET_TYPES[ticket_type]["price"] * amount
|
||||
try:
|
||||
# Notify about last draw if relevant (only if user is the winner)
|
||||
notify = self.notify_lottery_result(user.id)
|
||||
if notify:
|
||||
await ctx.reply(
|
||||
f"🎉 You won the last lottery! Jackpot: {notify[1]:,} coins.",
|
||||
mention_author=False,
|
||||
)
|
||||
|
||||
user_data = await bank_data(user)
|
||||
wallet = int(user_data.get("WALLET", 0))
|
||||
if wallet < price:
|
||||
await ctx.reply(
|
||||
f"You need at least {price} coins to buy {amount} {ticket_type} ticket(s).",
|
||||
mention_author=False,
|
||||
)
|
||||
return
|
||||
|
||||
if group_id:
|
||||
group_exists = self.db.fetch_one(
|
||||
"SELECT 1 FROM lottery_groups WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
in_group = self.db.fetch_one(
|
||||
"SELECT 1 FROM lottery_group_members WHERE group_id = %s AND user_id = %s",
|
||||
(group_id, user.id),
|
||||
)
|
||||
if not group_exists or not in_group:
|
||||
await ctx.reply(
|
||||
"You must be a member of the group to buy tickets for it."
|
||||
)
|
||||
return
|
||||
|
||||
user_ticket_count = self.db.fetch_one(
|
||||
"SELECT COUNT(*) as count FROM lottery_tickets WHERE USERID = %s",
|
||||
(user.id,),
|
||||
)["count"]
|
||||
if user_ticket_count + amount > MAX_TICKETS_PER_USER:
|
||||
await ctx.reply(
|
||||
f"You can only have {MAX_TICKETS_PER_USER} tickets per draw. You currently have {user_ticket_count}."
|
||||
)
|
||||
return
|
||||
|
||||
# Deduct ticket price
|
||||
await update_money(user, wallet=-price)
|
||||
self.add_to_jackpot(price)
|
||||
|
||||
# Store tickets in DB (one row per ticket for higher odds with multiple tickets)
|
||||
for _ in range(amount):
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_tickets (USERID, TIMESTAMP, TICKET_TYPE, group_id) VALUES (%s, %s, %s, %s)",
|
||||
(user.id, datetime.utcnow(), ticket_type, group_id),
|
||||
)
|
||||
|
||||
jackpot = self.get_jackpot()
|
||||
await ctx.reply(
|
||||
f"🎟️ {amount} {ticket_type.capitalize()} ticket(s) bought! Jackpot is now {jackpot:,} coins.",
|
||||
mention_author=False,
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error in buy_ticket: {e}")
|
||||
await ctx.reply(
|
||||
"An error occurred while buying your ticket(s).", mention_author=False
|
||||
)
|
||||
|
||||
@commands.command(name="lotterystats", help="Show current lottery stats.")
|
||||
async def lottery_stats(self, ctx: commands.Context):
|
||||
try:
|
||||
# Show last winner and their prize
|
||||
last_result = self.db.fetch_one(
|
||||
"SELECT * FROM lottery_results ORDER BY DRAW_TIME DESC LIMIT 1"
|
||||
)
|
||||
winner_text = "No draws yet."
|
||||
if last_result:
|
||||
winner = self.client.get_user(
|
||||
last_result["WINNER_ID"]
|
||||
) or await self.client.fetch_user(last_result["WINNER_ID"])
|
||||
winner_text = f"Last winner: {winner.mention if winner else 'Unknown'} ({last_result['AMOUNT']:,} coins)"
|
||||
|
||||
ticket_count = self.db.fetch_one(
|
||||
"SELECT COUNT(*) as count FROM lottery_tickets"
|
||||
)["count"]
|
||||
jackpot = self.get_jackpot()
|
||||
|
||||
# Check if the user has an unclaimed win
|
||||
unclaimed = self.db.fetch_one(
|
||||
"SELECT * FROM lottery_results WHERE WINNER_ID = %s AND CLAIMED = 0 ORDER BY DRAW_TIME DESC LIMIT 1",
|
||||
(ctx.author.id,),
|
||||
)
|
||||
winner_note = ""
|
||||
if unclaimed:
|
||||
# Mark as claimed and pay out
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_results SET CLAIMED = 1 WHERE ID = %s",
|
||||
(unclaimed["ID"],),
|
||||
)
|
||||
await update_money(ctx.author, wallet=unclaimed["AMOUNT"])
|
||||
winner_note = f"\n🎉 **You have won {unclaimed['AMOUNT']:,} coins! Your prize has been paid out.**"
|
||||
|
||||
await ctx.reply(
|
||||
f"{winner_text}\n"
|
||||
f"🎰 There are currently **{ticket_count}** tickets in the pool.\n"
|
||||
f"💰 Jackpot: **{jackpot:,}** coins.\n"
|
||||
f"Next draw in: {self.time_until_draw()}"
|
||||
f"{winner_note}",
|
||||
mention_author=False,
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error in lottery_stats: {e}")
|
||||
await ctx.reply(
|
||||
"An error occurred while fetching lottery stats.", mention_author=False
|
||||
)
|
||||
|
||||
def time_until_draw(self) -> str:
|
||||
now = datetime.utcnow()
|
||||
last_draw = self.get_last_draw_time()
|
||||
next_draw = last_draw + timedelta(hours=LOTTERY_INTERVAL_HOURS)
|
||||
remaining = next_draw - now
|
||||
if remaining.total_seconds() < 0:
|
||||
return "Drawing soon!"
|
||||
hours, remainder = divmod(int(remaining.total_seconds()), 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
return f"{hours}h {minutes}m {seconds}s"
|
||||
|
||||
@tasks.loop(minutes=1)
|
||||
async def lottery_draw(self):
|
||||
now = datetime.utcnow()
|
||||
last_draw = self.get_last_draw_time()
|
||||
if (now - last_draw).total_seconds() < LOTTERY_INTERVAL_HOURS * 3600:
|
||||
return # Not time yet
|
||||
|
||||
await self._run_lottery_draw()
|
||||
|
||||
@commands.command(name="testdraw", help="Manually trigger the lottery draw.")
|
||||
@commands.is_owner()
|
||||
async def testdraw(self, ctx: commands.Context):
|
||||
await ctx.send("Starting lottery draw...")
|
||||
await self._run_lottery_draw()
|
||||
|
||||
async def _run_lottery_draw(self):
|
||||
try:
|
||||
await self.client.wait_until_ready()
|
||||
tickets = self.db.fetch_all(
|
||||
"SELECT USERID, TICKET_TYPE FROM lottery_tickets"
|
||||
)
|
||||
jackpot = self.get_jackpot()
|
||||
if not tickets or jackpot <= 0:
|
||||
self.set_jackpot(self.get_jackpot() + ROLLOVER_BONUS)
|
||||
self.set_last_draw_time(datetime.utcnow())
|
||||
return
|
||||
|
||||
# Build weighted ticket list
|
||||
weighted_tickets = []
|
||||
for t in tickets:
|
||||
luck_row = self.db.fetch_one(
|
||||
"SELECT LUCK FROM lottery_luck WHERE USERID = %s", (t["USERID"],)
|
||||
)
|
||||
luck = luck_row["LUCK"] if luck_row else 0
|
||||
ticket_type_weight = TICKET_TYPES[t["TICKET_TYPE"]]["weight"]
|
||||
weight = ticket_type_weight * (1 + luck)
|
||||
weighted_tickets.extend([t["USERID"]] * weight)
|
||||
|
||||
winner_id = choice(weighted_tickets)
|
||||
# Find group for winning ticket BEFORE deleting tickets
|
||||
group_id = self.db.fetch_one(
|
||||
"SELECT group_id FROM lottery_tickets WHERE USERID = %s LIMIT 1",
|
||||
(winner_id,),
|
||||
)["group_id"]
|
||||
|
||||
self.db.execute_query("DELETE FROM lottery_tickets") # Reset for next round
|
||||
|
||||
if group_id:
|
||||
members = self.db.fetch_all(
|
||||
"SELECT user_id FROM lottery_group_members WHERE group_id = %s",
|
||||
(group_id,),
|
||||
)
|
||||
member_ids = [m["user_id"] for m in members]
|
||||
split_prize = (jackpot // 2) // len(member_ids)
|
||||
for uid in member_ids:
|
||||
member = self.client.get_user(uid) or await self.client.fetch_user(
|
||||
uid
|
||||
)
|
||||
await update_money(member, wallet=split_prize)
|
||||
# Store group win in results with WIN_TYPE='group'
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_results (WINNER_ID, AMOUNT, DRAW_TIME, CLAIMED, WIN_TYPE) VALUES (%s, %s, %s, 0, %s)",
|
||||
(group_id, jackpot // 2, datetime.utcnow(), "group"),
|
||||
)
|
||||
else:
|
||||
# Store solo win in results with WIN_TYPE='user'
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_results (WINNER_ID, AMOUNT, DRAW_TIME, CLAIMED, WIN_TYPE) VALUES (%s, %s, %s, 0, %s)",
|
||||
(winner_id, jackpot // 2, datetime.utcnow(), "user"),
|
||||
)
|
||||
# Carry over half the jackpot (rounded down)
|
||||
carryover = jackpot // 2
|
||||
self.set_jackpot(carryover)
|
||||
self.set_last_draw_time(datetime.utcnow())
|
||||
|
||||
# Reset winner's luck, increment others'
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_luck SET LUCK = 0 WHERE USERID = %s", (winner_id,)
|
||||
)
|
||||
self.db.execute_query(
|
||||
"UPDATE lottery_luck SET LUCK = LUCK + 1 WHERE USERID != %s",
|
||||
(winner_id,),
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Error in _run_lottery_draw: {e}")
|
||||
|
||||
@lottery_draw.before_loop
|
||||
async def before_lottery_draw(self):
|
||||
await self.client.wait_until_ready()
|
||||
|
||||
@commands.command(name="lotteryhistory")
|
||||
async def lottery_history(self, ctx):
|
||||
results = self.db.fetch_all(
|
||||
"SELECT * FROM lottery_results ORDER BY DRAW_TIME DESC LIMIT 10"
|
||||
)
|
||||
if not results:
|
||||
await ctx.reply("No lottery draws yet.")
|
||||
return
|
||||
lines = []
|
||||
for res in results:
|
||||
if res.get("WIN_TYPE") == "group":
|
||||
lines.append(
|
||||
f"{res['DRAW_TIME'].strftime('%Y-%m-%d')}: Group `{res['WINNER_ID']}` won {res['AMOUNT']:,} coins"
|
||||
)
|
||||
else:
|
||||
winner = self.client.get_user(
|
||||
res["WINNER_ID"]
|
||||
) or await self.client.fetch_user(res["WINNER_ID"])
|
||||
lines.append(
|
||||
f"{res['DRAW_TIME'].strftime('%Y-%m-%d')}: {winner.mention if winner else 'Unknown'} won {res['AMOUNT']:,} coins"
|
||||
)
|
||||
await ctx.reply("\n".join(lines))
|
||||
|
||||
@commands.command(name="lotteryleaderboard")
|
||||
async def lottery_leaderboard(self, ctx):
|
||||
winners = self.db.fetch_all(
|
||||
"SELECT WINNER_ID, COUNT(*) as wins, SUM(AMOUNT) as total FROM lottery_results GROUP BY WINNER_ID ORDER BY wins DESC LIMIT 10"
|
||||
)
|
||||
if not winners:
|
||||
await ctx.reply("No winners yet.")
|
||||
return
|
||||
lines = []
|
||||
for w in winners:
|
||||
user = self.client.get_user(w["WINNER_ID"]) or await self.client.fetch_user(
|
||||
w["WINNER_ID"]
|
||||
)
|
||||
lines.append(
|
||||
f"{user.mention if user else 'Unknown'}: {w['wins']} wins, {w['total']:,} coins"
|
||||
)
|
||||
await ctx.reply("\n".join(lines))
|
||||
|
||||
@commands.command(name="initluck")
|
||||
@commands.is_owner()
|
||||
async def init_luck(self, ctx):
|
||||
"""Initialize or reset the luck of a user."""
|
||||
user = ctx.author
|
||||
self.db.execute_query(
|
||||
"INSERT IGNORE INTO lottery_luck (USERID, LUCK) VALUES (%s, 0)", (user.id,)
|
||||
)
|
||||
await ctx.reply(f"Your luck has been initialized/reset.")
|
||||
|
||||
@commands.command(name="creategroup")
|
||||
async def create_group(self, ctx, group_id: str):
|
||||
exists = self.db.fetch_one(
|
||||
"SELECT 1 FROM lottery_groups WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
if exists:
|
||||
await ctx.reply("A group with that ID already exists.")
|
||||
return
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_groups (group_id, creator_id) VALUES (%s, %s)",
|
||||
(group_id, ctx.author.id),
|
||||
)
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_group_members (group_id, user_id) VALUES (%s, %s)",
|
||||
(group_id, ctx.author.id),
|
||||
)
|
||||
await ctx.reply(f"Group `{group_id}` created and you have joined it.")
|
||||
|
||||
@commands.command(name="joingroup")
|
||||
async def join_group(self, ctx, group_id: str):
|
||||
exists = self.db.fetch_one(
|
||||
"SELECT 1 FROM lottery_groups WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
if not exists:
|
||||
await ctx.reply("That group does not exist.")
|
||||
return
|
||||
already = self.db.fetch_one(
|
||||
"SELECT 1 FROM lottery_group_members WHERE group_id = %s AND user_id = %s",
|
||||
(group_id, ctx.author.id),
|
||||
)
|
||||
if already:
|
||||
await ctx.reply("You are already in this group.")
|
||||
return
|
||||
self.db.execute_query(
|
||||
"INSERT INTO lottery_group_members (group_id, user_id) VALUES (%s, %s)",
|
||||
(group_id, ctx.author.id),
|
||||
)
|
||||
await ctx.reply(f"You have joined group `{group_id}`.")
|
||||
|
||||
@commands.command(name="leavegroup")
|
||||
async def leave_group(self, ctx, group_id: str):
|
||||
self.db.execute_query(
|
||||
"DELETE FROM lottery_group_members WHERE group_id = %s AND user_id = %s",
|
||||
(group_id, ctx.author.id),
|
||||
)
|
||||
await ctx.reply(f"You have left group `{group_id}`.")
|
||||
|
||||
@commands.command(name="deletegroup")
|
||||
async def delete_group(self, ctx, group_id: str):
|
||||
# Check if group exists and if user is creator
|
||||
group = self.db.fetch_one(
|
||||
"SELECT creator_id FROM lottery_groups WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
if not group:
|
||||
await ctx.reply("That group does not exist.")
|
||||
return
|
||||
if group["creator_id"] != ctx.author.id:
|
||||
await ctx.reply("Only the group creator can delete this group.")
|
||||
return
|
||||
# Check if group is empty (no members except possibly the creator)
|
||||
members = self.db.fetch_all(
|
||||
"SELECT user_id FROM lottery_group_members WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
if len(members) > 1 or (
|
||||
len(members) == 1 and members[0]["user_id"] != ctx.author.id
|
||||
):
|
||||
await ctx.reply(
|
||||
"You can only delete a group if it is empty (no members except you)."
|
||||
)
|
||||
return
|
||||
# Delete group and membership
|
||||
self.db.execute_query(
|
||||
"DELETE FROM lottery_group_members WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
self.db.execute_query(
|
||||
"DELETE FROM lottery_groups WHERE group_id = %s", (group_id,)
|
||||
)
|
||||
await ctx.reply(f"Group `{group_id}` has been deleted.")
|
||||
|
||||
@commands.command(name="refundtickets")
|
||||
async def refund_tickets(self, ctx, amount: int = 1):
|
||||
user = ctx.author
|
||||
tickets = self.db.fetch_all(
|
||||
"SELECT * FROM lottery_tickets WHERE USERID = %s", (user.id,)
|
||||
)
|
||||
if not tickets:
|
||||
await ctx.reply("You have no tickets to refund for this draw.")
|
||||
return
|
||||
|
||||
if amount is None:
|
||||
amount = len(tickets)
|
||||
if amount < 1 or amount > len(tickets):
|
||||
await ctx.reply(
|
||||
f"You can only refund between 1 and {len(tickets)} tickets."
|
||||
)
|
||||
return
|
||||
|
||||
# Refund only the specified amount
|
||||
tickets_to_refund = tickets[:amount]
|
||||
total_refund = 0
|
||||
ticket_ids = []
|
||||
for ticket in tickets_to_refund:
|
||||
price = TICKET_TYPES[ticket["TICKET_TYPE"]]["price"]
|
||||
refund = int(price * 0.8)
|
||||
total_refund += refund
|
||||
ticket_ids.append(ticket["ID"])
|
||||
|
||||
# Remove only the refunded tickets
|
||||
format_strings = ",".join(["%s"] * len(ticket_ids))
|
||||
self.db.execute_query(
|
||||
f"DELETE FROM lottery_tickets WHERE ID IN ({format_strings})",
|
||||
tuple(ticket_ids),
|
||||
)
|
||||
await update_money(user, wallet=total_refund)
|
||||
await ctx.reply(
|
||||
f"{amount} ticket(s) refunded for {total_refund:,} coins (80% of purchase price)."
|
||||
)
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Lottery(client))
|
||||
Executable
Executable
+54
@@ -0,0 +1,54 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
class Roles(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.command(name="giveRole")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def _add_role(self, ctx, member: discord.Member, role):
|
||||
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||
await member.add_roles(role)
|
||||
await ctx.reply("role given", delete_after=2)
|
||||
|
||||
@commands.command(name="showRoles")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def _show_role(self, ctx):
|
||||
roles = [role for role in ctx.guild.roles][1:]
|
||||
embed = discord.Embed(
|
||||
colour=discord.Colour.purple(),
|
||||
timestamp=ctx.message.created_at,
|
||||
title=f"Roles",
|
||||
)
|
||||
embed.add_field(
|
||||
name="Roles:", value="\n".join([role.mention for role in roles])
|
||||
)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(name="takeRole")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def _take_role(self, ctx, member: discord.Member, role):
|
||||
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||
await member.remove_roles(role)
|
||||
await ctx.reply("role taken", delete_after=2)
|
||||
|
||||
@commands.command(name="deleteRole")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
async def _delete_role(self, ctx, role_name):
|
||||
role_object = discord.utils.get(ctx.guild.roles, name=role_name)
|
||||
await role_object.delete()
|
||||
|
||||
@commands.command("addRole")
|
||||
@commands.has_permissions(
|
||||
manage_roles=True
|
||||
) # Check if the user executing the command can manage roles
|
||||
async def _create_role(self, ctx, name):
|
||||
guild = ctx.guild
|
||||
await guild.create_role(name=name)
|
||||
await ctx.send(f"Role `{name}` has been created")
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Roles(client))
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
import discord
|
||||
import requests
|
||||
from discord.ext import commands
|
||||
from discord.ui import Select, View
|
||||
from random import shuffle
|
||||
from utils import sql_commands as mydb
|
||||
from utils.bank_functions import *
|
||||
|
||||
class MyView(View):
|
||||
def __init__(self, right: str, wrong: list):
|
||||
super().__init__()
|
||||
self.right = right
|
||||
options = wrong.copy()
|
||||
options.append(right)
|
||||
shuffle(options)
|
||||
|
||||
select = Select(
|
||||
placeholder="Pick an answer:",
|
||||
min_values=1,
|
||||
max_values=1,
|
||||
options=[discord.SelectOption(label=option) for option in options]
|
||||
)
|
||||
|
||||
self.add_item(select)
|
||||
|
||||
select.callback = self.select_callback # Set the callback method
|
||||
|
||||
async def select_callback(self, interaction: discord.Interaction):
|
||||
if interaction.data['values'][0] == self.right: # type: ignore
|
||||
await interaction.response.edit_message(content=f"You are correct!\n{self.right} was the right answer.", view=None)
|
||||
else:
|
||||
await interaction.response.edit_message(content=f"Oh no, that's not right!\n{self.right} was the right answer.", view=None)
|
||||
|
||||
class Test(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.is_owner()
|
||||
@commands.command(name="quiz")
|
||||
async def quiz(self, ctx):
|
||||
response = requests.get("https://opentdb.com/api.php?amount=1&category=18&difficulty=medium&type=multiple").json()["results"][0]
|
||||
question = response["question"]
|
||||
|
||||
view = MyView(response["correct_answer"], response["incorrect_answers"])
|
||||
await ctx.send(question, view=view)
|
||||
|
||||
@commands.is_owner()
|
||||
@commands.command(name="lottery", aliases=["bet" , "lotto"])
|
||||
async def lottery(self, ctx, amount:int=None): #type: ignore
|
||||
if amount == None:
|
||||
await ctx.send(mydb.select("JACKPOT", "global", True, "ID", "1"))
|
||||
return
|
||||
# mydb.select()
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Test(client))
|
||||
Executable
+302
@@ -0,0 +1,302 @@
|
||||
import discord
|
||||
from random import shuffle, choice
|
||||
from discord.ext import commands
|
||||
import utils.sql_commands as mydb
|
||||
|
||||
|
||||
lottery_list = ["🎁", "🎮", "🎷", "🔫", "📸", "🎃", "🏅"]
|
||||
|
||||
lottery_win = {
|
||||
"🎁": 2,
|
||||
"🎁🎁": 5,
|
||||
"🎁🎁🎁": 500,
|
||||
"🔫🔫🔫": 25,
|
||||
"📸📸📸": 50,
|
||||
"🎃🎃🎃": 75,
|
||||
"🏅🏅🏅": 100,
|
||||
"🎮🎮🎮": 250,
|
||||
"🎷🎷🎷": 1000,
|
||||
}
|
||||
|
||||
bj_values = {
|
||||
"2♦️": 2,
|
||||
"2♥️": 2,
|
||||
"2♣️": 2,
|
||||
"2♠️": 2,
|
||||
"3♦️": 3,
|
||||
"3♥️": 3,
|
||||
"3♣️": 3,
|
||||
"3♠️": 3,
|
||||
"4♦️": 4,
|
||||
"4♥️": 4,
|
||||
"4♣️": 4,
|
||||
"4♠️": 4,
|
||||
"5♦️": 5,
|
||||
"5♥️": 5,
|
||||
"5♣️": 5,
|
||||
"5♠️": 5,
|
||||
"6♦️": 6,
|
||||
"6♥️": 6,
|
||||
"6♣️": 6,
|
||||
"6♠️": 6,
|
||||
"7♦️": 7,
|
||||
"7♥️": 7,
|
||||
"7♣️": 7,
|
||||
"7♠️": 7,
|
||||
"8♦️": 8,
|
||||
"8♥️": 8,
|
||||
"8♣️": 8,
|
||||
"8♠️": 8,
|
||||
"9♦️": 9,
|
||||
"9♥️": 9,
|
||||
"9♣️": 9,
|
||||
"9♠️": 9,
|
||||
"10♦️": 10,
|
||||
"10♥️": 10,
|
||||
"10♣️": 10,
|
||||
"10♠️": 10,
|
||||
"J♦️": 10,
|
||||
"J♥️": 10,
|
||||
"J♣️": 10,
|
||||
"J♠️": 10,
|
||||
"Q♦️": 10,
|
||||
"Q♥️": 10,
|
||||
"Q♣️": 10,
|
||||
"Q♠️": 10,
|
||||
"K♦️": 10,
|
||||
"K♥️": 10,
|
||||
"K♣️": 10,
|
||||
"K♠️": 10,
|
||||
"A♦️": 11,
|
||||
"A♥️": 11,
|
||||
"A♣️": 11,
|
||||
"A♠️": 11,
|
||||
}
|
||||
|
||||
|
||||
class Deck:
|
||||
def __init__(self):
|
||||
self.deck = list(bj_values.keys())
|
||||
shuffle(self.deck)
|
||||
|
||||
async def deal(self):
|
||||
return self.deck.pop()
|
||||
|
||||
|
||||
class Hand:
|
||||
def __init__(self, name, bet):
|
||||
self.cards = []
|
||||
self.value = 0
|
||||
self.aces = 0
|
||||
self.bust = False
|
||||
self.name = name
|
||||
self.bet = bet
|
||||
|
||||
async def win_bet(self):
|
||||
pass
|
||||
|
||||
async def lose_bet(self):
|
||||
pass
|
||||
|
||||
async def add_card(self, card):
|
||||
self.cards.append(card)
|
||||
self.aces = ("".join(self.cards)).count("A")
|
||||
value = 0
|
||||
for card in self.cards:
|
||||
value += bj_values[card]
|
||||
self.value = value
|
||||
while self.value > 21 and self.aces:
|
||||
self.value -= 10
|
||||
self.aces -= 1
|
||||
|
||||
|
||||
async def hit(deck, hand):
|
||||
await hand.add_card(await deck.deal())
|
||||
|
||||
|
||||
async def double(deck, hand):
|
||||
pass
|
||||
|
||||
|
||||
async def split(deck, hands):
|
||||
pass
|
||||
|
||||
|
||||
async def payout(ctx, play, amount, multiplier):
|
||||
await ctx.reply(
|
||||
f"{play}\nBet: {amount:,}\nYou won {amount * multiplier:,} Flooneys"
|
||||
)
|
||||
|
||||
|
||||
async def check_winner(msg: discord.Interaction, player_hand, dealer_hand):
|
||||
p_value, d_value = player_hand.value, dealer_hand.value
|
||||
embed = discord.Embed(description="Blackjack")
|
||||
embed.add_field(name="Bet: ", value="amount", inline=True)
|
||||
embed.add_field(
|
||||
name=player_hand.name,
|
||||
value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name=dealer_hand.name,
|
||||
value=f"{', '.join(dealer_hand.cards)}: {dealer_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
|
||||
if (p_value > d_value and not player_hand.bust) or dealer_hand.bust:
|
||||
embed.add_field(name="Winner:", value=f"{player_hand.name}", inline=False)
|
||||
player_balance = int(mydb.select("WALLET", "economy", True, "ID", player_hand.name.id).get("WALLET", None))
|
||||
mydb.add("economy", "ID", "WALLET", player_hand.name.id, player_balance + player_hand.bet*2, True)
|
||||
elif p_value < d_value and dealer_hand.bust:
|
||||
embed.add_field(name="Winner:", value=f"{dealer_hand.name}", inline=False)
|
||||
else:
|
||||
embed.add_field(name="Winner:", value=f"Draw", inline=False)
|
||||
await msg.edit_original_response(embed=embed)
|
||||
|
||||
|
||||
async def dealer(msg: discord.Interaction, player_hand, dealer_hand, cards):
|
||||
while dealer_hand.value < 17 and not player_hand.bust and not dealer_hand.bust:
|
||||
await hit(cards, dealer_hand)
|
||||
if dealer_hand.value > 21:
|
||||
dealer_hand.bust = True
|
||||
embed = discord.Embed(description="Blackjack")
|
||||
embed.add_field(name="Bet: ", value="amount", inline=True)
|
||||
embed.add_field(
|
||||
name=player_hand.name,
|
||||
value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name=dealer_hand.name,
|
||||
value=f"{', '.join(dealer_hand.cards)}: {dealer_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
await msg.edit_original_response(embed=embed)
|
||||
await check_winner(msg, player_hand, dealer_hand)
|
||||
|
||||
|
||||
class MyView(discord.ui.View):
|
||||
def __init__(self, player_hand, dealer_hand, cards):
|
||||
super().__init__()
|
||||
self.player_hand = player_hand
|
||||
self.dealer_hand = dealer_hand
|
||||
self.cards = cards
|
||||
|
||||
@discord.ui.button(label="Hit", style=discord.ButtonStyle.primary, emoji="✅")
|
||||
async def hit(self, interaction: discord.Interaction, button: discord.ui.Button):
|
||||
await hit(self.cards, self.player_hand)
|
||||
embed = discord.Embed(description="Blackjack")
|
||||
embed.add_field(name="Bet: ", value="amount", inline=True)
|
||||
embed.add_field(
|
||||
name=self.player_hand.name,
|
||||
value=f"{', '.join(self.player_hand.cards)}: {self.player_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name=self.dealer_hand.name,
|
||||
value=f"{(self.dealer_hand.cards)[0]}",
|
||||
inline=False,
|
||||
)
|
||||
msg = interaction
|
||||
if self.player_hand.value < 21:
|
||||
await msg.response.edit_message(embed=embed)
|
||||
else:
|
||||
await msg.response.edit_message(embed=embed, view=None)
|
||||
if self.player_hand.value > 21:
|
||||
self.player_hand.bust = True
|
||||
await dealer(msg, self.player_hand, self.dealer_hand, self.cards)
|
||||
|
||||
@discord.ui.button(label="Stand", style=discord.ButtonStyle.secondary, emoji="🛑")
|
||||
async def stand(self, interaction: discord.Interaction, button: discord.ui.Button):
|
||||
embed = discord.Embed(description="Blackjack")
|
||||
embed.add_field(name="Bet: ", value=self.player_hand.bet, inline=True)
|
||||
embed.add_field(
|
||||
name=self.player_hand.name,
|
||||
value=f"{', '.join(self.player_hand.cards)}: {self.player_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name=self.dealer_hand.name,
|
||||
value=f"{(self.dealer_hand.cards)[0]}",
|
||||
inline=False,
|
||||
)
|
||||
msg = interaction
|
||||
await msg.response.edit_message(embed=embed, view=None)
|
||||
await dealer(msg, self.player_hand, self.dealer_hand, self.cards)
|
||||
|
||||
|
||||
class Gamble(commands.Cog):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
@commands.command()
|
||||
async def blackjack(self, ctx, bet):
|
||||
amount = int(bet)
|
||||
|
||||
cards = Deck()
|
||||
player_balance = int(mydb.select("WALLET", "economy", True, "ID", ctx.author.id).get(
|
||||
"WALLET", None
|
||||
)
|
||||
)
|
||||
if player_balance < bet or bet < 0:
|
||||
await ctx.reply("You have insufficient funds.")
|
||||
return
|
||||
mydb.add("economy", "ID", "WALLET", ctx.author.id, player_balance - bet, True)
|
||||
player_hand, dealer_hand = Hand(ctx.author, amount), Hand("Dealer", None)
|
||||
|
||||
# setup
|
||||
for _ in range(2):
|
||||
await player_hand.add_card(await cards.deal())
|
||||
await dealer_hand.add_card(await cards.deal())
|
||||
|
||||
embed = discord.Embed(description="Blackjack")
|
||||
embed.add_field(name="Bet: ", value=amount, inline=True)
|
||||
embed.add_field(
|
||||
name=ctx.author,
|
||||
value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(name="Dealer", value=f"{(dealer_hand.cards)[0]}", inline=False)
|
||||
|
||||
view = MyView(player_hand, dealer_hand, cards)
|
||||
await ctx.send(embed=embed, view=view)
|
||||
|
||||
@commands.command()
|
||||
async def show_buttons(self, ctx):
|
||||
await ctx.reply(
|
||||
"This is a button!", view=MyView(None, None, None)
|
||||
) # Send a message with our View class that contains the button
|
||||
|
||||
|
||||
@commands.cooldown(1, 1, commands.BucketType.user)
|
||||
@commands.command(name="lottery", aliases=["slots"])
|
||||
async def lottery(self, ctx, bet: int):
|
||||
player_balance = int(
|
||||
mydb.select("WALLET", "economy", True, "ID", ctx.author.id).get(
|
||||
"WALLET", None
|
||||
)
|
||||
)
|
||||
if player_balance < bet or bet < 0:
|
||||
await ctx.reply("You have insufficient funds.")
|
||||
return
|
||||
play = "".join([choice(lottery_list) for _ in range(3)])
|
||||
|
||||
if play in lottery_win:
|
||||
mult = lottery_win[play]
|
||||
await payout(ctx, play, bet, mult)
|
||||
|
||||
elif play.count("🎁") == 2:
|
||||
mult = lottery_win["🎁🎁"]
|
||||
await payout(ctx, play, bet, mult)
|
||||
|
||||
elif play.count("🎁") == 1:
|
||||
mult = lottery_win["🎁"]
|
||||
await payout(ctx, play, bet, mult)
|
||||
|
||||
else:
|
||||
mydb.add("economy", "ID", "WALLET", ctx.author.id, player_balance - bet, True)
|
||||
await ctx.reply(f"{play}\nYou lost {int(bet):,} Flooneys")
|
||||
|
||||
|
||||
async def setup(client):
|
||||
await client.add_cog(Gamble(client))
|
||||
Reference in New Issue
Block a user