- Updated README title to show OVERSPEND1 FORK - Changed maintainer credit to @overspend1 - Updated alive command to show @overspend1 as creator instead of Meliodas
232 lines
8.4 KiB
Python
232 lines
8.4 KiB
Python
import asyncio
|
|
import os
|
|
import shlex
|
|
from datetime import datetime
|
|
|
|
from app import BOT, Config, Message
|
|
|
|
|
|
# Dangerous commands that should be blocked
|
|
DANGEROUS_COMMANDS = [
|
|
'rm', 'sudo rm', 'del', 'format', 'fdisk', 'mkfs',
|
|
'dd', 'sudo dd', 'chmod 000', 'sudo chmod',
|
|
':(){ :|:& };:', 'shutdown', 'reboot', 'halt',
|
|
'sudo shutdown', 'sudo reboot', 'sudo halt',
|
|
'passwd', 'sudo passwd', 'userdel', 'sudo userdel'
|
|
]
|
|
|
|
|
|
def is_dangerous_command(command: str) -> bool:
|
|
"""Check if command contains dangerous operations"""
|
|
command_lower = command.lower().strip()
|
|
for dangerous in DANGEROUS_COMMANDS:
|
|
if command_lower.startswith(dangerous):
|
|
return True
|
|
return False
|
|
|
|
|
|
@BOT.add_cmd(cmd="sh", allow_sudo=False)
|
|
async def shell_command(bot: BOT, message: Message):
|
|
"""
|
|
CMD: SH
|
|
INFO: Execute shell commands safely (Owner only).
|
|
FLAGS: -o for output only, -t for with timestamps
|
|
USAGE: .sh ls -la
|
|
"""
|
|
# Only allow owner to use shell commands
|
|
if message.from_user.id != Config.OWNER_ID:
|
|
await message.reply("❌ <b>Access Denied:</b> Only the bot owner can execute shell commands.")
|
|
return
|
|
|
|
command = message.filtered_input
|
|
if not command:
|
|
await message.reply("❌ <b>No command provided.</b>\nUsage: <code>.sh [command]</code>")
|
|
return
|
|
|
|
# Check for dangerous commands
|
|
if is_dangerous_command(command):
|
|
await message.reply("⚠️ <b>Dangerous command blocked for safety!</b>\n"
|
|
f"Command: <code>{command}</code>\n\n"
|
|
"This command could harm your system.")
|
|
return
|
|
|
|
response = await message.reply(f"🔄 <b>Executing:</b> <code>{command}</code>")
|
|
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Execute command with timeout
|
|
process = await asyncio.create_subprocess_shell(
|
|
command,
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.PIPE,
|
|
cwd=os.getcwd()
|
|
)
|
|
|
|
# Wait for completion with timeout
|
|
try:
|
|
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=30.0)
|
|
except asyncio.TimeoutError:
|
|
process.kill()
|
|
await response.edit("⏰ <b>Command timed out after 30 seconds!</b>")
|
|
return
|
|
|
|
end_time = datetime.now()
|
|
execution_time = (end_time - start_time).total_seconds()
|
|
|
|
# Decode output
|
|
stdout_text = stdout.decode('utf-8', errors='ignore').strip()
|
|
stderr_text = stderr.decode('utf-8', errors='ignore').strip()
|
|
|
|
# Prepare output
|
|
result_text = f"💻 <b>Shell Command Result</b>\n\n"
|
|
result_text += f"<b>Command:</b> <code>{command}</code>\n"
|
|
result_text += f"<b>Exit Code:</b> <code>{process.returncode}</code>\n"
|
|
result_text += f"<b>Execution Time:</b> <code>{execution_time:.2f}s</code>\n"
|
|
|
|
if "-t" in message.flags:
|
|
result_text += f"<b>Started:</b> <code>{start_time.strftime('%H:%M:%S')}</code>\n"
|
|
result_text += f"<b>Finished:</b> <code>{end_time.strftime('%H:%M:%S')}</code>\n"
|
|
|
|
result_text += "\n"
|
|
|
|
# Add stdout if present
|
|
if stdout_text:
|
|
if len(stdout_text) > 3000:
|
|
stdout_text = stdout_text[:3000] + "\n... (output truncated)"
|
|
result_text += f"<b>📤 Output:</b>\n<pre>{stdout_text}</pre>\n"
|
|
|
|
# Add stderr if present
|
|
if stderr_text:
|
|
if len(stderr_text) > 1000:
|
|
stderr_text = stderr_text[:1000] + "\n... (error truncated)"
|
|
result_text += f"<b>❌ Error:</b>\n<pre>{stderr_text}</pre>\n"
|
|
|
|
# If no output
|
|
if not stdout_text and not stderr_text:
|
|
result_text += "<i>No output produced.</i>\n"
|
|
|
|
# Success indicator
|
|
if process.returncode == 0:
|
|
result_text += "\n✅ <b>Command executed successfully!</b>"
|
|
else:
|
|
result_text += f"\n❌ <b>Command failed with exit code {process.returncode}</b>"
|
|
|
|
await response.edit(result_text)
|
|
|
|
except Exception as e:
|
|
await response.edit(f"❌ <b>Error executing command:</b>\n<code>{str(e)}</code>")
|
|
|
|
|
|
@BOT.add_cmd(cmd="exec", allow_sudo=False)
|
|
async def python_exec(bot: BOT, message: Message):
|
|
"""
|
|
CMD: EXEC
|
|
INFO: Execute Python code safely (Owner only).
|
|
USAGE: .exec print("Hello World")
|
|
"""
|
|
# Only allow owner
|
|
if message.from_user.id != Config.OWNER_ID:
|
|
await message.reply("❌ <b>Access Denied:</b> Only the bot owner can execute Python code.")
|
|
return
|
|
|
|
code = message.filtered_input
|
|
if not code:
|
|
await message.reply("❌ <b>No code provided.</b>\nUsage: <code>.exec [python_code]</code>")
|
|
return
|
|
|
|
response = await message.reply(f"🐍 <b>Executing Python code...</b>\n<pre>{code}</pre>")
|
|
|
|
try:
|
|
# Capture output
|
|
import io
|
|
import sys
|
|
from contextlib import redirect_stdout, redirect_stderr
|
|
|
|
stdout_capture = io.StringIO()
|
|
stderr_capture = io.StringIO()
|
|
|
|
start_time = datetime.now()
|
|
|
|
# Execute the code
|
|
with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture):
|
|
exec(code)
|
|
|
|
end_time = datetime.now()
|
|
execution_time = (end_time - start_time).total_seconds()
|
|
|
|
# Get captured output
|
|
stdout_output = stdout_capture.getvalue()
|
|
stderr_output = stderr_capture.getvalue()
|
|
|
|
result_text = f"🐍 <b>Python Execution Result</b>\n\n"
|
|
result_text += f"<b>Execution Time:</b> <code>{execution_time:.3f}s</code>\n\n"
|
|
|
|
if stdout_output:
|
|
if len(stdout_output) > 3500:
|
|
stdout_output = stdout_output[:3500] + "\n... (output truncated)"
|
|
result_text += f"<b>📤 Output:</b>\n<pre>{stdout_output}</pre>\n"
|
|
|
|
if stderr_output:
|
|
if len(stderr_output) > 1000:
|
|
stderr_output = stderr_output[:1000] + "\n... (error truncated)"
|
|
result_text += f"<b>❌ Error:</b>\n<pre>{stderr_output}</pre>\n"
|
|
|
|
if not stdout_output and not stderr_output:
|
|
result_text += "<i>Code executed without output.</i>\n"
|
|
|
|
result_text += "\n✅ <b>Python code executed successfully!</b>"
|
|
|
|
await response.edit(result_text)
|
|
|
|
except Exception as e:
|
|
error_text = f"🐍 <b>Python Execution Error</b>\n\n"
|
|
error_text += f"<b>Error:</b> <code>{type(e).__name__}: {str(e)}</code>\n"
|
|
error_text += f"<b>Code:</b>\n<pre>{code}</pre>"
|
|
|
|
await response.edit(error_text)
|
|
|
|
|
|
@BOT.add_cmd(cmd="eval", allow_sudo=False)
|
|
async def python_eval(bot: BOT, message: Message):
|
|
"""
|
|
CMD: EVAL
|
|
INFO: Evaluate Python expressions safely (Owner only).
|
|
USAGE: .eval 2 + 2
|
|
"""
|
|
# Only allow owner
|
|
if message.from_user.id != Config.OWNER_ID:
|
|
await message.reply("❌ <b>Access Denied:</b> Only the bot owner can evaluate Python expressions.")
|
|
return
|
|
|
|
expression = message.filtered_input
|
|
if not expression:
|
|
await message.reply("❌ <b>No expression provided.</b>\nUsage: <code>.eval [expression]</code>")
|
|
return
|
|
|
|
response = await message.reply(f"🧮 <b>Evaluating:</b> <code>{expression}</code>")
|
|
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Evaluate the expression
|
|
result = eval(expression)
|
|
|
|
end_time = datetime.now()
|
|
execution_time = (end_time - start_time).total_seconds()
|
|
|
|
result_text = f"🧮 <b>Python Evaluation Result</b>\n\n"
|
|
result_text += f"<b>Expression:</b> <code>{expression}</code>\n"
|
|
result_text += f"<b>Result:</b> <code>{repr(result)}</code>\n"
|
|
result_text += f"<b>Type:</b> <code>{type(result).__name__}</code>\n"
|
|
result_text += f"<b>Execution Time:</b> <code>{execution_time:.3f}s</code>\n"
|
|
result_text += "\n✅ <b>Expression evaluated successfully!</b>"
|
|
|
|
await response.edit(result_text)
|
|
|
|
except Exception as e:
|
|
error_text = f"🧮 <b>Python Evaluation Error</b>\n\n"
|
|
error_text += f"<b>Expression:</b> <code>{expression}</code>\n"
|
|
error_text += f"<b>Error:</b> <code>{type(e).__name__}: {str(e)}</code>"
|
|
|
|
await response.edit(error_text) |