import discord, os, asyncio, ctypes from discord import app_commands TOKEN = 'qwerty' ALLOWED = {362372093423255552, 649288650441490433, 288102417386700800} GRACE_PERIOD = 300 COOLDOWN = 60 bot = discord.Client(intents=discord.Intents.default()) tree = app_commands.CommandTree(bot) @bot.event async def on_ready(): print("bot is ready") await tree.sync() shutdown_pending = False @tree.command(name="shutdown", description="shuts down the pc") @app_commands.checks.cooldown(1, COOLDOWN) async def shutdown(itn: discord.Interaction): global shutdown_pending if itn.user.id not in ALLOWED: await itn.response.send_message("no") return shutdown_pending = True await itn.response.send_message(f"shutting down in {GRACE_PERIOD // 60} minutes") class LII(ctypes.Structure): _fields_ = [("cbSize", ctypes.c_uint), ("dwTime", ctypes.c_uint)] info = LII(cbSize=ctypes.sizeof(LII)) ctypes.windll.user32.GetLastInputInfo(ctypes.byref(info)) last_input = info.dwTime i = 0 while i < GRACE_PERIOD: await asyncio.sleep(1) ctypes.windll.user32.GetLastInputInfo(ctypes.byref(info)) if not shutdown_pending: return if info.dwTime != last_input: await itn.edit_original_response(content="someone is using the pc, cancelled") shutdown_pending = False return i += 1 await itn.edit_original_response(content="saving vms...") proc = await asyncio.create_subprocess_shell( 'powershell "Get-VM | Where State -eq Running | Stop-VM -Save"', stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) _, stderr = await proc.communicate() if proc.returncode != 0: await itn.edit_original_response(content=f"something went wrong with the vms, cancelled\n```{stderr.decode()}```") shutdown_pending = False return await itn.edit_original_response(content="vms saved, shutting down") proc = await asyncio.create_subprocess_shell("shutdown /s /t 5") await proc.communicate() shutdown_pending = False @shutdown.error async def shutdown_error(itn: discord.Interaction, error: app_commands.AppCommandError): if isinstance(error, app_commands.CommandOnCooldown): await itn.response.send_message(f"wait {error.retry_after:.0f} seconds") @tree.command(name="abort", description="cancels the shutdown") async def abort(itn: discord.Interaction): global shutdown_pending if itn.user.id not in ALLOWED: await itn.response.send_message("no") return if not shutdown_pending: await itn.response.send_message("nothing to cancel") return shutdown_pending = False await itn.response.send_message("cancelled") bot.run(TOKEN)