forbid_joins.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
  2. # █▀█ █ █ █ █▀█ █▀▄ █
  3. # © Copyright 2022
  4. # https://t.me/hikariatama
  5. #
  6. # 🔒 Licensed under the GNU AGPLv3
  7. # 🌐 https://www.gnu.org/licenses/agpl-3.0.html
  8. from telethon import TelegramClient
  9. from telethon.utils import is_list_like
  10. import inspect
  11. import logging
  12. from . import loader
  13. logger = logging.getLogger(__name__)
  14. # ⚠️⚠️ WARNING! ⚠️⚠️
  15. # If you are a module developer, and you'll try to bypass this protection to
  16. # force user join your channel, you will be added to SCAM modules
  17. # list and you will be banned from Hikka federation.
  18. # Let USER decide, which channel he will follow. Do not be so petty
  19. # I hope, you understood me.
  20. # Thank you
  21. def install_join_forbidder(client: TelegramClient) -> TelegramClient:
  22. if hasattr(client, "_forbid_join_tag"):
  23. return client
  24. old_call = client._call
  25. async def new_call(
  26. sender: "MTProtoSender", # type: ignore
  27. request: "TLRequest", # type: ignore
  28. ordered: bool = False,
  29. flood_sleep_threshold: int = None,
  30. ):
  31. not_tuple = False
  32. if not is_list_like(request):
  33. not_tuple = True
  34. request = (request,)
  35. new_request = []
  36. for item in request:
  37. if item.CONSTRUCTOR_ID in {615851205, 1817183516}:
  38. if next(
  39. (
  40. frame_info.frame.f_locals["self"]
  41. for frame_info in inspect.stack()
  42. if hasattr(frame_info, "frame")
  43. and hasattr(frame_info.frame, "f_locals")
  44. and isinstance(frame_info.frame.f_locals, dict)
  45. and "self" in frame_info.frame.f_locals
  46. and isinstance(
  47. frame_info.frame.f_locals["self"], loader.Module
  48. )
  49. and frame_info.frame.f_locals["self"].__class__.__name__
  50. not in {
  51. "APIRatelimiterMod",
  52. "ForbidJoinMod",
  53. "HelpMod",
  54. "LoaderMod",
  55. "HikkaSettingsMod",
  56. }
  57. # APIRatelimiterMod is a core proxy, so it wraps around every module in Hikka, if installed
  58. # ForbidJoinMod is also a Core proxy, so it wraps around every module in Hikka, if installed
  59. # HelpMod uses JoinChannelRequest for .support command
  60. # LoaderMod prompts user to join developers' channels
  61. # HikkaSettings prompts user to join channels, required by modules
  62. ),
  63. None,
  64. ):
  65. logger.debug(
  66. "🎉 I protected you from unintented"
  67. f" {item.__class__.__name__} ({item})!"
  68. )
  69. continue
  70. new_request += [item]
  71. if not new_request:
  72. return
  73. return await old_call(
  74. sender,
  75. new_request[0] if not_tuple else tuple(new_request),
  76. ordered,
  77. flood_sleep_threshold,
  78. )
  79. client._call = new_call
  80. client._joins_forbidden = True
  81. logger.debug("🎉 JoinForbidder installed!")
  82. return client