mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-05-18 19:32:29 +12:00
inital release of sfx cog
This commit is contained in:
parent
37adcf10ad
commit
d81d5e5ef7
|
@ -391,8 +391,7 @@ class RoleManagement(
|
||||||
Roles with spaces in the name should be put in quotes
|
Roles with spaces in the name should be put in quotes
|
||||||
"""
|
"""
|
||||||
current = await self.config.role(add_role).add_with()
|
current = await self.config.role(add_role).add_with()
|
||||||
current = [discord.utils.get(ctx.guild.roles, id=r)
|
current = [discord.utils.get(ctx.guild.roles, id=r) for r in current]
|
||||||
for r in current]
|
|
||||||
|
|
||||||
await self.config.role(add_role).add_with.set([r.id for r in roles])
|
await self.config.role(add_role).add_with.set([r.id for r in roles])
|
||||||
|
|
||||||
|
@ -401,8 +400,9 @@ class RoleManagement(
|
||||||
elif not roles and not current:
|
elif not roles and not current:
|
||||||
await ctx.send("No roles originally defined.")
|
await ctx.send("No roles originally defined.")
|
||||||
else:
|
else:
|
||||||
await ctx.send(f"Add with roles set to `{humanize_list([r.name for r in roles])}` from `{humanize_list(current) if current else None}`")
|
await ctx.send(
|
||||||
|
f"Add with roles set to `{humanize_list([r.name for r in roles])}` from `{humanize_list(current) if current else None}`"
|
||||||
|
)
|
||||||
|
|
||||||
@rgroup.command(name="viewreactions")
|
@rgroup.command(name="viewreactions")
|
||||||
async def rg_view_reactions(self, ctx: GuildContext):
|
async def rg_view_reactions(self, ctx: GuildContext):
|
||||||
|
|
5
sfx/__init__.py
Normal file
5
sfx/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from .sfx import SFX
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(SFX(bot))
|
15
sfx/info.json
Normal file
15
sfx/info.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"author": [
|
||||||
|
"Brandons209"
|
||||||
|
],
|
||||||
|
"install_msg": "Thanks for install.",
|
||||||
|
"short": "Play sound effects!",
|
||||||
|
"description": "Play sound effects, either via links or files. Integrates with economy and cost manager cog.",
|
||||||
|
"min_bot_version": "3.5.0",
|
||||||
|
"requirements": ["tabulate"],
|
||||||
|
"tags": [
|
||||||
|
"sfx",
|
||||||
|
"saysound",
|
||||||
|
"audio"
|
||||||
|
]
|
||||||
|
}
|
210
sfx/injection.py
Normal file
210
sfx/injection.py
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
#### INJECTED BY SFX COG ####
|
||||||
|
async def sfx_play(self, ctx: commands.Context, query: str, volume = 100):
|
||||||
|
### From play command, process query and check if can play in this context ###
|
||||||
|
query = Query.process_input(query, self.local_folder_current_path)
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
if not self._player_check(ctx):
|
||||||
|
if self.lavalink_connection_aborted:
|
||||||
|
msg = _("Connection to Lavalink has failed")
|
||||||
|
desc = EmptyEmbed
|
||||||
|
if await self.bot.is_owner(ctx.author):
|
||||||
|
desc = _("Please check your console or logs for details.")
|
||||||
|
return await self.send_embed_msg(ctx, title=msg, description=desc)
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
not ctx.author.voice.channel.permissions_for(ctx.me).connect
|
||||||
|
or not ctx.author.voice.channel.permissions_for(ctx.me).move_members
|
||||||
|
and self.is_vc_full(ctx.author.voice.channel)
|
||||||
|
):
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable To Play Tracks"),
|
||||||
|
description=_("I don't have permission to connect to your channel."),
|
||||||
|
)
|
||||||
|
await lavalink.connect(ctx.author.voice.channel)
|
||||||
|
player = lavalink.get_player(ctx.guild.id)
|
||||||
|
player.store("connect", datetime.datetime.utcnow())
|
||||||
|
except AttributeError:
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable To Play Tracks"),
|
||||||
|
description=_("Connect to a voice channel first."),
|
||||||
|
)
|
||||||
|
except IndexError:
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable To Play Tracks"),
|
||||||
|
description=_("Connection to Lavalink has not yet been established."),
|
||||||
|
)
|
||||||
|
|
||||||
|
### PLAYER SETTINGS ###
|
||||||
|
player = lavalink.get_player(ctx.guild.id)
|
||||||
|
|
||||||
|
player.store("channel", ctx.channel.id)
|
||||||
|
player.store("guild", ctx.guild.id)
|
||||||
|
await self._eq_check(ctx, player)
|
||||||
|
|
||||||
|
player.repeat = False
|
||||||
|
player.shuffle = False
|
||||||
|
player.shuffle_bumped = True
|
||||||
|
if player.volume != volume:
|
||||||
|
await player.set_volume(volume)
|
||||||
|
|
||||||
|
if len(player.queue) >= 10000:
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx, title=_("Unable To Play Tracks"), description=_("Queue size limit reached.")
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.sfx_enqueue_tracks(ctx, query)
|
||||||
|
except QueryUnauthorized as err:
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx, title=_("Unable To Play Tracks"), description=err.message
|
||||||
|
)
|
||||||
|
|
||||||
|
async def sfx_enqueue_tracks(
|
||||||
|
self, ctx: commands.Context, query: Query, enqueue: bool = True
|
||||||
|
) -> Union[discord.Message, List[lavalink.Track], lavalink.Track]:
|
||||||
|
player = lavalink.get_player(ctx.guild.id)
|
||||||
|
try:
|
||||||
|
if self.play_lock[ctx.message.guild.id]:
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable To Get Tracks"),
|
||||||
|
description=_("Wait until the playlist has finished loading."),
|
||||||
|
)
|
||||||
|
except KeyError:
|
||||||
|
self.update_player_lock(ctx, True)
|
||||||
|
guild_data = await self.config.guild(ctx.guild).all()
|
||||||
|
first_track_only = False
|
||||||
|
single_track = None
|
||||||
|
index = None
|
||||||
|
playlist_data = None
|
||||||
|
playlist_url = None
|
||||||
|
seek = 0
|
||||||
|
|
||||||
|
if not await self.is_query_allowed(
|
||||||
|
self.config, ctx.guild, f"{query}", query_obj=query
|
||||||
|
):
|
||||||
|
raise QueryUnauthorized(
|
||||||
|
_("{query} is not an allowed query.").format(query=query.to_string_user())
|
||||||
|
)
|
||||||
|
if query.single_track:
|
||||||
|
first_track_only = True
|
||||||
|
index = query.track_index
|
||||||
|
if query.start_time:
|
||||||
|
seek = query.start_time
|
||||||
|
try:
|
||||||
|
result, called_api = await self.api_interface.fetch_track(ctx, player, query)
|
||||||
|
except TrackEnqueueError:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable to Get Track"),
|
||||||
|
description=_(
|
||||||
|
"I'm unable get a track from Lavalink at the moment, "
|
||||||
|
"try again in a few minutes."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
tracks = result.tracks
|
||||||
|
playlist_data = result.playlist_info
|
||||||
|
if not enqueue:
|
||||||
|
return tracks
|
||||||
|
if not tracks:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
title = _("Nothing found.")
|
||||||
|
embed = discord.Embed(title=title)
|
||||||
|
if result.exception_message:
|
||||||
|
if "Status Code" in result.exception_message:
|
||||||
|
embed.set_footer(text=result.exception_message[:2000])
|
||||||
|
else:
|
||||||
|
embed.set_footer(text=result.exception_message[:2000].replace("\n", ""))
|
||||||
|
if await self.config.use_external_lavalink() and query.is_local:
|
||||||
|
embed.description = _(
|
||||||
|
"Local tracks will not work "
|
||||||
|
"if the `Lavalink.jar` cannot see the track.\n"
|
||||||
|
"This may be due to permissions or because Lavalink.jar is being run "
|
||||||
|
"in a different machine than the local tracks."
|
||||||
|
)
|
||||||
|
elif query.is_local and query.suffix in _PARTIALLY_SUPPORTED_MUSIC_EXT:
|
||||||
|
title = _("Track is not playable.")
|
||||||
|
embed = discord.Embed(title=title)
|
||||||
|
embed.description = _(
|
||||||
|
"**{suffix}** is not a fully supported format and some "
|
||||||
|
"tracks may not play."
|
||||||
|
).format(suffix=query.suffix)
|
||||||
|
return await self.send_embed_msg(ctx, embed=embed)
|
||||||
|
|
||||||
|
queue_dur = await self.queue_duration(ctx)
|
||||||
|
queue_total_duration = self.format_time(queue_dur)
|
||||||
|
before_queue_length = len(player.queue)
|
||||||
|
|
||||||
|
|
||||||
|
single_track = None
|
||||||
|
# a ytsearch: prefixed item where we only need the first Track returned
|
||||||
|
# this is in the case of [p]play <query>, a single Spotify url/code
|
||||||
|
# or this is a localtrack item
|
||||||
|
try:
|
||||||
|
if len(player.queue) >= 10000:
|
||||||
|
return await self.send_embed_msg(ctx, title=_("Queue size limit reached."))
|
||||||
|
|
||||||
|
single_track = (
|
||||||
|
tracks
|
||||||
|
if isinstance(tracks, lavalink.rest_api.Track)
|
||||||
|
else tracks[index]
|
||||||
|
if index
|
||||||
|
else tracks[0]
|
||||||
|
)
|
||||||
|
if seek and seek > 0:
|
||||||
|
single_track.start_timestamp = seek * 1000
|
||||||
|
if not await self.is_query_allowed(
|
||||||
|
self.config,
|
||||||
|
ctx.guild,
|
||||||
|
(
|
||||||
|
f"{single_track.title} {single_track.author} {single_track.uri} "
|
||||||
|
f"{str(Query.process_input(single_track, self.local_folder_current_path))}"
|
||||||
|
),
|
||||||
|
):
|
||||||
|
if IS_DEBUG:
|
||||||
|
log.debug(f"Query is not allowed in {ctx.guild} ({ctx.guild.id})")
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx, title=_("This track is not allowed in this server.")
|
||||||
|
)
|
||||||
|
elif guild_data["maxlength"] > 0:
|
||||||
|
if self.is_track_too_long(single_track, guild_data["maxlength"]):
|
||||||
|
player.add(ctx.author, single_track)
|
||||||
|
player.maybe_shuffle()
|
||||||
|
self.bot.dispatch(
|
||||||
|
"red_audio_track_enqueue",
|
||||||
|
player.channel.guild,
|
||||||
|
single_track,
|
||||||
|
ctx.author,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx, title=_("Track exceeds maximum length.")
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
player.add(ctx.author, single_track)
|
||||||
|
player.maybe_shuffle()
|
||||||
|
self.bot.dispatch(
|
||||||
|
"red_audio_track_enqueue", player.channel.guild, single_track, ctx.author
|
||||||
|
)
|
||||||
|
except IndexError:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
title = _("Nothing found")
|
||||||
|
desc = EmptyEmbed
|
||||||
|
if await self.bot.is_owner(ctx.author):
|
||||||
|
desc = _("Please check your console or logs for details.")
|
||||||
|
return await self.send_embed_msg(ctx, title=title, description=desc)
|
||||||
|
|
||||||
|
if not player.current:
|
||||||
|
await player.play()
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return single_track or message
|
||||||
|
|
||||||
|
### END INJECTION BY SFX ###
|
290
sfx/sfx.py
Normal file
290
sfx/sfx.py
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
from redbot.core.utils.chat_formatting import *
|
||||||
|
from redbot.core import Config, checks, commands, bank
|
||||||
|
from redbot.core.data_manager import cog_data_path
|
||||||
|
import discord
|
||||||
|
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import asyncio
|
||||||
|
from difflib import get_close_matches
|
||||||
|
import tabulate
|
||||||
|
|
||||||
|
from .utils import saysound, code_path
|
||||||
|
|
||||||
|
EXT = ("mp3", "flac", "ogg", "wav")
|
||||||
|
|
||||||
|
|
||||||
|
class SFX(commands.Cog):
|
||||||
|
""" Play saysounds in VC's in your guild
|
||||||
|
Supports costs, files, and links.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
self.config = Config.get_conf(self, identifier=8495126065166516132, force_registration=True)
|
||||||
|
|
||||||
|
# saysounds maps saysound name (str) -> saysound data (dict)
|
||||||
|
default_guild = {"saysounds": {}, "FREE_ROLES": []}
|
||||||
|
default_global = {"attachments": True}
|
||||||
|
|
||||||
|
self.config.register_guild(**default_guild)
|
||||||
|
self.config.register_global(**default_global)
|
||||||
|
|
||||||
|
global PATH
|
||||||
|
global AUDIO_CODE_PATH
|
||||||
|
PATH = str(cog_data_path(cog_instance=self))
|
||||||
|
audio_cog = bot.get_cog("Audio")
|
||||||
|
if audio_cog:
|
||||||
|
AUDIO_CODE_PATH = str(code_path(cog_instance=audio_cog))
|
||||||
|
else:
|
||||||
|
AUDIO_CODE_PATH = None
|
||||||
|
|
||||||
|
# integrates cost manager free roles!
|
||||||
|
# if cost_manager isn't loaded, use this cog's free roles
|
||||||
|
async def get_cost(self, member: discord.Member, sound: dict):
|
||||||
|
cost = sound["cost"]
|
||||||
|
cost_manager = self.bot.get_cog("CostManager")
|
||||||
|
|
||||||
|
if cost_manager:
|
||||||
|
free_roles = await cost_manager.config.guild(member.guild).FREE_ROLES()
|
||||||
|
else:
|
||||||
|
free_roles = await self.config.guild(member.guild).FREE_ROLES()
|
||||||
|
|
||||||
|
member_roles = {r.id for r in member.roles if r.name != "@everyone"}
|
||||||
|
found_roles = set(free_roles) & member_roles
|
||||||
|
if found_roles:
|
||||||
|
cost = 0
|
||||||
|
|
||||||
|
return cost
|
||||||
|
|
||||||
|
# plays sound in vc of author
|
||||||
|
async def play(self, ctx, sound: dict):
|
||||||
|
audio_cog = self.bot.get_cog("Audio")
|
||||||
|
if not audio_cog:
|
||||||
|
await ctx.send(error("Unable to load audio cog, please contact bot owner!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
query = sound["url"] if sound["url"] else sound["filepath"]
|
||||||
|
await audio_cog.sfx_play(ctx, query, volume=sound["volume"])
|
||||||
|
except Exception as e:
|
||||||
|
await ctx.send(error("Unable to play sound, please contact bot owner!"))
|
||||||
|
print(e) # TODO add logging properly
|
||||||
|
|
||||||
|
@commands.group()
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
async def sfxset(self, ctx):
|
||||||
|
"""
|
||||||
|
Manage settings for saysounds
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@sfxset.command(name="add")
|
||||||
|
@commands.guild_only()
|
||||||
|
async def sfxset_add(self, ctx, cost: int, vol: int, *, name: str):
|
||||||
|
"""
|
||||||
|
Add an sfx sound for the guild.
|
||||||
|
|
||||||
|
Attach the audio file to the message.
|
||||||
|
"""
|
||||||
|
can_use = await self.config.attachments()
|
||||||
|
|
||||||
|
if not can_use:
|
||||||
|
await ctx.send(error("Sorry, I only allow adding say sounds using URLs."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(ctx.message.attachments) < 1:
|
||||||
|
await ctx.send(error("Please provide an attachment."))
|
||||||
|
return
|
||||||
|
|
||||||
|
file = ctx.message.attachments[0]
|
||||||
|
ext = file.filename.split(".")[-1]
|
||||||
|
|
||||||
|
if ext not in EXT:
|
||||||
|
await ctx.send(error("Audio file must one of `mp3, wav, flac, or ogg` formats."))
|
||||||
|
return
|
||||||
|
|
||||||
|
save_path = os.path.join(PATH, str(ctx.guild.id))
|
||||||
|
if not os.path.exists(save_path):
|
||||||
|
os.makedirs(save_path)
|
||||||
|
|
||||||
|
save_path = os.path.join(save_path, file.filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await file.save(save_path)
|
||||||
|
except:
|
||||||
|
await ctx.send(error("Error saving file, please try again."))
|
||||||
|
return
|
||||||
|
|
||||||
|
async with self.config.guild(ctx.guild).saysounds() as saysounds:
|
||||||
|
author = f"{ctx.author} id: {ctx.author.id}"
|
||||||
|
new_sound = saysound(name, author, cost=cost, volume=vol, filepath=save_path)
|
||||||
|
saysounds[name] = new_sound
|
||||||
|
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@sfxset.command(name="addurl")
|
||||||
|
@commands.guild_only()
|
||||||
|
async def sfxset_addurl(self, ctx, cost: int, vol: int, url: str, *, name: str):
|
||||||
|
"""
|
||||||
|
Add an sfx sound for the guild.
|
||||||
|
|
||||||
|
URL must be a direct link to the audio file, a youtube link, spotify link,
|
||||||
|
soundcloud link etc.
|
||||||
|
You can test if it will work using the `play` command on the bot.
|
||||||
|
"""
|
||||||
|
async with self.config.guild(ctx.guild).saysounds() as saysounds:
|
||||||
|
author = f"{ctx.author} id: {ctx.author.id}"
|
||||||
|
new_sound = saysound(name, author, cost=cost, volume=vol, url=url)
|
||||||
|
saysounds[name] = new_sound
|
||||||
|
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@sfxset.command(name="del")
|
||||||
|
@commands.guild_only()
|
||||||
|
async def sfxset_del(self, ctx, *, name: str):
|
||||||
|
"""
|
||||||
|
Delete an sfx sound for the guild.
|
||||||
|
"""
|
||||||
|
async with self.config.guild(ctx.guild).saysounds() as saysounds:
|
||||||
|
try:
|
||||||
|
del saysounds[name]
|
||||||
|
await ctx.tick()
|
||||||
|
except KeyError:
|
||||||
|
await ctx.send(error("That say sound does not exist!"))
|
||||||
|
|
||||||
|
@sfxset.command(name="file")
|
||||||
|
@checks.is_owner()
|
||||||
|
async def sfxset_file(self, ctx, *, on_off: bool = None):
|
||||||
|
"""
|
||||||
|
Enable or disable allowing to save audio files directly for playback
|
||||||
|
"""
|
||||||
|
curr = await self.config.attachments()
|
||||||
|
if on_off is None:
|
||||||
|
msg = "on" if curr else "off"
|
||||||
|
await ctx.send(f"Allowing saving of audio files is currently {msg}.")
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.config.attachments.set(on_off)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@sfxset.command(name="setup")
|
||||||
|
@checks.is_owner()
|
||||||
|
async def sfxset_setup(self, ctx):
|
||||||
|
"""
|
||||||
|
Run this first to inject code into audio cog for proper sfx usage.
|
||||||
|
|
||||||
|
After injection, reload audio cog and run this again to confirm injection
|
||||||
|
was successful.
|
||||||
|
"""
|
||||||
|
audio_cog = self.bot.get_cog("Audio")
|
||||||
|
|
||||||
|
if not audio_cog:
|
||||||
|
await ctx.send(error("Audio cog not loaded, load it first before running this."))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
if callable(audio_cog.sfx_play):
|
||||||
|
await ctx.send("Injection successful, SFX is ready to use!")
|
||||||
|
else:
|
||||||
|
await ctx.send("Function found but not callable, unknown error.")
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not AUDIO_CODE_PATH:
|
||||||
|
await ctx.send(error("Please reload the cog after the Audio cog has been loaded!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
inject_path = str(code_path(cog_instance=self) / "injection.py")
|
||||||
|
with open(inject_path, "r") as f:
|
||||||
|
injection = f.read()
|
||||||
|
|
||||||
|
inject_path = os.path.join(AUDIO_CODE_PATH, "utilities", "player.py")
|
||||||
|
with open(inject_path, "a") as f:
|
||||||
|
f.write(injection)
|
||||||
|
|
||||||
|
await ctx.send("Injection complete, reload audio cog then run this command again to make sure it worked.")
|
||||||
|
|
||||||
|
@commands.command(name="sfx")
|
||||||
|
@commands.guild_only()
|
||||||
|
@commands.cooldown(rate=1, per=10, type=commands.BucketType.user)
|
||||||
|
async def sfx(self, ctx, *, name: str):
|
||||||
|
"""
|
||||||
|
Play a say sound!
|
||||||
|
"""
|
||||||
|
if not ctx.author.voice or ctx.author.voice.channel is None:
|
||||||
|
await ctx.send(error("Connect to a voice channel to use this command."))
|
||||||
|
return
|
||||||
|
|
||||||
|
saysounds = await self.config.guild(ctx.guild).saysounds()
|
||||||
|
audio_cog = self.bot.get_cog("Audio")
|
||||||
|
play = self.bot.get_command("play")
|
||||||
|
volume = self.bot.get_command("volume")
|
||||||
|
if not play:
|
||||||
|
await ctx.send(error("Audio cog not loaded! Please contact bot owner."))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
sound = saysounds[name]
|
||||||
|
except KeyError:
|
||||||
|
# name doesn't have to be full name, will find closest match
|
||||||
|
matches = get_close_matches(name, list(saysounds.keys()), n=1, cutoff=0.7)
|
||||||
|
if matches:
|
||||||
|
sound = saysounds[matches[0]]
|
||||||
|
else:
|
||||||
|
await ctx.send(error("Say sound could not be found!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
# found saysound
|
||||||
|
|
||||||
|
# charge user
|
||||||
|
cost = await self.get_cost(ctx.author, sound)
|
||||||
|
msg = None
|
||||||
|
if cost > 0:
|
||||||
|
currency_name = await bank.get_currency_name(ctx.guild)
|
||||||
|
try:
|
||||||
|
await bank.withdraw_credits(ctx.author, cost)
|
||||||
|
balance = await bank.get_balance(ctx.author)
|
||||||
|
msg = await ctx.send(f"Charged: {cost}, Balance: {balance}")
|
||||||
|
except ValueError:
|
||||||
|
balance = await bank.get_balance(ctx.author)
|
||||||
|
msg = await ctx.send(
|
||||||
|
error(
|
||||||
|
f"Sorry {ctx.author.name}, you do not have enough {currency_name} to use that say sound. (Cost: {cost}, Balance: {balance})"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
await msg.delete()
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.play(ctx, sound)
|
||||||
|
|
||||||
|
if msg:
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
await msg.delete()
|
||||||
|
|
||||||
|
@commands.command(name="sfxlist")
|
||||||
|
async def sfx_list(self, ctx):
|
||||||
|
"""
|
||||||
|
List all say sounds for guild.
|
||||||
|
"""
|
||||||
|
|
||||||
|
saysounds = await self.config.guild(ctx.guild).saysounds()
|
||||||
|
msg = []
|
||||||
|
|
||||||
|
keys = sorted(list(saysounds.keys()))
|
||||||
|
|
||||||
|
for sound_name in keys:
|
||||||
|
msg.append((sound_name, saysounds[sound_name]["cost"]))
|
||||||
|
|
||||||
|
msg = tabulate.tabulate(msg, ["Sound", "Cost"], tablefmt="github")
|
||||||
|
|
||||||
|
pages = pagify(msg)
|
||||||
|
|
||||||
|
for page in pages:
|
||||||
|
try:
|
||||||
|
await ctx.author.send(box(page))
|
||||||
|
except:
|
||||||
|
await ctx.send("Please allow DMs from server members so I can DM you the list!")
|
||||||
|
return
|
13
sfx/utils.py
Normal file
13
sfx/utils.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import inspect
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# defines a saysound dictionary
|
||||||
|
def saysound(name: str, added_by: str, cost: int = 0, volume: int = 100, url: str = None, filepath: str = None) -> dict:
|
||||||
|
saysound = {"name": name, "added_by": added_by, "cost": cost, "volume": volume, "url": url, "filepath": filepath}
|
||||||
|
|
||||||
|
return saysound
|
||||||
|
|
||||||
|
|
||||||
|
# gets path to main directory of cog's code
|
||||||
|
def code_path(cog_instance):
|
||||||
|
return Path(inspect.getfile(cog_instance.__class__)).parent
|
Loading…
Reference in a new issue