From a5b417ccac424884ecc40a5c1450fb6a787f132d Mon Sep 17 00:00:00 2001 From: Jamon Date: Mon, 12 Aug 2024 23:22:18 +1200 Subject: [PATCH] Added a restartserver command to the discord bot, so I can restart the server from my phone or any device, only the admin role is allowed to use it. Also added a youtube download command. --- discordbot.py | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/discordbot.py b/discordbot.py index f963110..d22902a 100644 --- a/discordbot.py +++ b/discordbot.py @@ -4,7 +4,13 @@ from discord.ext import commands import pymongo from bson.objectid import ObjectId import logging -from config import DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI, DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, ACCOUNT_LINKED_ROLE_ID, DISCORD_WEBHOOK_URL +from config import GAME_SERVER_PATH, ADMIN_ROLE_ID, MUSIC_FOLDER, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI, DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, ACCOUNT_LINKED_ROLE_ID, DISCORD_WEBHOOK_URL +import yt_dlp +import os +import subprocess +import re +import psutil +import time # Set up logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(levelname)s:%(name)s: %(message)s') @@ -205,6 +211,85 @@ async def sync_linked_role(interaction: discord.Interaction): count += 1 await interaction.followup.send(f"Synced roles for {count} linked users.") +@bot.tree.command(name="downloadsong", description="Download a YouTube video as MP3") +@app_commands.describe(url="YouTube video URL") +async def download_song(interaction: discord.Interaction, url: str): + if not interaction.user.get_role(ADMIN_ROLE_ID): + await interaction.response.send_message("You don't have permission to use this command.", ephemeral=True) + return + + await interaction.response.defer() + + ydl_opts = { + 'format': 'bestaudio/best', + 'postprocessors': [{ + 'key': 'FFmpegExtractAudio', + 'preferredcodec': 'mp3', + 'preferredquality': '192', + }], + 'outtmpl': os.path.join(MUSIC_FOLDER, '%(title)s.%(ext)s'), + } + + try: + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + info = ydl.extract_info(url, download=False) + title = info['title'] + artist = info.get('artist', 'Unknown') + + # Format the filename + formatted_title = re.sub(r'[^\w\-]', '', title.title().replace(' ', '')) + formatted_artist = re.sub(r'[^\w\-]', '', artist.title().replace(' ', '')) + filename = f"{formatted_artist}-{formatted_title}.mp3" + + ydl_opts['outtmpl'] = os.path.join(MUSIC_FOLDER, filename) + ydl.download([url]) + + await interaction.followup.send(f"Successfully downloaded: {filename}") + except Exception as e: + await interaction.followup.send(f"An error occurred: {str(e)}") + +@bot.tree.command(name="restartserver", description="Restart or start the game server") +async def restart_server(interaction: discord.Interaction): + if not interaction.user.get_role(ADMIN_ROLE_ID): + await interaction.response.send_message("You don't have permission to use this command.", ephemeral=True) + return + + await interaction.response.defer() + + server_was_running = False + + try: + # Find and kill the existing game_server.py process + for proc in psutil.process_iter(['pid', 'name', 'cmdline']): + if 'python' in proc.info['name'].lower() and any('game_server.py' in cmd.lower() for cmd in proc.info['cmdline']): + server_was_running = True + proc.terminate() + proc.wait(timeout=10) # Wait for the process to terminate + break + + if server_was_running: + # Wait a moment to ensure the port is freed + time.sleep(2) + + # Start the process + subprocess.Popen(["py", GAME_SERVER_PATH], shell=True) + + if server_was_running: + await interaction.followup.send("Game server has been restarted successfully.") + else: + await interaction.followup.send("Game server has been started successfully.") + + except psutil.NoSuchProcess: + await interaction.followup.send("Failed to restart the game server. The process disappeared unexpectedly. Attempting to start a new instance.") + subprocess.Popen(["python", GAME_SERVER_PATH], shell=True) + except psutil.AccessDenied: + await interaction.followup.send("Failed to restart the game server. Access denied when trying to terminate the process. Attempting to start a new instance.") + subprocess.Popen(["python", GAME_SERVER_PATH], shell=True) + except psutil.TimeoutExpired: + await interaction.followup.send("Failed to restart the game server. Timeout occurred while waiting for the process to terminate. Attempting to start a new instance.") + subprocess.Popen(["python", GAME_SERVER_PATH], shell=True) + except Exception as e: + await interaction.followup.send(f"An error occurred while managing the server: {str(e)}") bot.run(DISCORD_BOT_TOKEN) \ No newline at end of file