userbot.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. """
  2. CREDITS:
  3. MOST OF THE CODE IN THIS FILE IS WRITTEN BY @Pokurt.
  4. SOURCE:
  5. https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
  6. """
  7. import os
  8. import re
  9. import subprocess
  10. import sys
  11. import traceback
  12. from asyncio import sleep, create_subprocess_shell, subprocess
  13. from html import escape
  14. from io import StringIO
  15. from time import time
  16. from pyrogram import filters
  17. from pyrogram.errors import MessageNotModified
  18. from pyrogram.types import Message, ReplyKeyboardMarkup
  19. from wbb import app2 # don't remove
  20. from wbb import SUDOERS, USERBOT_PREFIX, app, arq, eor
  21. from wbb.core.keyboard import ikb
  22. from wbb.core.tasks import add_task, rm_task
  23. # Eval and Sh module from nana-remix
  24. m = None
  25. p = print
  26. r = None
  27. arrow = lambda x: (x.text if isinstance(x, Message) else "") + "\n`→`"
  28. async def aexec(code, client, message):
  29. exec(
  30. "async def __aexec(client, message): "
  31. + "".join(f"\n {a}" for a in code.split("\n"))
  32. )
  33. return await locals()["__aexec"](client, message)
  34. async def iter_edit(message: Message, text: str):
  35. async for m in app2.iter_history(message.chat.id):
  36. # If no replies found, reply
  37. if m.message_id == message.message_id:
  38. return 0
  39. if not m.from_user or not m.text or not m.reply_to_message:
  40. continue
  41. if (
  42. (m.reply_to_message.message_id == message.message_id)
  43. and (m.from_user.id == message.from_user.id)
  44. and ("→" in m.text)
  45. ):
  46. try:
  47. return await m.edit(text)
  48. except MessageNotModified:
  49. return
  50. @app2.on_message(
  51. filters.user(SUDOERS)
  52. & ~filters.forwarded
  53. & ~filters.via_bot
  54. & filters.command("eval", prefixes=USERBOT_PREFIX)
  55. )
  56. async def executor(client, message: Message):
  57. global m, p, r
  58. try:
  59. cmd = message.text.split(" ", maxsplit=1)[1]
  60. except IndexError:
  61. return await message.delete()
  62. if message.chat.type == "channel":
  63. return
  64. m = message
  65. p = print
  66. # To prevent keyboard input attacks
  67. if m.reply_to_message:
  68. r = m.reply_to_message
  69. if r.reply_markup and isinstance(r.reply_markup, ReplyKeyboardMarkup):
  70. return await eor(m, text="INSECURE!")
  71. status = None
  72. old_stderr = sys.stderr
  73. old_stdout = sys.stdout
  74. redirected_output = sys.stdout = StringIO()
  75. redirected_error = sys.stderr = StringIO()
  76. stdout, stderr, exc = None, None, None
  77. try:
  78. task, task_id = await add_task(
  79. aexec,
  80. "Eval",
  81. cmd,
  82. client,
  83. m,
  84. )
  85. text = f"{arrow('')} Pending Task `{task_id}`"
  86. if not message.edit_date:
  87. status = await m.reply(text, quote=True)
  88. await task
  89. except Exception as e:
  90. e = traceback.format_exc()
  91. print(e)
  92. exc = e.splitlines()[-1]
  93. await rm_task()
  94. stdout = redirected_output.getvalue()
  95. stderr = redirected_error.getvalue()
  96. sys.stdout = old_stdout
  97. sys.stderr = old_stderr
  98. evaluation = ""
  99. if exc:
  100. evaluation = exc
  101. elif stderr:
  102. evaluation = stderr
  103. elif stdout:
  104. evaluation = stdout
  105. else:
  106. evaluation = "Success"
  107. final_output = f"**→**\n`{escape(evaluation.strip())}`"
  108. if len(final_output) > 4096:
  109. filename = "output.txt"
  110. with open(filename, "w+", encoding="utf8") as out_file:
  111. out_file.write(str(evaluation.strip()))
  112. await message.reply_document(
  113. document=filename,
  114. caption="`→`\n **Attached Document**",
  115. quote=False,
  116. )
  117. os.remove(filename)
  118. if status:
  119. await status.delete()
  120. return
  121. # Edit the output if input is edited
  122. if message.edit_date:
  123. status_ = await iter_edit(message, final_output)
  124. if status_ == 0:
  125. return await message.reply(final_output, quote=True)
  126. return
  127. if not status.from_user:
  128. status = await app2.get_messages(status.chat.id, status.message_id)
  129. await eor(status, text=final_output, quote=True)
  130. @app2.on_message(
  131. filters.user(SUDOERS)
  132. & ~filters.forwarded
  133. & ~filters.via_bot
  134. & ~filters.edited
  135. & filters.command("sh", prefixes=USERBOT_PREFIX),
  136. )
  137. async def shellrunner(_, message: Message):
  138. if len(message.command) < 2:
  139. return await eor(message, text="**Usage:**\n/sh git pull")
  140. if message.reply_to_message:
  141. r = message.reply_to_message
  142. if r.reply_markup and isinstance(
  143. r.reply_markup,
  144. ReplyKeyboardMarkup,
  145. ):
  146. return await eor(message, text="INSECURE!")
  147. output = ""
  148. text = message.text.split(None, 1)[1]
  149. if "\n" in text:
  150. code = text.split("\n")
  151. shell = " ".join(code)
  152. else:
  153. shell = text
  154. process = await create_subprocess_shell(
  155. shell,
  156. stdout=subprocess.PIPE,
  157. stderr=subprocess.PIPE,
  158. )
  159. out, errorz = await process.communicate()
  160. if errorz:
  161. error=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{errorz.decode('utf-8')}```"
  162. return await eor(message, text=error)
  163. output += out.decode("utf-8")
  164. output += "\n"
  165. if str(output) == "\n":
  166. output = None
  167. if output:
  168. if len(output) > 4096:
  169. with open("output.txt", "w+") as file:
  170. file.write(output)
  171. await message.reply_document("output.txt",caption=f"{escape(text)}")
  172. return os.remove("output.txt")
  173. await eor(
  174. message,
  175. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{(output)}```",
  176. )
  177. else:
  178. return await eor(
  179. message,
  180. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`",
  181. )