discord-guess-img-bot/cogs/lottery.py

195 lines
9.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import discord
import random
import json
import asyncio
import datetime
from dotenv import load_dotenv
from discord.ext import commands
from discord import app_commands
from discord import FFmpegPCMAudio
# 載入 .env 檔案
load_dotenv()
# 從環境變數讀取 Guild ID 並轉型為 int
MY_GUILD_ID = int(os.getenv('GUILD_ID'))
class Lottery(commands.Cog):
def __init__(self, bot):
self.bot = bot
with open('./pokemon.json', mode='r', encoding='utf8') as jFile:
self.pokeData = json.load(jFile)
with open('./animate.json', mode='r', encoding='utf8') as jFile:
self.aniData = json.load(jFile)
self.getPokeCount = 0
self.getAniCount = 0
self.pokeList = random.sample(range(0, len(self.pokeData)), len(self.pokeData))
self.aniList = random.sample(range(0, len(self.aniData)), len(self.aniData))
self.stop = False
# --- 建立抽選清單 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="建立抽選清單", description="建立寶可夢或動畫角色的抽選清單")
@app_commands.choices(list_name=[
app_commands.Choice(name="寶可夢", value="寶可夢"),
app_commands.Choice(name="動畫角色", value="動畫角色"),
app_commands.Choice(name="全部", value="全部")
])
async def create_list(self, interaction: discord.Interaction, list_name: app_commands.Choice[str]):
if list_name.value == "寶可夢":
self.pokeList = random.sample(range(0, len(self.pokeData)), len(self.pokeData))
self.getPokeCount = 0
msg = "已建立寶可夢抽選清單!"
elif list_name.value == "動畫角色":
self.aniList = random.sample(range(0, len(self.aniData)), len(self.aniData))
self.getAniCount = 0
msg = "已建立動畫角色抽選清單!"
else:
self.pokeList = random.sample(range(0, len(self.pokeData)), len(self.pokeData))
self.aniList = random.sample(range(0, len(self.aniData)), len(self.aniData))
self.getPokeCount = 0
self.getAniCount = 0
msg = "已建立全部抽選清單!"
await interaction.response.send_message(msg, ephemeral=True)
# --- 顯示清單狀態 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="抽選清單", description="檢視所有抽選清單及目前抽選狀態")
async def show_list(self, interaction: discord.Interaction):
pokeCount = self.getPokeCount + 1
aniCount = self.getAniCount + 1
await interaction.response.send_message(
f'寶可夢清單:共{len(self.pokeData)}個,正準備抽選第 {pokeCount}\n'
f'動畫角色清單:共{len(self.aniData)}個,正準備抽選第 {aniCount}'
)
# --- 抽寶可夢 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="抽寶可夢", description="顯示題目,並於指定秒數後公布答案圖片")
@app_commands.describe(t="倒數秒數需大於5")
async def get_poke(self, interaction: discord.Interaction, t: int):
if t < 5:
await interaction.response.send_message("秒數需大於5秒", ephemeral=True)
return
if self.getPokeCount >= len(self.pokeData):
await interaction.response.send_message("清單已抽取完畢,請重新建立抽選清單", ephemeral=True)
return
if interaction.user.voice and interaction.user.voice.channel:
vc = interaction.guild.voice_client or await interaction.user.voice.channel.connect()
idx = self.pokeList[self.getPokeCount]
poke = self.pokeData[idx]
self.getPokeCount += 1
await interaction.response.send_message(f'{self.getPokeCount}\n{poke["name"]} \n倒數 {t} 秒,開始!')
await asyncio.sleep(t - 5)
if not vc.is_playing():
vc.play(FFmpegPCMAudio('countdown.wav'))
await asyncio.sleep(5)
await interaction.followup.send("時間到!")
embed = discord.Embed(title="抽選寶可夢", timestamp=datetime.datetime.now(), color=0x34f4b4)
embed.add_field(name="編號:", value=poke["number"], inline=True)
embed.add_field(name="名稱:", value=poke["name"], inline=True)
embed.set_image(url=poke["url"])
await interaction.followup.send(embed=embed)
await vc.disconnect()
else:
await interaction.response.send_message("請先加入語音頻道", ephemeral=True)
# --- 抽動畫角色 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="抽動畫角色", description="顯示題目,並於指定秒數後公布答案圖片")
@app_commands.describe(t="倒數秒數需大於5")
async def get_ani(self, interaction: discord.Interaction, t: int):
if t < 5:
await interaction.response.send_message("秒數需大於5秒", ephemeral=True)
return
if self.getAniCount >= len(self.aniData):
await interaction.response.send_message("清單已抽取完畢,請重新建立抽選清單", ephemeral=True)
return
if interaction.user.voice and interaction.user.voice.channel:
vc = interaction.guild.voice_client or await interaction.user.voice.channel.connect()
idx = self.aniList[self.getAniCount]
ani = self.aniData[idx]
self.getAniCount += 1
await interaction.response.send_message(f'{self.getAniCount}\n{ani["animate"]}{ani["character"]}\n倒數 {t} 秒,開始!')
await asyncio.sleep(t - 5)
if not vc.is_playing():
vc.play(FFmpegPCMAudio('countdown.wav'))
await asyncio.sleep(5)
await interaction.followup.send("時間到!")
embed = discord.Embed(title=f'{self.getAniCount} 抽角色', timestamp=datetime.datetime.now(), color=0x34f4b4)
embed.add_field(name="動畫:", value=ani["animate"], inline=True)
embed.add_field(name="角色:", value=ani["character"], inline=True)
embed.set_image(url=ani["url"])
await interaction.followup.send(embed=embed)
await vc.disconnect()
else:
await interaction.response.send_message("請先加入語音頻道", ephemeral=True)
# --- 新增:動畫角色單一複習 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="動畫角色複習", description="顯示指定編號的角色")
@app_commands.describe(num="想要查看的角色編號 (從 1 開始)")
async def check_ani(self, interaction: discord.Interaction, num: int = 1):
if num <= 0 or num > len(self.aniData):
await interaction.response.send_message(f'超過範圍 1~{len(self.aniData)}', ephemeral=True)
return
ani = self.aniData[num - 1]
embed = discord.Embed(title=f'{num} 號角色', timestamp=datetime.datetime.now(), color=0x34f4b4)
embed.add_field(name="動畫:", value=ani["animate"], inline=True)
embed.add_field(name="角色:", value=ani["character"], inline=True)
embed.set_image(url=ani["url"])
await interaction.response.send_message(embed=embed)
# --- 新增:動畫角色總複習 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="動畫角色總複習", description="每 1 秒顯示一位動畫角色,直到結束")
async def check_all_ani(self, interaction: discord.Interaction):
self.stop = False
await interaction.response.send_message("動畫角色總複習開始,如需停止請輸入 /停止", ephemeral=True)
current_idx = 0
while current_idx < len(self.aniData):
if self.stop:
await interaction.followup.send("複習已由指令中止。")
return
ani = self.aniData[current_idx]
current_idx += 1
embed = discord.Embed(title=f'總複習:第 {current_idx} 號角色', timestamp=datetime.datetime.now(), color=0x34f4b4)
embed.add_field(name="動畫:", value=ani["animate"], inline=True)
embed.add_field(name="角色:", value=ani["character"], inline=True)
embed.set_image(url=ani["url"])
await interaction.followup.send(embed=embed)
await asyncio.sleep(1)
await interaction.followup.send("複習完畢!")
# --- 停止複習 ---
@app_commands.guilds(discord.Object(id=MY_GUILD_ID))
@app_commands.command(name="停止", description="停止顯示總複習清單")
async def stop_check_all_ani(self, interaction: discord.Interaction):
self.stop = True
await interaction.response.send_message("已接收停止指令", ephemeral=True)
# Discord.py 2.0+ 的 setup 寫法
async def setup(bot):
await bot.add_cog(Lottery(bot))