Selaa lähdekoodia

Rewrote Captcha module

TheHamkerCat 5 vuotta sitten
vanhempi
sitoutus
430ee044d9
4 muutettua tiedostoa jossa 128 lisäystä ja 71 poistoa
  1. 1 0
      .gitignore
  2. BIN
      assets/arial.ttf
  3. 76 71
      wbb/modules/greetings.py
  4. 51 0
      wbb/utils/functions.py

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
+*.jpg
 token.py
 token.py
 *.raw
 *.raw
 images/
 images/

BIN
assets/arial.ttf


+ 76 - 71
wbb/modules/greetings.py

@@ -1,22 +1,19 @@
-"""
- Thanks to @dashezup for this idea
- Repo - https://github.com/dashezup/tgbot
-"""
+""" Kang with proper credits or /gbun """
 
 
 import asyncio
 import asyncio
 from wbb import app, WELCOME_DELAY_KICK_SEC
 from wbb import app, WELCOME_DELAY_KICK_SEC
 from wbb.modules.admin import member_permissions
 from wbb.modules.admin import member_permissions
 from wbb.utils.errors import capture_err
 from wbb.utils.errors import capture_err
 from wbb.utils.filter_groups import welcome_captcha_group
 from wbb.utils.filter_groups import welcome_captcha_group
+from wbb.utils.functions import generate_captcha
 from wbb.utils.dbfunctions import (
 from wbb.utils.dbfunctions import (
-        is_gbanned_user, is_captcha_on, captcha_on, captcha_off
-        )
+    is_gbanned_user, is_captcha_on, captcha_on, captcha_off
+)
 from pyrogram.types import (
 from pyrogram.types import (
-        Message, InlineKeyboardMarkup,
-        InlineKeyboardButton, ChatPermissions, User
-         )
+    Message, InlineKeyboardMarkup,
+    InlineKeyboardButton, ChatPermissions, User
+)
 from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, ChatAdminRequired
 from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, ChatAdminRequired
-from pyrogram import emoji
 from pyrogram import filters
 from pyrogram import filters
 from random import shuffle
 from random import shuffle
 from datetime import datetime
 from datetime import datetime
@@ -25,47 +22,65 @@ __MODULE__ = "Captcha"
 __HELP__ = "/captcha [ON|OFF] - Enable/Disable Captcha."
 __HELP__ = "/captcha [ON|OFF] - Enable/Disable Captcha."
 
 
 
 
+answers_dicc = []
+
+
 @app.on_message(filters.new_chat_members, group=welcome_captcha_group)
 @app.on_message(filters.new_chat_members, group=welcome_captcha_group)
 @capture_err
 @capture_err
 async def welcome(_, message: Message):
 async def welcome(_, message: Message):
+    global answers_dicc
     """Mute new member and send message with button"""
     """Mute new member and send message with button"""
     if not await is_captcha_on(message.chat.id):
     if not await is_captcha_on(message.chat.id):
         return
         return
     for member in message.new_chat_members:
     for member in message.new_chat_members:
         try:
         try:
-            if await is_gbanned_user(member.id):
-                await message.chat.kick_member(member.id)
-                continue
+            # if await is_gbanned_user(member.id):
+            #    await message.chat.kick_member(member.id)
+            #    continue
             if member.is_bot:
             if member.is_bot:
                 continue  # ignore bots
                 continue  # ignore bots
-            text = (f"Welcome, {(member.mention())}\nAre you human?\n"
-                    f"Click on the button which include this emoji {emoji.CHECK_MARK_BUTTON}.'")
             await message.chat.restrict_member(member.id, ChatPermissions())
             await message.chat.restrict_member(member.id, ChatPermissions())
+            text = (f"Welcome, {(member.mention())} Are you human?\n"
+                    f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} seconds or you'll be kicked.")
         except ChatAdminRequired:
         except ChatAdminRequired:
-            continue
-
-        keyboard = [
-            InlineKeyboardButton(
-                f"{emoji.BRAIN}",
-                callback_data=f"pressed_button {emoji.BRAIN} {member.id}"
-            ),
-            InlineKeyboardButton(
-                f"{emoji.CHECK_MARK_BUTTON}",
-                callback_data=f"pressed_button {emoji.CHECK_MARK_BUTTON} {member.id}"
-            ),
-            InlineKeyboardButton(
-                f"{emoji.CROSS_MARK}",
-                callback_data=f"pressed_button {emoji.CROSS_MARK} {member.id}"
-            ),
-            InlineKeyboardButton(
-                f"{emoji.ROBOT}",
-                callback_data=f"pressed_button {emoji.ROBOT} {member.id}"
+            break
+        captcha = generate_captcha()
+        captcha_image = captcha[0]
+        captcha_answer = captcha[1]
+        wrong_answers = captcha[2]
+        correct_button = InlineKeyboardButton(
+            f"{captcha_answer}",
+            callback_data=f"pressed_button {captcha_answer} {member.id}"
+        )
+        temp_keyboard_1 = [correct_button]
+        temp_keyboard_2 = []
+        for i in range(3):
+            temp_keyboard_1.append(
+                InlineKeyboardButton(
+                    f"{wrong_answers[i]}",
+                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
+                )
+            )
+        for i in range(3, 7):
+            temp_keyboard_2.append(
+                InlineKeyboardButton(
+                    f"{wrong_answers[i]}",
+                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
+                )
             )
             )
-        ]
+        shuffle(temp_keyboard_1)
+        keyboard = [temp_keyboard_1, temp_keyboard_2]
         shuffle(keyboard)
         shuffle(keyboard)
-        keyboard = InlineKeyboardMarkup([keyboard])
-        button_message = await message.reply(
-            text,
+        verification_data = {
+            "user_id": member.id,
+            "answer": captcha_answer,
+            "keyboard": keyboard
+        }
+        keyboard = InlineKeyboardMarkup(keyboard)
+        answers_dicc.append(verification_data)
+        button_message = await message.reply_photo(
+            photo=captcha_image,
+            caption=text,
             reply_markup=keyboard,
             reply_markup=keyboard,
             quote=True
             quote=True
         )
         )
@@ -75,47 +90,42 @@ async def welcome(_, message: Message):
 
 
 
 
 @app.on_callback_query(filters.regex("pressed_button"))
 @app.on_callback_query(filters.regex("pressed_button"))
-async def callback_query_welcome_button(client, callback_query):
-    """After the new member presses the button, set his permissions to
-    chat permissions, delete button message and join message
+async def callback_query_welcome_button(_, callback_query):
+    """After the new member presses the correct button,
+    set his permissions to chat permissions,
+    delete button message and join message.
     """
     """
+    global answers_dicc
     data = callback_query.data
     data = callback_query.data
     pending_user = await app.get_users(int(data.split(None, 2)[2]))
     pending_user = await app.get_users(int(data.split(None, 2)[2]))
     pressed_user_id = callback_query.from_user.id
     pressed_user_id = callback_query.from_user.id
     pending_user_id = pending_user.id
     pending_user_id = pending_user.id
     button_message = callback_query.message
     button_message = callback_query.message
     answer = data.split(None, 2)[1]
     answer = data.split(None, 2)[1]
+    if len(answers_dicc) != 0:
+        for i in answers_dicc:
+            if i['user_id'] == pending_user_id:
+                correct_answer = i['answer']
+                keyboard = i['keyboard']
     if pending_user_id == pressed_user_id:
     if pending_user_id == pressed_user_id:
-        if answer != emoji.CHECK_MARK_BUTTON:
+        if answer != correct_answer:
             await callback_query.answer("Yeah, It's Wrong.")
             await callback_query.answer("Yeah, It's Wrong.")
-            keyboard = [
-                InlineKeyboardButton(
-                    f"{emoji.BRAIN}",
-                    callback_data=f"pressed_button {emoji.BRAIN} {pending_user_id}"
-                ),
-                InlineKeyboardButton(
-                    f"{emoji.CHECK_MARK_BUTTON}",
-                    callback_data=f"pressed_button {emoji.CHECK_MARK_BUTTON} {pending_user_id}"
-                ),
-                InlineKeyboardButton(
-                    f"{emoji.CROSS_MARK}",
-                    callback_data=f"pressed_button {emoji.CROSS_MARK} {pending_user_id}"
-                ),
-                InlineKeyboardButton(
-                    f"{emoji.ROBOT}",
-                    callback_data=f"pressed_button {emoji.ROBOT} {pending_user_id}"
-                )
-            ]
+            shuffle(keyboard[0])
+            shuffle(keyboard[1])
             shuffle(keyboard)
             shuffle(keyboard)
-            keyboard = InlineKeyboardMarkup([keyboard])
+            keyboard = InlineKeyboardMarkup(keyboard)
             await button_message.edit(
             await button_message.edit(
-                text=button_message.text,
+                text=button_message.caption.markdown,
                 reply_markup=keyboard
                 reply_markup=keyboard
             )
             )
             return
             return
         await callback_query.answer("Captcha passed successfully!")
         await callback_query.answer("Captcha passed successfully!")
         await button_message.chat.unban_member(pending_user_id)
         await button_message.chat.unban_member(pending_user_id)
         await button_message.delete()
         await button_message.delete()
+        if len(answers_dicc) != 0:
+            for ii in answers_dicc:
+                if ii['user_id'] == pending_user_id:
+                    answers_dicc.remove(ii)
         return
         return
     else:
     else:
         await callback_query.answer("This is not for you")
         await callback_query.answer("This is not for you")
@@ -126,25 +136,20 @@ async def kick_restricted_after_delay(delay, button_message: Message, user: User
     """If the new member is still restricted after the delay, delete
     """If the new member is still restricted after the delay, delete
     button message and join message and then kick him
     button message and join message and then kick him
     """
     """
+    global answers_dicc
     await asyncio.sleep(delay)
     await asyncio.sleep(delay)
     join_message = button_message.reply_to_message
     join_message = button_message.reply_to_message
     group_chat = button_message.chat
     group_chat = button_message.chat
     user_id = user.id
     user_id = user.id
     await join_message.delete()
     await join_message.delete()
     await button_message.delete()
     await button_message.delete()
+    if len(answers_dicc) != 0:
+        for i in answers_dicc:
+            if i['user_id'] == user_id:
+                answers_dicc.remove(i)
     await _ban_restricted_user_until_date(group_chat, user_id, duration=delay)
     await _ban_restricted_user_until_date(group_chat, user_id, duration=delay)
 
 
 
 
-@app.on_message(filters.left_chat_member)
-@capture_err
-async def left_chat_member(_, message: Message):
-    """When a restricted member left the chat, ban him for a while"""
-    group_chat = message.chat
-    user_id = message.left_chat_member.id
-    await _ban_restricted_user_until_date(group_chat, user_id,
-                                          duration=WELCOME_DELAY_KICK_SEC)
-
-
 async def _ban_restricted_user_until_date(group_chat,
 async def _ban_restricted_user_until_date(group_chat,
                                           user_id: int,
                                           user_id: int,
                                           duration: int):
                                           duration: int):

+ 51 - 0
wbb/utils/functions.py

@@ -0,0 +1,51 @@
+from PIL import Image, ImageDraw, ImageFont, ImageFilter
+from random import randint
+
+
+def generate_captcha():
+    # Generate one letter
+    def gen_letter():
+        return chr(randint(65, 90))
+    
+    def rndColor():
+        return (randint(64, 255), randint(64, 255), randint(64, 255))
+    def rndColor2():
+        return (randint(32, 127), randint(32, 127), randint(32, 127))
+    
+    # Generate a 4 letter word
+    def gen_wrong_answer():
+        word = ""
+        for _ in range(4):
+            word += gen_letter()
+        return word 
+
+    # Generate 7 wrong captcha answers
+    wrong_answers = []
+    for _ in range(7):
+        wrong_answers.append(gen_wrong_answer())
+    
+    width = 120 * 4
+    height = 120
+    correct_answer = ""
+    font = ImageFont.truetype("assets/arial.ttf", 90)
+    file = "assets/captcha.jpg"
+    image = Image.new('RGB', (width, height), (255, 255, 255))
+    draw = ImageDraw.Draw(image)
+    
+    # Draw random points on image
+    for x in range(width):
+        for y in range(height):
+            draw.point((x, y), fill=rndColor())
+
+    for t in range(4):
+        letter = gen_letter()
+        correct_answer += letter
+        draw.text(
+                (120 * t + 32, 3),
+                letter,
+                font=font,
+                fill=rndColor2()
+                )
+    image = image.filter(ImageFilter.BLUR)
+    image.save(file, 'jpeg')
+    return [file, correct_answer, wrong_answers]