userbot.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 html import escape
  13. from io import StringIO
  14. from pyrogram import filters
  15. from pyrogram.errors import MessageNotModified
  16. from pyrogram.types import Message, ReplyKeyboardMarkup
  17. from wbb import (SUDOERS, USERBOT_PREFIX, app, app2, # don't remove
  18. arq, eor)
  19. from wbb.core.sections import section
  20. from wbb.core.tasks import add_task, rm_task
  21. # Eval and Sh module from nana-remix
  22. m = None
  23. p = print
  24. r = None
  25. arq = arq
  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 m.reply_to_message.message_id == message.message_id:
  41. if m.from_user.id == message.from_user.id:
  42. if "→" in m.text:
  43. try:
  44. return await m.edit(text)
  45. except MessageNotModified:
  46. return
  47. @app2.on_message(
  48. filters.user(SUDOERS)
  49. & ~filters.forwarded
  50. & ~filters.via_bot
  51. & filters.command("eval", prefixes=USERBOT_PREFIX)
  52. )
  53. async def executor(client, message: Message):
  54. global m, p, r
  55. try:
  56. cmd = message.text.split(" ", maxsplit=1)[1]
  57. except IndexError:
  58. return await message.delete()
  59. if message.chat.type == "channel":
  60. return
  61. m = message
  62. p = print
  63. # To prevent keyboard input attacks
  64. if m.reply_to_message:
  65. r = m.reply_to_message
  66. if r.reply_markup:
  67. if isinstance(r.reply_markup, ReplyKeyboardMarkup):
  68. return await eor(m, text="INSECURE!")
  69. status = None
  70. old_stderr = sys.stderr
  71. old_stdout = sys.stdout
  72. redirected_output = sys.stdout = StringIO()
  73. redirected_error = sys.stderr = StringIO()
  74. stdout, stderr, exc = None, None, None
  75. try:
  76. task, task_id = await add_task(
  77. aexec,
  78. "Eval",
  79. cmd,
  80. client,
  81. m,
  82. )
  83. text = f"{arrow('')} Pending Task `{task_id}`"
  84. if not message.edit_date:
  85. status = await m.reply(text, quote=True)
  86. await task
  87. except Exception as e:
  88. e = traceback.format_exc()
  89. print(e)
  90. exc = e.splitlines()[-1]
  91. await rm_task()
  92. stdout = redirected_output.getvalue()
  93. stderr = redirected_error.getvalue()
  94. sys.stdout = old_stdout
  95. sys.stderr = old_stderr
  96. evaluation = ""
  97. if exc:
  98. evaluation = exc
  99. elif stderr:
  100. evaluation = stderr
  101. elif stdout:
  102. evaluation = stdout
  103. # Save the last stdout in globals,
  104. # Can use the it in next calls
  105. globals()["lstdout"] = 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. return await status.delete()
  120. # Edit the output if input is edited
  121. if message.edit_date:
  122. status_ = await iter_edit(message, final_output)
  123. if status_ == 0:
  124. pass
  125. else:
  126. return
  127. await eor(status, text=final_output, quote=True)
  128. @app2.on_message(
  129. filters.user(SUDOERS)
  130. & ~filters.forwarded
  131. & ~filters.via_bot
  132. & ~filters.edited
  133. & filters.command("sh", prefixes=USERBOT_PREFIX),
  134. )
  135. async def shellrunner(client, message: Message):
  136. if len(message.command) < 2:
  137. return await eor(message, text="**Usage:**\n/sh git pull")
  138. if message.reply_to_message:
  139. r = message.reply_to_message
  140. if r.reply_markup:
  141. if isinstance(r.reply_markup, ReplyKeyboardMarkup):
  142. return await eor(message, text="INSECURE!")
  143. text = message.text.split(None, 1)[1]
  144. if "\n" in text:
  145. code = text.split("\n")
  146. output = ""
  147. for x in code:
  148. shell = re.split(
  149. """ (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
  150. )
  151. try:
  152. process = subprocess.Popen(
  153. shell,
  154. stdout=subprocess.PIPE,
  155. stderr=subprocess.PIPE,
  156. )
  157. except Exception as err:
  158. print(err)
  159. await eor(
  160. message,
  161. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{escape(err)}```",
  162. )
  163. output += f"**{code}**\n"
  164. output += process.stdout.read()[:-1].decode("utf-8")
  165. output += "\n"
  166. else:
  167. shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
  168. for a in range(len(shell)):
  169. shell[a] = shell[a].replace('"', "")
  170. try:
  171. process = subprocess.Popen(
  172. shell,
  173. stdout=subprocess.PIPE,
  174. stderr=subprocess.PIPE,
  175. )
  176. except Exception as err:
  177. print(err)
  178. exc_type, exc_obj, exc_tb = sys.exc_info()
  179. errors = traceback.format_exception(
  180. etype=exc_type,
  181. value=exc_obj,
  182. tb=exc_tb,
  183. )
  184. return await eor(
  185. message,
  186. text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{''.join(errors)}```",
  187. )
  188. output = process.stdout.read()[:-1].decode("utf-8")
  189. if str(output) == "\n":
  190. output = None
  191. if output:
  192. if len(output) > 4096:
  193. with open("output.txt", "w+") as file:
  194. file.write(output)
  195. await app2.send_document(
  196. message.chat.id,
  197. "output.txt",
  198. reply_to_message_id=message.message_id,
  199. caption=escape(text),
  200. )
  201. return os.remove("output.txt")
  202. await eor(
  203. message,
  204. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{escape(output)}```",
  205. )
  206. else:
  207. await eor(
  208. message,
  209. text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`",
  210. )