userbot.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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
  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.tasks import add_task, rm_task
  22. # Eval and Sh module from nana-remix
  23. m = None
  24. p = print
  25. r = None
  26. arrow = lambda x: (x.text if isinstance(x, Message) else "") + "\n`→`"
  27. async def aexec(code, client, message):
  28. exec(
  29. "async def __aexec(client, message): "
  30. + "".join(f"\n {a}" for a in code.split("\n"))
  31. )
  32. return await locals()["__aexec"](client, message)
  33. async def iter_edit(message: Message, text: str):
  34. async for m in app2.iter_history(message.chat.id):
  35. # If no replies found, reply
  36. if m.message_id == message.message_id:
  37. return 0
  38. if not m.from_user or not m.text or not m.reply_to_message:
  39. continue
  40. if (
  41. (m.reply_to_message.message_id == message.message_id)
  42. and (m.from_user.id == message.from_user.id)
  43. and ("→" in m.text)
  44. ):
  45. try:
  46. return await m.edit(text)
  47. except MessageNotModified:
  48. return
  49. @app2.on_message(
  50. filters.user(SUDOERS)
  51. & ~filters.forwarded
  52. & ~filters.via_bot
  53. & filters.command("eval", prefixes=USERBOT_PREFIX)
  54. )
  55. async def executor(client, message: Message):
  56. global m, p, r
  57. try:
  58. cmd = message.text.split(" ", maxsplit=1)[1]
  59. except IndexError:
  60. return await message.delete()
  61. if message.chat.type == "channel":
  62. return
  63. m = message
  64. p = print
  65. # To prevent keyboard input attacks
  66. if m.reply_to_message:
  67. r = m.reply_to_message
  68. if r.reply_markup and isinstance(
  69. r.reply_markup, ReplyKeyboardMarkup
  70. ):
  71. return await eor(m, text="INSECURE!")
  72. status = None
  73. old_stderr = sys.stderr
  74. old_stdout = sys.stdout
  75. redirected_output = sys.stdout = StringIO()
  76. redirected_error = sys.stderr = StringIO()
  77. stdout, stderr, exc = None, None, None
  78. try:
  79. task, task_id = await add_task(
  80. aexec,
  81. "Eval",
  82. cmd,
  83. client,
  84. m,
  85. )
  86. text = f"{arrow('')} Pending Task `{task_id}`"
  87. if not message.edit_date:
  88. status = await m.reply(text, quote=True)
  89. await task
  90. except Exception as e:
  91. e = traceback.format_exc()
  92. print(e)
  93. exc = e.splitlines()[-1]
  94. await rm_task()
  95. stdout = redirected_output.getvalue()
  96. stderr = redirected_error.getvalue()
  97. sys.stdout = old_stdout
  98. sys.stderr = old_stderr
  99. evaluation = ""
  100. if exc:
  101. evaluation = exc
  102. elif stderr:
  103. evaluation = stderr
  104. elif stdout:
  105. evaluation = stdout
  106. else:
  107. evaluation = "Success"
  108. final_output = f"**→**\n`{escape(evaluation.strip())}`"
  109. if len(final_output) > 4096:
  110. filename = "output.txt"
  111. with open(filename, "w+", encoding="utf8") as out_file:
  112. out_file.write(str(evaluation.strip()))
  113. await message.reply_document(
  114. document=filename,
  115. caption="`→`\n **Attached Document**",
  116. quote=False,
  117. )
  118. os.remove(filename)
  119. if status:
  120. await status.delete()
  121. return
  122. # Edit the output if input is edited
  123. if message.edit_date:
  124. status_ = await iter_edit(message, final_output)
  125. if status_ == 0:
  126. return await message.reply(final_output, quote=True)
  127. return
  128. if not status.from_user:
  129. status = await app2.get_messages(
  130. status.chat.id, status.message_id
  131. )
  132. await eor(status, text=final_output, quote=True)
  133. @app2.on_message(
  134. filters.user(SUDOERS)
  135. & ~filters.forwarded
  136. & ~filters.via_bot
  137. & ~filters.edited
  138. & filters.command("sh", prefixes=USERBOT_PREFIX),
  139. )
  140. async def shellrunner(_, message: Message):
  141. if len(message.command) < 2:
  142. return await eor(message, text="**Usage:**\n/sh git pull")
  143. if message.reply_to_message:
  144. r = message.reply_to_message
  145. if r.reply_markup and isinstance(
  146. r.reply_markup,
  147. ReplyKeyboardMarkup,
  148. ):
  149. return await eor(message, text="INSECURE!")
  150. text = message.text.split(None, 1)[1]
  151. if "\n" in text:
  152. code = text.split("\n")
  153. output = ""
  154. for x in code:
  155. shell = re.split(
  156. """ (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
  157. )
  158. try:
  159. process = subprocess.Popen(
  160. shell,
  161. stdout=subprocess.PIPE,
  162. stderr=subprocess.PIPE,
  163. )
  164. except Exception as err:
  165. print(err)
  166. await eor(
  167. message,
  168. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{escape(err)}```",
  169. )
  170. output += f"**{code}**\n"
  171. output += process.stdout.read()[:-1].decode("utf-8")
  172. output += "\n"
  173. else:
  174. shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
  175. for a, _ in enumerate(shell):
  176. shell[a] = shell[a].replace('"', "")
  177. try:
  178. process = subprocess.Popen(
  179. shell,
  180. stdout=subprocess.PIPE,
  181. stderr=subprocess.PIPE,
  182. )
  183. except Exception as err:
  184. print(err)
  185. exc_type, exc_obj, exc_tb = sys.exc_info()
  186. errors = traceback.format_exception(
  187. etype=exc_type,
  188. value=exc_obj,
  189. tb=exc_tb,
  190. )
  191. return await eor(
  192. message,
  193. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{''.join(errors)}```",
  194. )
  195. output = process.stdout.read()[:-1].decode("utf-8")
  196. if str(output) == "\n":
  197. output = None
  198. if output:
  199. if len(output) > 4096:
  200. with open("output.txt", "w+") as file:
  201. file.write(output)
  202. await app2.send_document(
  203. message.chat.id,
  204. "output.txt",
  205. reply_to_message_id=message.message_id,
  206. caption=escape(text),
  207. )
  208. return os.remove("output.txt")
  209. await eor(
  210. message,
  211. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{escape(output)}```",
  212. )
  213. else:
  214. await eor(
  215. message,
  216. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`",
  217. )