Full Code of vanhbakaa/moonbix-bot for AI

main 49516e761e57 cached
29 files
103.2 KB
24.5k tokens
66 symbols
1 requests
Download .txt
Repository: vanhbakaa/moonbix-bot
Branch: main
Commit: 49516e761e57
Files: 29
Total size: 103.2 KB

Directory structure:
gitextract_smur5s11/

├── .env-example
├── .gitignore
├── LICENSE
├── README.md
├── bot/
│   ├── __init__.py
│   ├── config/
│   │   ├── __init__.py
│   │   ├── config.py
│   │   └── proxies.txt
│   ├── core/
│   │   ├── __init__.py
│   │   ├── agents.py
│   │   ├── headers.py
│   │   ├── query.py
│   │   ├── registrator.py
│   │   ├── solver/
│   │   │   ├── captcha/
│   │   │   │   ├── events.cp311-win_amd64.pyd
│   │   │   │   ├── payload.cp311-win_amd64.pyd
│   │   │   │   └── utils.cp311-win_amd64.pyd
│   │   │   ├── captcha_solver.cp311-win_amd64.pyd
│   │   │   └── classify/
│   │   │       ├── classifier.cp311-win_amd64.pyd
│   │   │       └── image.py
│   │   └── tapper.py
│   ├── exceptions/
│   │   └── __init__.py
│   └── utils/
│       ├── __init__.py
│       ├── launcher.py
│       └── logger.py
├── main.py
├── requirements.txt
├── run.bat
├── run.sh
└── version

================================================
FILE CONTENTS
================================================

================================================
FILE: .env-example
================================================
API_ID=
API_HASH=

REF_LINK=
AUTO_TASK=
AUTO_PLAY_GAME=
DELAY_EACH_ACCOUNT=

MORE_ACCURATE_CAPTCHA_SOLVER=

USE_PROXY_FROM_FILE=


================================================
FILE: .gitignore
================================================
.env
sessions
data.txt


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
## Recommendation before use

# Join the bot [here](https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&startapp=ref_6624523270&utm_medium=web_share_copy)

> [!WARNING]
> ⚠️ I do my best to avoid detection of bots, but using bots is forbidden in all airdrops. i cannot guarantee that you will not be detected as a bot. Use at your own risk. I am not responsible for any consequences of using this software.

# 🔥🔥 MUST USE PYTHON 3.11.5 (CAPTCHA VERSION ISN'T WORK ON TERMUX)🔥🔥

## Features  
| Feature                                                     | Supported  |
|---------------------------------------------------------------|:----------------:|
| Multithreading                                                |        ✅        |
| Proxy binding to session                                      |        ✅        |
| Auto ref                                                      |        ✅        |
| Auto checkin                                                  |        ✅        |
| Auto play game                                                |        ✅        |
| Auto solve captcha                                             |        ✅        |
| Support for pyrogram .session                                 |        ✅        |
Auto get maxium points each game        |        ✅        |
## [Settings](https://github.com/vanhbakaa/moonbix-bot/blob/main/.env-example)
| Settings | Description |
|----------------------------|:-------------------------------------------------------------------------------------------------------------:|
| **API_ID / API_HASH**      | Platform data from which to run the Telegram session (default - android)                                      |       
| **REF_LINK**               | Put your ref link here (default: my ref link)                                                                 |
| **AUTO_TASK**              | Auto do task (default: True)                                                                                  |
| **AUTO_PLAY_GAME**         | AUTO PLAY GAME (default: True)                                                                                |
| **MORE_ACCURATE_CAPTCHA_SOLVER**         | Option to use more accurate solver (it will slower) (default: False)                                                                                |
| **DELAY_EACH_ACCOUNT**         | SLEEP between each account (default: [15,25])                                                                                |
| **USE_PROXY_FROM_FILE**    | Whether to use a proxy from the bot/config/proxies.txt file (True / False)                                    |


## Quick Start 📚

To install libraries and run bot - open run.bat on Windows

## Prerequisites
Before you begin, make sure you have the following installed:
- [Python](https://www.python.org/downloads/) **version 3.11.5**

## Obtaining API Keys
1. Go to my.telegram.org and log in using your phone number.
2. Select "API development tools" and fill out the form to register a new application.
3. Record the API_ID and API_HASH provided after registering your application in the .env file.

## Installation
You can download the [**repository**](https://github.com/vanhbakaa/Kaia-bot/) by cloning it to your system and installing the necessary dependencies:
```shell
git clone https://github.com/vanhbakaa/moonbix-bot.git
cd moonbix-bot
```

Then you can do automatic installation by typing:

Windows:
```shell
run.bat
```

Linux:
```shell
run.sh
```

# Linux manual installation
```shell
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
cp .env-example .env
nano .env  # Here you must specify your API_ID and API_HASH, the rest is taken by default
python3 main.py
```

You can also use arguments for quick start, for example:
```shell
~/moonbix-bot >>> python3 main.py --action (1/2)
# Or
~/moonbix-bot >>> python3 main.py -a (1/2)

# 1 - Run clicker
# 2 - Creates a session
```

# Windows manual installation
```shell
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
copy .env-example .env
# Here you must specify your API_ID and API_HASH, the rest is taken by default
python main.py
```
You can also use arguments for quick start, for example:
```shell
~/moonbix-bot >>> python main.py --action (1/2)
# Or
~/moonbix-bot >>> python main.py -a (1/2)

# 1 - Run clicker
# 2 - Creates a session
```

# Termux manual installation
```
> pkg update && pkg upgrade -y
> pkg install python rust git -y
> git clone https://github.com/vanhbakaa/moonbix-bot.git
> cd moonbix-bot
> pip install -r requirements.txt
> python main.py
```

You can also use arguments for quick start, for example:
```termux
~/moonbix-bot > python main.py --action (1/2)
# Or
~/moonbix-bot > python main.py -a (1/2)

# 1 - Run clicker
# 2 - Creates a session 
```
# Support This Project

If you'd like to support the development of this project, please consider making a donation. Every little bit helps!

👉 **[Click here to view donation options](https://github.com/vanhbakaa/Donation/blob/main/README.md)** 👈

Your support allows us to keep improving the project and bring more features!

Thank you for your generosity! 🙌

### Contacts

For support or questions, you can contact me [![Static Badge](https://img.shields.io/badge/Telegram-Channel-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/airdrop_tool_vanh)


================================================
FILE: bot/__init__.py
================================================
__version__ = '1.0'


================================================
FILE: bot/config/__init__.py
================================================
from .config import settings


================================================
FILE: bot/config/config.py
================================================
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", env_ignore_empty=True)

    API_ID: int
    API_HASH: str


    REF_LINK: str = "https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&startapp=ref_6624523270&utm_medium=web_share_copy"
    AUTO_TASK: bool = True
    AUTO_PLAY_GAME: bool = True
    DELAY_EACH_ACCOUNT: list[int] = [60, 120]

    MORE_ACCURATE_CAPTCHA_SOLVER: bool = False

    USE_PROXY_FROM_FILE: bool = False


settings = Settings()



================================================
FILE: bot/config/proxies.txt
================================================
http://38.154.227.167:5868:vanhbaka:Vanhdayyyy
http://45.127.248.127:5128:vanhbaka:Vanhdayyyy
http://207.244.217.165:6712:vanhbaka:Vanhdayyyy


================================================
FILE: bot/core/__init__.py
================================================
__version__ = '1.0'

================================================
FILE: bot/core/agents.py
================================================
import random


def generate_random_user_agent(device_type='android', browser_type='chrome'):
    chrome_versions = list(range(110, 127))
    firefox_versions = list(range(90, 100))

    if browser_type == 'chrome':
        major_version = random.choice(chrome_versions)
        minor_version = random.randint(0, 9)
        build_version = random.randint(1000, 9999)
        patch_version = random.randint(0, 99)
        browser_version = f"{major_version}.{minor_version}.{build_version}.{patch_version}"
    elif browser_type == 'firefox':
        browser_version = random.choice(firefox_versions)

    if device_type == 'android':
        android_versions = ['10.0', '11.0', '12.0', '13.0']
        android_device = random.choice([
            'SM-G960F', 'Pixel 5', 'SM-A505F', 'Pixel 4a', 'Pixel 6 Pro', 'SM-N975F',
            'SM-G973F', 'Pixel 3', 'SM-G980F', 'Pixel 5a', 'SM-G998B', 'Pixel 4',
            'SM-G991B', 'SM-G996B', 'SM-F711B', 'SM-F916B', 'SM-G781B', 'SM-N986B',
            'SM-N981B', 'Pixel 2', 'Pixel 2 XL', 'Pixel 3 XL', 'Pixel 4 XL',
            'Pixel 5 XL', 'Pixel 6', 'Pixel 6 XL', 'Pixel 6a', 'Pixel 7', 'Pixel 7 Pro',
            'OnePlus 8', 'OnePlus 8 Pro', 'OnePlus 9', 'OnePlus 9 Pro', 'OnePlus Nord', 'OnePlus Nord 2',
            'OnePlus Nord CE', 'OnePlus 10', 'OnePlus 10 Pro', 'OnePlus 10T', 'OnePlus 10T Pro',
            'Xiaomi Mi 9', 'Xiaomi Mi 10', 'Xiaomi Mi 11', 'Xiaomi Redmi Note 8', 'Xiaomi Redmi Note 9',
            'Huawei P30', 'Huawei P40', 'Huawei Mate 30', 'Huawei Mate 40', 'Sony Xperia 1',
            'Sony Xperia 5', 'LG G8', 'LG V50', 'LG V60', 'Nokia 8.3', 'Nokia 9 PureView'
        ])
        android_version = random.choice(android_versions)
        if browser_type == 'chrome':
            return (f"Mozilla/5.0 (Linux; Android {android_version}; {android_device}) AppleWebKit/537.36 "
                    f"(KHTML, like Gecko) Chrome/{browser_version} Mobile Safari/537.36")
        elif browser_type == 'firefox':
            return (f"Mozilla/5.0 (Android {android_version}; Mobile; rv:{browser_version}.0) "
                    f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")

    elif device_type == 'ios':
        ios_versions = ['13.0', '14.0', '15.0', '16.0']
        ios_version = random.choice(ios_versions)
        if browser_type == 'chrome':
            return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
                    f"AppleWebKit/537.36 (KHTML, like Gecko) CriOS/{browser_version} Mobile/15E148 Safari/604.1")
        elif browser_type == 'firefox':
            return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
                    f"AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/{browser_version}.0 Mobile/15E148 Safari/605.1.15")

    elif device_type == 'windows':
        windows_versions = ['10.0', '11.0']
        windows_version = random.choice(windows_versions)
        if browser_type == 'chrome':
            return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                    f"Chrome/{browser_version} Safari/537.36")
        elif browser_type == 'firefox':
            return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64; rv:{browser_version}.0) "
                    f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")

    elif device_type == 'ubuntu':
        if browser_type == 'chrome':
            return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) AppleWebKit/537.36 (KHTML, like Gecko) "
                    f"Chrome/{browser_version} Safari/537.36")
        elif browser_type == 'firefox':
            return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{browser_version}.0) Gecko/{browser_version}.0 "
                    f"Firefox/{browser_version}.0")

    return None


================================================
FILE: bot/core/headers.py
================================================
headers = {
    'Accept': '*/*',
    'Accept-Language': 'en-US',
    "Bnc-Uuid": "",
    'Clienttype': "web",
    'Content-Type': 'application/json',
    'Csrftoken': 'd41d8cd98f00b204e9800998ecf8427e',
    'Device-Info': "",
    "Priority": "u=1, i",
    "Fvideo-Id": "33bda003f0aea1fa919ee400b6e9f40775ff584a",
    "Fvideo-Token": "",
    "Lang": "en",
    'Origin': 'https://www.binance.com',
    'Referer': 'https://www.binance.com/en/game/tg/moon-bix',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36',
    "X-Growth-Token": ""
}

================================================
FILE: bot/core/query.py
================================================
import asyncio
import json
import random
import traceback
from itertools import cycle
from time import time
from urllib.parse import unquote, quote
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import base64

import aiohttp
from aiocfscrape import CloudflareScraper
from aiohttp_proxy import ProxyConnector
from better_proxy import Proxy
from pyrogram import Client
from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait
from pyrogram.raw.types import InputBotAppShortName
from pyrogram.raw.functions.messages import RequestAppWebView
from soupsieve.util import lower

from bot.core.agents import generate_random_user_agent
from bot.config import settings
import cloudscraper
from math import sqrt

from bot.utils import logger
from bot.exceptions import InvalidSession
from .headers import headers
from random import randint, choices, choice, uniform
import secrets
import uuid
from faker import Faker
import string


fake = Faker()
min_length = 256
max_length = 1024


def base64_encode(data):
    return base64.b64encode(data).decode('utf-8')


class Tapper:
    def __init__(self, query: str, accname: str):
        self.query = query
        self.session_name = accname
        self.first_name = ''
        self.last_name = ''
        temp_query = unquote(query)
        self.user_id = temp_query.split('"id":')[1].split(',"first_name"')[0]
        # print(self.user_id)
        self.user = ''
        self.auth_token = ""
        self.last_claim = None
        self.last_checkin = None
        self.balace = 0
        self.access_token = None
        self.game_response = None
        self.game = None
        self.rs = 1000
        self.curr_time = None

    def random_fingerprint(self, lengths=32):
        return ''.join(choices('0123456789abcdef', k=lengths))

    def generate_Fvideo_token(self, length):

        characters = string.ascii_letters + string.digits + "+/"
        digits = string.digits
        characters1 = string.ascii_letters + digits

        random_string = ''.join(choice(characters) for _ in range(length - 3))

        random_string += '='
        random_string += choice(digits)
        random_string += choice(characters1)

        return random_string

    fake = Faker()

    def get_random_resolution(self):
        width = randint(720, 1920)
        height = randint(720, 1080)
        return f"{width},{height}"

    def get_random_timezone(self):
        timezones = [
            "GMT+07:00", "GMT+05:30", "GMT-08:00", "GMT+00:00", "GMT+03:00"
        ]
        return choice(timezones)

    def get_random_timezone_offset(self, timezone):
        # Extract the offset from the timezone format "GMT+07:00"
        sign = 1 if "+" in timezone else -1
        hours = int(timezone.split("GMT")[1].split(":")[0])
        return sign * hours * 60

    def get_random_plugins(self):
        plugins = [
            "PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
            "Flash,Java,Silverlight,QuickTime",
            "Chrome PDF Viewer,Widevine Content Decryption Module",
        ]
        return choice(plugins)

    def get_random_canvas_code(self):
        return ''.join(choices(lower(string.hexdigits), k=8))

    def get_random_fingerprint(self):
        return ''.join(choices(lower(string.hexdigits), k=32))

    def generate_random_data(self, user_agent):
        timezone = self.get_random_timezone()
        sol = self.get_random_resolution()
        data = {
            "screen_resolution": sol,
            "available_screen_resolution": sol,
            "system_version": fake.random_element(["Windows 10", "Windows 11", "Ubuntu 20.04"]),
            "brand_model": fake.random_element(["unknown", "Dell XPS 13", "HP Spectre"]),
            "system_lang": "en-EN",
            "timezone": timezone,
            "timezoneOffset": self.get_random_timezone_offset(timezone),
            "user_agent": user_agent,
            "list_plugin": self.get_random_plugins(),
            "canvas_code": self.get_random_canvas_code(),
            "webgl_vendor": fake.company(),
            "webgl_renderer": f"ANGLE ({fake.company()}, {fake.company()} Graphics)",
            "audio": str(uniform(100, 130)),
            "platform": fake.random_element(["Win32", "Win64"]),
            "web_timezone": fake.timezone(),
            "device_name": f"{fake.user_agent()} ({fake.random_element(['Windows'])})",
            "fingerprint": self.get_random_fingerprint(),
            "device_id": "",
            "related_device_ids": ""
        }
        return data

    async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
        try:
            response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5), ssl=False)
            ip = (await response.json()).get('origin')
            logger.info(f"{self.session_name} | Proxy IP: {ip}")
            return True
        except Exception as error:
            logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
            return False

    def setup_session(self, session: cloudscraper.CloudScraper):
        payload = {
            "queryString": self.auth_token,
            "socialType": "telegram"
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/third-party/access/accessToken",
            headers=headers, json=payload)
        data_ = response.json()
        if data_['code'] == '000000':
            logger.success(f"{self.session_name} | <green>Get access token sucessfully</green>")
            self.access_token = data_['data']['accessToken']
        else:
            logger.warning(f"{self.session_name} | <red>Get access token failed: {data_}</red>")

    def random_data_type(self, type, end_time, item_size, item_pts, pos_y: float):
        # I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !

        # end_time = int(end_time)
        if type == 1:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)

            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
            hook_shot_angle = "{:.3f}".format(cal_angle)

            item_type = 1
            item_s = item_size
            point = randint(1, 200)

        elif type == 2:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            #  hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)
            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
            hook_shot_angle = "{:.3f}".format(cal_angle)
            item_type = 2
            item_s = item_size
            point = int(item_size) + int(item_pts)

        elif type == 0:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            # hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)
            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))

            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))

            hook_shot_angle = "{:.3f}".format(cal_angle)

            item_type = 0
            item_s = item_size
            point = randint(1, 200)
        else:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = 0
            hook_hit_y = 0
            item_type = randint(0, 2)
            item_s = randint(1, 100)
            point = randint(1, 200)

        # 1727080937255|272.705|208.070|-0.944|0|0|2|38|12;1727080938339|224.985|241.018|-0.432|249.685|294.600|1|70|182;1727080941172|124.175|241.530|0.420|0|0|2|57|186;1727080943373|77.580|210.808|0.910|0|0|2|7|140;1727080944891|181.929|250.277|-0.066|189.091|359.041|2|60|90;1727080948123|269.666|211.426|-0.902|0|0|2|92|11;1727080949024|279.568|199.250|-1.047|0|0|2|60|34;1727080950908|162.174|250.020|0.096|144.951|428.190|0|30|191;1727080953975|78.758|212.055|0.895|0|0|0|1|151;1727080955243|133.916|244.791|0.334|103.100|333.596|1|30|15;1727080957193|278.835|200.291|-1.035|0|0|1|5|150;1727080959444|209.788|245.932|-0.298|303.593|550.828|1|70|72;1727080965178|87.635|220.354|0.786|0|0|1|85|73;1727080967129|168.297|250.390|0.046|156.376|509.116|1|50|110;1727080971647|188.297|249.779|-0.118|209.403|427.530|1|30|30;1727080974548|145.269|252.269|0.237|105.591|416.545|1|30|92;1727080978299|172.753|252.036|0.010|168.866|661.017|1|50|13
        data = f"{pick_time}|{hook_pos_x}|{hook_pos_y}|{hook_shot_angle}|{hook_hit_x}|{hook_hit_y}|{item_type}|{item_s}|{point}"
        return data

    def encrypt(self, text, key):
        iv = get_random_bytes(12)
        iv_base64 = base64_encode(iv)
        # print(iv_base64[:16].encode('utf-8'))
        cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv_base64[:16].encode('utf-8'))
        ciphertext = cipher.encrypt(pad(text.encode('utf-8'), AES.block_size))
        ciphertext_base64 = base64_encode(ciphertext)
        return iv_base64 + ciphertext_base64

    def get_game_data(self):
        # I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
        try:
            end_time = int((time() + 45) * 1000)
            # print(end_time)
            random_pick_time = randint(8, 15)
            total_obj = 0
            key_for_game = self.game_response['data']['gameTag']
            obj_type = {
                "coin": {},
                "trap": {},
                "bonus": ""
            }
            for obj in self.game_response['data']['cryptoMinerConfig']['itemSettingList']:
                total_obj += obj['quantity']
                if obj['type'] == "BONUS":
                    obj_type['bonus'] = f"{obj['rewardValueList'][0]},{obj['size']}"
                else:
                    for reward in obj['rewardValueList']:
                        if int(reward) > 0:
                            obj_type['coin'].update({reward: f"{obj['size']},{obj['quantity']}"})
                        else:
                            obj_type['trap'].update({abs(int(reward)): f"{obj['size']},{obj['quantity']}"})

            limit = min(total_obj, random_pick_time)
            random_pick_sth_times = randint(1, limit)
            picked_bonus = False
            picked = 0
            logger.info(f"{self.session_name} | Playing game!")
            game_data_payload = []
            score = 0
            # print(obj_type)

            pos_y = []
            for i in range(random_pick_sth_times + 5):
                pos_y.append(uniform(250, 550))

            sorted_pos_y = sorted(pos_y)
            for i in range(1, len(sorted_pos_y)):
                if sorted_pos_y[i] - sorted_pos_y[i - 1] < 40:
                    sorted_pos_y[i] += randint(40, 55)

            Total_tap = 0

            while end_time > self.curr_time and picked < random_pick_sth_times:
                self.rs = randint(2500, 4000)
                random_reward = randint(1, 100)
                if random_reward <= 20:
                    if len(list(obj_type['trap'].keys())) > 0:
                        picked += 1
                        reward_d = choice(list(obj_type['trap'].keys()))
                        quantity = obj_type['trap'][reward_d].split(',')[1]
                        item_size = obj_type['trap'][reward_d].split(',')[0]
                        if int(quantity) > 0:
                            data_ = self.random_data_type(end_time=end_time,
                                                          type=0,
                                                          item_size=int(item_size),
                                                          item_pts=0,
                                                          pos_y=sorted_pos_y[Total_tap])
                            if data_ is not None:
                                Total_tap += 1
                                score = max(0, score - int(reward_d))
                                game_data_payload.append(data_)
                                if int(quantity) - 1 > 0:
                                    obj_type['trap'].update({reward_d: f"{item_size},{int(quantity) - 1}"})

                                else:
                                    obj_type["trap"].pop(reward_d)
                            else:
                                break
                elif random_reward > 20 and random_reward <= 70:
                    if len(list(obj_type['coin'].keys())) > 0:
                        picked += 1
                        reward_d = choice(list(obj_type['coin'].keys()))
                        quantity = obj_type['coin'][reward_d].split(',')[1]
                        item_size = obj_type['coin'][reward_d].split(',')[0]
                        if int(quantity) > 0:

                            data_ = self.random_data_type(end_time=end_time,
                                                          type=1,
                                                          item_size=item_size,
                                                          item_pts=0,
                                                          pos_y=sorted_pos_y[Total_tap])
                            if data_ is not None:
                                Total_tap += 1
                                score += int(reward_d)
                                game_data_payload.append(data_)
                                if int(quantity) - 1 > 0:
                                    obj_type['coin'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
                                else:
                                    obj_type["coin"].pop(reward_d)
                            else:
                                break
                elif random_reward > 70 and random_reward <= 100 and picked_bonus is False:
                    picked += 1
                    size = obj_type['bonus'].split(',')[1]
                    pts = obj_type['bonus'].split(',')[0]
                    data_ = self.random_data_type(end_time=end_time,
                                                  type=2,
                                                  item_size=size,
                                                  item_pts=pts,
                                                  pos_y=sorted_pos_y[Total_tap])
                    if data_ is not None:
                        Total_tap += 1
                        picked_bonus = True
                        score += int(pts)
                        game_data_payload.append(data_)

                self.curr_time += self.rs

            if len(game_data_payload) > 0:

                data_pl = ';'.join(game_data_payload)
                # print(data_pl)
                game_payload = self.encrypt(data_pl, key_for_game)
                self.game = {
                    "payload": game_payload,
                    "log": score,
                    "debug": data_pl
                }
                # print(self.game)
                return True
            else:
                logger.warning(f"{self.session_name} | <yellow>Failed to play game, reason: Time out</yellow>")
                return False
        except Exception as error:
            traceback.print_exc()
            logger.error(f"{self.session_name} | <red>Unknown error while trying to get game data: {str(error)}</red>")
            return False

    def setup_account(self, session: cloudscraper.CloudScraper):
        ref_id = settings.REF_LINK.split("=")[1].split('&')[0].split('_')[1]
        payload = {
            "agentId": str(ref_id),
            "resourceId": 2056
        }
        res = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/referral",
            headers=headers,
            json=payload)
        json_d = res.json()
        if json_d['success']:
            res = session.post(
                "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/participated",
                headers=headers, json=payload)
            json_d = res.json()
            if json_d['success']:
                logger.success(f"{self.session_name} | <green>Successfully set up account !</green>")
                login_task = {
                    "resourceId": 2057
                }
                complete = self.complete_task(session, login_task)
                if complete == "done":
                    logger.success(f"{self.session_name} | <green>Successfully checkin for the first time !</green>")

        else:
            logger.warning(
                f"{self.session_name} | <yellow>Unknown error while tryng to init account: {json_d}</yellow>")

    async def get_user_info(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['code'] == '000000':
            # print(data_)
            data__ = data_['data']
            if data__['participated'] is False:
                logger.info(f"{self.session_name} | Attempt to set up account...")
                self.setup_account(session)
                await asyncio.sleep(uniform(3, 5))
                await self.get_user_info(session)
            else:
                logger.info(f"{self.session_name} | <cyan>Logged in</cyan>")
                logger.info(
                    f"{self.session_name} | Total point: <yellow>{data__['metaInfo']['totalGrade']}</yellow> | <white>Risk Passed: <red>{data__['riskPassed']}</red> | Qualified: <red>{data__['qualified']}</red></white>")

        else:
            logger.warning(f"{self.session_name} | <red>Get user data failed: {data_}</red>")

    def get_user_info1(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
            headers=headers, json=payload)
        data_ = response.json()
        if data_['code'] == '000000':
            # print(data_)
            data__ = data_['data']
            return data__
        else:
            logger.warning(f"{self.session_name} | <red>Get ticket data failed: {data_}</red>")

    def get_task_list(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/list",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['code'] == '000000':
            task_list = data_['data']['data'][0]['taskList']['data']  # bruh what are they doing ????
            tasks = []
            for task in task_list:
                # print(task)
                if task['type'] == "THIRD_PARTY_BIND":
                    continue
                elif task['status'] == "COMPLETED":
                    continue
                elif task['status'] == "IN_PROGRESS":
                    tasks.append(task)
            return tasks
        else:
            logger.warning(f"{self.session_name} | <red>Get tasks list failed: {data_}</red>")
            return None

    def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
        task_ids = [task['resourceId']]
        payload = {
            "referralCode": "null",
            "resourceIdList": task_ids
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/complete",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['success']:
            return "done"
        else:
            return data_['messageDetail']

    def complete_game(self, session: cloudscraper.CloudScraper):
        string_payload = self.game['payload']
        payload = {
            "log": self.game['log'],
            "payload": string_payload,
            "resourceId": 2056
        }
        # print(payload)
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/complete",
            headers=headers, json=payload)
        data_ = response.json()

        if data_['success']:
            logger.success(
                f"{self.session_name} | <green>Sucessfully earned: <yellow>{self.game['log']}</yellow> from game !</green>")
        else:
            logger.warning(
                f"{self.session_name} | <yellow>Failed to complete game | {self.game['log']}: {data_}</yellow>")

    def auto_update_ticket(self, session: cloudscraper.CloudScraper):
        ticket_data = self.get_user_info1(session)
        return ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']

    async def play_game(self, session: cloudscraper.CloudScraper):
        ticket_data = self.get_user_info1(session)
        if ticket_data['metaInfo']['totalAttempts'] == ticket_data['metaInfo']['consumedAttempts']:
            logger.warning(f"{self.session_name} | No Attempt left to play game...")
            return
        attempt_left = ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
        logger.info(f"{self.session_name} | Starting to play game...")
        while attempt_left > 0:
            # await asyncio.sleep(1000)
            logger.info(f"{self.session_name} | Attempts left: <cyan>{attempt_left}</cyan>")
            payload = {
                "resourceId": 2056
            }
            headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
            # print(headers)
            response = session.post(
                "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
                headers=headers, json=payload)
            if response.status_code == 200:
                data_ = response.json()
                # print(data_)
                if 'sessionId' in data_['data']:
                    # print("ok")
                    sessionId = data_['data']['sessionId']

                    captcha_data = f"bizId=tg_mini_game_play&sv=20220812&lang=en&securityCheckResponseValidateId={data_['data']['securityCheckValidateId']}&clientType=web"

                    captcha_header = {
                        "accept-encoding": "gzip, deflate, br",
                        "accept-language": "en-US,en;q=0.9",
                        "content-type": "text/plain; charset=UTF-8",
                        "bnc-uuid": "xxx",
                        "captcha-sdk-version": "1.0.0",
                        "clienttype": "web",
                        "device-info": headers['Device-Info'],
                        "fvideo-id": "xxx",
                        "origin": "https://www.binance.com",
                        "referer": "https://www.binance.com/",
                        'sec-fetch-dest': 'empty',
                        'sec-fetch-mode': 'cors',
                        'sec-fetch-site': 'same-origin',
                        "user-agent": headers["User-Agent"],
                        "x-captcha-se": "true"
                    }

                    cap_res = session.post("https://api.commonservice.io/gateway-api/v1/public/antibot/getCaptcha",
                                           headers=captcha_header, data=captcha_data)
                    if cap_res.status_code == 200:
                        # print(cap_res.text)
                        captcha_data_ = cap_res.json()['data']
                        cap_type = captcha_data_['captchaType']
                        bizId = captcha_data
                        sig = captcha_data_['sig']
                        salt = captcha_data_['salt']
                        tag = captcha_data_['tag']
                        path2 = captcha_data_['path2']
                        ek = captcha_data_['ek']
                        logger.info(f"{self.session_name} | Attempt to solve captcha ({tag})...")

                        captcha_data = {
                            "sig": sig,
                            "salt": salt,
                            "path2": path2,
                            "ek": ek,
                            "captchaType": cap_type,
                            "tag": tag
                        }

                        # dat = {
                        #     "mode": "VANHBAKA",
                        #     "bizId": bizId,
                        #     "captchaData": {
                        #             "sig": sig,
                        #             "salt": salt,
                        #             "path2": path2,
                        #             "ek": ek,
                        #             "captchaType": cap_type,
                        #             "tag": tag
                        #     }
                        # }
                        # head = {
                        #     "user_id": self.user_id
                        # }
                        #
                        # solve = session.post("http://127.0.0.1:5000/captcha/solve", json=dat, headers=head)
                        # solve1 = solve.json()
                        # print(solve1)

                        # print(payload)
                        from bot.core.solver.captcha_solver import solve_captcha

                        solve = await solve_captcha(bizId, captcha_data)
                        # print(solve)
                        await asyncio.sleep(random.uniform(2,4))
                        if solve['ok']:
                            sol = solve['solution']
                            # print(sol)
                            vaild_captcha = f"{bizId}&data={sol['payload']}&s={sol['s']}&sig={sig}"
                            # print(vaild_captcha)

                            solver = session.post(
                                "https://api.commonservice.io/gateway-api/v1/public/antibot/validateCaptcha",
                                data=vaild_captcha, headers=captcha_header)
                            if solver.status_code == 200:
                                # print(solver.json())

                                captcha_token = solver.json()['data']['token']
                                if captcha_token == "":
                                    logger.warning(
                                        f"{self.session_name} | <yellow>Failed to solve captcha. Try again next round...</yellow>")
                                    sleep_ = uniform(10, 15)
                                    logger.info(f"{self.session_name} | Sleep {sleep_}s...")
                                    await asyncio.sleep(sleep_)
                                    continue
                                logger.success(f"{self.session_name} | <green>Solved captcha successfully | Solve time: <cyan>{solve['solveTime']}s</cyan></green>")
                                headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
                                start_game_header = headers.copy()
                                start_game_header['X-Captcha-Challenge'] = sig
                                start_game_header['X-Captcha-Session-Id'] = sessionId
                                start_game_header['X-Captcha-Token'] = captcha_token
                                payload = {
                                    "resourceId": 2056
                                }
                                # print(start_game_header)
                                res_d = session.post(
                                    "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
                                    headers=start_game_header, json=payload)
                                data_ = res_d.json()
                            # print(data_)
                attempt_left = self.auto_update_ticket(session)
                if data_['success']:
                    logger.success(
                        f"{self.session_name} | <green>Game <cyan>{data_['data']['gameTag']}</cyan> started successful</green>")
                    self.game_response = data_
                    # print(data_)
                    sleep_ = uniform(45, 45.05)
                    self.curr_time = int((time() * 1000))
                    check = self.get_game_data()
                    if check:
                        logger.info(
                            f"{self.session_name} | Wait <white>{sleep_}s</white> to complete the game...")
                        await asyncio.sleep(sleep_)

                        self.complete_game(session)
            else:
                print(response.text)
                logger.warning(f"Start game failed: {response.status_code}")

            sleep_ = uniform(20, 25)

            logger.info(f"{self.session_name} | Sleep {sleep_}s...")

            await asyncio.sleep(sleep_)

    async def run(self, proxy: str | None) -> None:
        access_token_created_time = 0
        proxy_conn = ProxyConnector().from_url(proxy) if proxy else None

        headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
        http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
        session = cloudscraper.create_scraper()

        if proxy:
            proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
            if proxy_check:
                proxy_type = proxy.split(':')[0]
                proxies = {
                    proxy_type: proxy
                }
                session.proxies.update(proxies)
                logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")

        token_live_time = randint(28700, 28800)
        while True:
            try:
                if time() - access_token_created_time >= token_live_time:
                    tg_web_data = self.query
                    self.auth_token = tg_web_data
                    data = self.generate_random_data(headers['User-Agent'])
                    json_data = json.dumps(data)
                    encoded_data = base64.b64encode(json_data.encode()).decode()
                    headers['Device-Info'] = encoded_data
                    # print(encoded_data)
                    fvideo_token = self.generate_Fvideo_token(196)
                    headers['X-Tg-User-Id'] = self.user_id
                    # print(self.user)
                    headers['Fvideo-Id'] = secrets.token_hex(20)
                    headers['Fvideo-Token'] = fvideo_token
                    headers['Bnc-Uuid'] = str(uuid.uuid4())
                    headers['Cookie'] = f"theme=dark; bnc-uuid={headers['Bnc-Uuid']};"
                    # print(fvideo_token)
                    self.setup_session(session)
                    access_token_created_time = time()
                    token_live_time = randint(3500, 3600)

                if self.access_token:
                    headers['X-Growth-Token'] = self.access_token
                    await self.get_user_info(session)
                    if settings.AUTO_TASK:
                        task_list = self.get_task_list(session)
                        for task in task_list:
                            check = self.complete_task(session, task)
                            if check == "done":
                                logger.success(
                                    f"{self.session_name} | <green>Successfully completed task <cyan>{task['type']}</cyan> | Reward: <yellow>{task['rewardList'][0]['amount']}</yellow></green>")
                            else:
                                logger.warning(
                                    f"{self.session_name} | <light-yellow> Failed to complete task: {task['type']}, msg: {check}</light-yellow>")
                            await asyncio.sleep(uniform(3, 5))

                if settings.AUTO_PLAY_GAME:
                    await self.play_game(session)

                logger.info(f"<light-blue>==Completed {self.session_name}==</light-blue>")
                session.close()
                await http_client.close()
                # session.close()
                break

            except InvalidSession as error:
                raise error

            except Exception as error:
                traceback.print_exc()
                logger.error(f"{self.session_name} | Unknown error: {error}")
                await asyncio.sleep(delay=randint(60, 120))


async def run_tapper_no_thread_query(queryids, proxies):
    proxies_cycle = cycle(proxies) if proxies else None
    acc = "Account"
    while True:
        i = 0
        for query in queryids:

            try:
                await Tapper(query=query, accname=f"{acc}-{i}").run(next(proxies_cycle) if proxies_cycle else None)
                i += 1
            except InvalidSession:
                logger.error(f"{query} | Invalid Session")

            sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
            logger.info(f"Sleep {sleep_}s...")
            await asyncio.sleep(sleep_)

        sleep_ = randint(1500, 2500)
        logger.info(f"<red>Sleep {sleep_}s...</red>")
        await asyncio.sleep(sleep_)


================================================
FILE: bot/core/registrator.py
================================================
from pyrogram import Client

from bot.config import settings
from bot.utils import logger


async def register_sessions() -> None:
    API_ID = settings.API_ID
    API_HASH = settings.API_HASH

    if not API_ID or not API_HASH:
        raise ValueError("API_ID and API_HASH not found in the .env file.")

    session_name = input('\nEnter the session name (press Enter to exit): ')

    if not session_name:
        return None

    session = Client(
        name=session_name,
        api_id=API_ID,
        api_hash=API_HASH,
        workdir="sessions/"
    )

    async with session:
        user_data = await session.get_me()

    logger.success(f'Session added successfully @{user_data.username} | {user_data.first_name} {user_data.last_name}')


================================================
FILE: bot/core/solver/classify/image.py
================================================
from PIL import Image
import requests
from io import BytesIO

async def process_image(url):
    square_size = 110

    try:
        response = requests.get(url)
        image = Image.open(BytesIO(response.content))

        cropped_images = []

        for row in range(3):
            for col in range(3):
                x_min = col * square_size
                y_min = row * square_size
                x_max = x_min + square_size
                y_max = y_min + square_size

                # Crop the image
                cropped_image = image.crop((x_min, y_min, x_max, y_max))
                cropped_images.append(cropped_image)

        return cropped_images

    except Exception as err:
        return str(err)


================================================
FILE: bot/core/tapper.py
================================================
import asyncio
import json
import random
import traceback
from itertools import cycle
from time import time
from urllib.parse import unquote, quote
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import base64

import aiohttp
from aiocfscrape import CloudflareScraper
from aiohttp_proxy import ProxyConnector
from better_proxy import Proxy
from pyrogram import Client
from pyrogram.errors import Unauthorized, UserDeactivated, AuthKeyUnregistered, FloodWait
from pyrogram.raw.types import InputBotAppShortName
from pyrogram.raw.functions.messages import RequestAppWebView
from soupsieve.util import lower

from bot.core.agents import generate_random_user_agent
from bot.config import settings
import cloudscraper
from math import sqrt

from bot.utils import logger
from bot.exceptions import InvalidSession
from .headers import headers
from random import randint, choices, choice, uniform
import secrets
import uuid
from faker import Faker
import string


fake = Faker()
min_length = 256
max_length = 1024


def base64_encode(data):
    return base64.b64encode(data).decode('utf-8')


class Tapper:
    def __init__(self, tg_client: Client):
        self.tg_client = tg_client
        self.session_name = tg_client.name
        self.first_name = ''
        self.last_name = ''
        self.user_id = ''
        self.user = ''
        self.auth_token = ""
        self.last_claim = None
        self.last_checkin = None
        self.balace = 0
        self.access_token = None
        self.game_response = None
        self.game = None
        self.rs = 1000
        self.curr_time = None

    async def get_tg_web_data(self, proxy: str | None) -> str:
        ref_param = settings.REF_LINK.split("=")[1].split('&')[0]
        if proxy:
            proxy = Proxy.from_str(proxy)
            proxy_dict = dict(
                scheme=proxy.protocol,
                hostname=proxy.host,
                port=proxy.port,
                username=proxy.login,
                password=proxy.password
            )
        else:
            proxy_dict = None

        self.tg_client.proxy = proxy_dict

        try:
            if not self.tg_client.is_connected:
                try:
                    await self.tg_client.connect()
                except (Unauthorized, UserDeactivated, AuthKeyUnregistered):
                    raise InvalidSession(self.session_name)

            while True:
                try:
                    peer = await self.tg_client.resolve_peer('Binance_Moonbix_bot')
                    break
                except FloodWait as fl:
                    fls = fl.value

                    logger.warning(f"<light-yellow>{self.session_name}</light-yellow> | FloodWait {fl}")
                    logger.info(f"<light-yellow>{self.session_name}</light-yellow> | Sleep {fls}s")

                    await asyncio.sleep(fls + 3)

            web_view = await self.tg_client.invoke(RequestAppWebView(
                peer=peer,
                app=InputBotAppShortName(bot_id=peer, short_name="start"),
                platform='android',
                write_allowed=True,
                start_param=ref_param
            ))

            auth_url = web_view.url
            # print(auth_url)
            tg_web_data1 = unquote(string=auth_url.split('tgWebAppData=')[1].split('&tgWebAppVersion')[0])
            tg_web_data = unquote(
                string=unquote(string=auth_url.split('tgWebAppData=')[1].split('&tgWebAppVersion')[0]))

            self.user_id = tg_web_data.split('"id":')[1].split(',"first_name"')[0]
            self.first_name = tg_web_data.split('"first_name":"')[1].split('","last_name"')[0]
            self.last_name = tg_web_data.split('"last_name":"')[1].split('","username"')[0]

            if self.tg_client.is_connected:
                await self.tg_client.disconnect()

            return tg_web_data1

        except InvalidSession as error:
            raise error

        except Exception as error:
            traceback.print_exc()
            logger.error(f"<light-yellow>{self.session_name}</light-yellow> | Unknown error during Authorization: "
                         f"{error}")
            await asyncio.sleep(delay=3)

    def random_fingerprint(self, lengths=32):
        return ''.join(choices('0123456789abcdef', k=lengths))

    def generate_Fvideo_token(self, length):

        characters = string.ascii_letters + string.digits + "+/"
        digits = string.digits
        characters1 = string.ascii_letters + digits

        random_string = ''.join(choice(characters) for _ in range(length - 3))

        random_string += '='
        random_string += choice(digits)
        random_string += choice(characters1)

        return random_string

    fake = Faker()

    def get_random_resolution(self):
        width = randint(720, 1920)
        height = randint(720, 1080)
        return f"{width},{height}"

    def get_random_timezone(self):
        timezones = [
            "GMT+07:00", "GMT+05:30", "GMT-08:00", "GMT+00:00", "GMT+03:00"
        ]
        return choice(timezones)

    def get_random_timezone_offset(self, timezone):
        # Extract the offset from the timezone format "GMT+07:00"
        sign = 1 if "+" in timezone else -1
        hours = int(timezone.split("GMT")[1].split(":")[0])
        return sign * hours * 60

    def get_random_plugins(self):
        plugins = [
            "PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
            "Flash,Java,Silverlight,QuickTime",
            "Chrome PDF Viewer,Widevine Content Decryption Module",
        ]
        return choice(plugins)

    def get_random_canvas_code(self):
        return ''.join(choices(lower(string.hexdigits), k=8))

    def get_random_fingerprint(self):
        return ''.join(choices(lower(string.hexdigits), k=32))

    def generate_random_data(self, user_agent):
        timezone = self.get_random_timezone()
        sol = self.get_random_resolution()
        data = {
            "screen_resolution": sol,
            "available_screen_resolution": sol,
            "system_version": fake.random_element(["Windows 10", "Windows 11", "Ubuntu 20.04"]),
            "brand_model": fake.random_element(["unknown", "Dell XPS 13", "HP Spectre"]),
            "system_lang": "en-EN",
            "timezone": timezone,
            "timezoneOffset": self.get_random_timezone_offset(timezone),
            "user_agent": user_agent,
            "list_plugin": self.get_random_plugins(),
            "canvas_code": self.get_random_canvas_code(),
            "webgl_vendor": fake.company(),
            "webgl_renderer": f"ANGLE ({fake.company()}, {fake.company()} Graphics)",
            "audio": str(uniform(100, 130)),
            "platform": fake.random_element(["Win32", "Win64"]),
            "web_timezone": fake.timezone(),
            "device_name": f"{fake.user_agent()} ({fake.random_element(['Windows'])})",
            "fingerprint": self.get_random_fingerprint(),
            "device_id": "",
            "related_device_ids": ""
        }
        return data

    async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy):
        try:
            response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5), ssl=False)
            ip = (await response.json()).get('origin')
            logger.info(f"{self.session_name} | Proxy IP: {ip}")
            return True
        except Exception as error:
            logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
            return False

    def setup_session(self, session: cloudscraper.CloudScraper):
        payload = {
            "queryString": self.auth_token,
            "socialType": "telegram"
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/third-party/access/accessToken",
            headers=headers, json=payload)
        data_ = response.json()
        if data_['code'] == '000000':
            logger.success(f"{self.session_name} | <green>Get access token sucessfully</green>")
            self.access_token = data_['data']['accessToken']
        else:
            logger.warning(f"{self.session_name} | <red>Get access token failed: {data_}</red>")

    def random_data_type(self, type, end_time, item_size, item_pts, pos_y: float):
        # I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !

        # end_time = int(end_time)
        if type == 1:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)

            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
            hook_shot_angle = "{:.3f}".format(cal_angle)

            item_type = 1
            item_s = item_size
            point = randint(1, 200)

        elif type == 2:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            #  hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)
            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))
            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))
            hook_shot_angle = "{:.3f}".format(cal_angle)
            item_type = 2
            item_s = item_size
            point = int(item_size) + int(item_pts)

        elif type == 0:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            # hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = "{:.3f}".format(round(uniform(100, 400), 3))
            hook_hit_y = "{:.3f}".format(pos_y)
            multi = (float(hook_hit_x) - float(hook_pos_x)) * (float(hook_hit_x) - float(hook_pos_x))
            mult2i = (float(hook_hit_y) - float(hook_pos_y)) * (float(hook_hit_y) - float(hook_pos_y))

            cal_angle = (float(hook_pos_x) - float(hook_hit_x)) / (sqrt(multi + mult2i))

            hook_shot_angle = "{:.3f}".format(cal_angle)

            item_type = 0
            item_s = item_size
            point = randint(1, 200)
        else:
            pick_time = self.curr_time + self.rs
            if pick_time >= end_time:
                pick_time = end_time - 1000
                return None

            hook_pos_x = "{:.3f}".format(round(uniform(75, 230), 3))
            hook_pos_y = "{:.3f}".format(round(uniform(199, 230), 3))
            hook_shot_angle = "{:.3f}".format(round(uniform(-1, 1), 3))
            hook_hit_x = 0
            hook_hit_y = 0
            item_type = randint(0, 2)
            item_s = randint(1, 100)
            point = randint(1, 200)

        # 1727080937255|272.705|208.070|-0.944|0|0|2|38|12;1727080938339|224.985|241.018|-0.432|249.685|294.600|1|70|182;1727080941172|124.175|241.530|0.420|0|0|2|57|186;1727080943373|77.580|210.808|0.910|0|0|2|7|140;1727080944891|181.929|250.277|-0.066|189.091|359.041|2|60|90;1727080948123|269.666|211.426|-0.902|0|0|2|92|11;1727080949024|279.568|199.250|-1.047|0|0|2|60|34;1727080950908|162.174|250.020|0.096|144.951|428.190|0|30|191;1727080953975|78.758|212.055|0.895|0|0|0|1|151;1727080955243|133.916|244.791|0.334|103.100|333.596|1|30|15;1727080957193|278.835|200.291|-1.035|0|0|1|5|150;1727080959444|209.788|245.932|-0.298|303.593|550.828|1|70|72;1727080965178|87.635|220.354|0.786|0|0|1|85|73;1727080967129|168.297|250.390|0.046|156.376|509.116|1|50|110;1727080971647|188.297|249.779|-0.118|209.403|427.530|1|30|30;1727080974548|145.269|252.269|0.237|105.591|416.545|1|30|92;1727080978299|172.753|252.036|0.010|168.866|661.017|1|50|13
        data = f"{pick_time}|{hook_pos_x}|{hook_pos_y}|{hook_shot_angle}|{hook_hit_x}|{hook_hit_y}|{item_type}|{item_s}|{point}"
        return data

    def encrypt(self, text, key):
        iv = get_random_bytes(12)
        iv_base64 = base64_encode(iv)
        # print(iv_base64[:16].encode('utf-8'))
        cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv_base64[:16].encode('utf-8'))
        ciphertext = cipher.encrypt(pad(text.encode('utf-8'), AES.block_size))
        ciphertext_base64 = base64_encode(ciphertext)
        return iv_base64 + ciphertext_base64

    def get_game_data(self):
        # I WOKED HARD TO FIND OUT THIS.SO IF U COPY PLEASE CREDIT ME !
        try:
            end_time = int((time() + 45) * 1000)
            # print(end_time)
            random_pick_time = randint(8, 15)
            total_obj = 0
            key_for_game = self.game_response['data']['gameTag']
            obj_type = {
                "coin": {},
                "trap": {},
                "bonus": ""
            }
            for obj in self.game_response['data']['cryptoMinerConfig']['itemSettingList']:
                total_obj += obj['quantity']
                if obj['type'] == "BONUS":
                    obj_type['bonus'] = f"{obj['rewardValueList'][0]},{obj['size']}"
                else:
                    for reward in obj['rewardValueList']:
                        if int(reward) > 0:
                            obj_type['coin'].update({reward: f"{obj['size']},{obj['quantity']}"})
                        else:
                            obj_type['trap'].update({abs(int(reward)): f"{obj['size']},{obj['quantity']}"})

            limit = min(total_obj, random_pick_time)
            random_pick_sth_times = randint(1, limit)
            picked_bonus = False
            picked = 0
            logger.info(f"{self.session_name} | Playing game!")
            game_data_payload = []
            score = 0
            # print(obj_type)

            pos_y = []
            for i in range(random_pick_sth_times + 5):
                pos_y.append(uniform(250, 550))

            sorted_pos_y = sorted(pos_y)
            for i in range(1, len(sorted_pos_y)):
                if sorted_pos_y[i] - sorted_pos_y[i - 1] < 40:
                    sorted_pos_y[i] += randint(40, 55)

            Total_tap = 0

            while end_time > self.curr_time and picked < random_pick_sth_times:
                self.rs = randint(2500, 4000)
                random_reward = randint(1, 100)
                if random_reward <= 20:
                    if len(list(obj_type['trap'].keys())) > 0:
                        picked += 1
                        reward_d = choice(list(obj_type['trap'].keys()))
                        quantity = obj_type['trap'][reward_d].split(',')[1]
                        item_size = obj_type['trap'][reward_d].split(',')[0]
                        if int(quantity) > 0:
                            data_ = self.random_data_type(end_time=end_time,
                                                          type=0,
                                                          item_size=int(item_size),
                                                          item_pts=0,
                                                          pos_y=sorted_pos_y[Total_tap])
                            if data_ is not None:
                                Total_tap += 1
                                score = max(0, score - int(reward_d))
                                game_data_payload.append(data_)
                                if int(quantity) - 1 > 0:
                                    obj_type['trap'].update({reward_d: f"{item_size},{int(quantity) - 1}"})

                                else:
                                    obj_type["trap"].pop(reward_d)
                            else:
                                break
                elif random_reward > 20 and random_reward <= 70:
                    if len(list(obj_type['coin'].keys())) > 0:
                        picked += 1
                        reward_d = choice(list(obj_type['coin'].keys()))
                        quantity = obj_type['coin'][reward_d].split(',')[1]
                        item_size = obj_type['coin'][reward_d].split(',')[0]
                        if int(quantity) > 0:

                            data_ = self.random_data_type(end_time=end_time,
                                                          type=1,
                                                          item_size=item_size,
                                                          item_pts=0,
                                                          pos_y=sorted_pos_y[Total_tap])
                            if data_ is not None:
                                Total_tap += 1
                                score += int(reward_d)
                                game_data_payload.append(data_)
                                if int(quantity) - 1 > 0:
                                    obj_type['coin'].update({reward_d: f"{item_size},{int(quantity) - 1}"})
                                else:
                                    obj_type["coin"].pop(reward_d)
                            else:
                                break
                elif random_reward > 70 and random_reward <= 100 and picked_bonus is False:
                    picked += 1
                    size = obj_type['bonus'].split(',')[1]
                    pts = obj_type['bonus'].split(',')[0]
                    data_ = self.random_data_type(end_time=end_time,
                                                  type=2,
                                                  item_size=size,
                                                  item_pts=pts,
                                                  pos_y=sorted_pos_y[Total_tap])
                    if data_ is not None:
                        Total_tap += 1
                        picked_bonus = True
                        score += int(pts)
                        game_data_payload.append(data_)

                self.curr_time += self.rs

            if len(game_data_payload) > 0:

                data_pl = ';'.join(game_data_payload)
                # print(data_pl)
                game_payload = self.encrypt(data_pl, key_for_game)
                self.game = {
                    "payload": game_payload,
                    "log": score,
                    "debug": data_pl
                }
                # print(self.game)
                return True
            else:
                logger.warning(f"{self.session_name} | <yellow>Failed to play game, reason: Time out</yellow>")
                return False
        except Exception as error:
            traceback.print_exc()
            logger.error(f"{self.session_name} | <red>Unknown error while trying to get game data: {str(error)}</red>")
            return False

    def setup_account(self, session: cloudscraper.CloudScraper):
        ref_id = settings.REF_LINK.split("=")[1].split('&')[0].split('_')[1]
        payload = {
            "agentId": str(ref_id),
            "resourceId": 2056
        }
        res = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/referral",
            headers=headers,
            json=payload)
        json_d = res.json()
        if json_d['success']:
            res = session.post(
                "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/participated",
                headers=headers, json=payload)
            json_d = res.json()
            if json_d['success']:
                logger.success(f"{self.session_name} | <green>Successfully set up account !</green>")
                login_task = {
                    "resourceId": 2057
                }
                complete = self.complete_task(session, login_task)
                if complete == "done":
                    logger.success(f"{self.session_name} | <green>Successfully checkin for the first time !</green>")

        else:
            logger.warning(
                f"{self.session_name} | <yellow>Unknown error while tryng to init account: {json_d}</yellow>")

    async def get_user_info(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['code'] == '000000':
            # print(data_)
            data__ = data_['data']
            if data__['participated'] is False:
                logger.info(f"{self.session_name} | Attempt to set up account...")
                self.setup_account(session)
                await asyncio.sleep(uniform(3, 5))
                await self.get_user_info(session)
            else:
                logger.info(f"{self.session_name} | <cyan>Logged in</cyan>")
                logger.info(
                    f"{self.session_name} | Total point: <yellow>{data__['metaInfo']['totalGrade']}</yellow> | <white>Risk Passed: <red>{data__['riskPassed']}</red> | Qualified: <red>{data__['qualified']}</red></white>")

        else:
            logger.warning(f"{self.session_name} | <red>Get user data failed: {data_}</red>")

    def get_user_info1(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/user/user-info",
            headers=headers, json=payload)
        data_ = response.json()
        if data_['code'] == '000000':
            # print(data_)
            data__ = data_['data']
            return data__
        else:
            logger.warning(f"{self.session_name} | <red>Get ticket data failed: {data_}</red>")

    def get_task_list(self, session: cloudscraper.CloudScraper):
        payload = {
            "resourceId": 2056
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/list",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['code'] == '000000':
            task_list = data_['data']['data'][0]['taskList']['data']  # bruh what are they doing ????
            tasks = []
            for task in task_list:
                # print(task)
                if task['type'] == "THIRD_PARTY_BIND":
                    continue
                elif task['status'] == "COMPLETED":
                    continue
                elif task['status'] == "IN_PROGRESS":
                    tasks.append(task)
            return tasks
        else:
            logger.warning(f"{self.session_name} | <red>Get tasks list failed: {data_}</red>")
            return None

    def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
        task_ids = [task['resourceId']]
        payload = {
            "referralCode": "null",
            "resourceIdList": task_ids
        }
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/task/complete",
            headers=headers, json=payload)
        data_ = response.json()
        # print(data_)
        if data_['success']:
            return "done"
        else:
            return data_['messageDetail']

    def complete_game(self, session: cloudscraper.CloudScraper):
        string_payload = self.game['payload']
        payload = {
            "log": self.game['log'],
            "payload": string_payload,
            "resourceId": 2056
        }
        # print(payload)
        response = session.post(
            "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/complete",
            headers=headers, json=payload)
        data_ = response.json()

        if data_['success']:
            logger.success(
                f"{self.session_name} | <green>Sucessfully earned: <yellow>{self.game['log']}</yellow> from game !</green>")
        else:
            logger.warning(
                f"{self.session_name} | <yellow>Failed to complete game | {self.game['log']}: {data_}</yellow>")

    def auto_update_ticket(self, session: cloudscraper.CloudScraper):
        ticket_data = self.get_user_info1(session)
        return ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']

    async def play_game(self, session: cloudscraper.CloudScraper):
        ticket_data = self.get_user_info1(session)
        if ticket_data['metaInfo']['totalAttempts'] == ticket_data['metaInfo']['consumedAttempts']:
            logger.warning(f"{self.session_name} | No Attempt left to play game...")
            return
        attempt_left = ticket_data['metaInfo']['totalAttempts'] - ticket_data['metaInfo']['consumedAttempts']
        logger.info(f"{self.session_name} | Starting to play game...")
        while attempt_left > 0:
            # await asyncio.sleep(1000)
            logger.info(f"{self.session_name} | Attempts left: <cyan>{attempt_left}</cyan>")
            payload = {
                "resourceId": 2056
            }
            headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
            # print(headers)
            response = session.post(
                "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
                headers=headers, json=payload)
            if response.status_code == 200:
                data_ = response.json()
                # print(data_)
                if 'sessionId' in data_['data']:
                    # print("ok")
                    sessionId = data_['data']['sessionId']

                    captcha_data = f"bizId=tg_mini_game_play&sv=20220812&lang=en&securityCheckResponseValidateId={data_['data']['securityCheckValidateId']}&clientType=web"

                    captcha_header = {
                        "accept-encoding": "gzip, deflate, br",
                        "accept-language": "en-US,en;q=0.9",
                        "content-type": "text/plain; charset=UTF-8",
                        "bnc-uuid": "xxx",
                        "captcha-sdk-version": "1.0.0",
                        "clienttype": "web",
                        "device-info": headers['Device-Info'],
                        "fvideo-id": "xxx",
                        "origin": "https://www.binance.com",
                        "referer": "https://www.binance.com/",
                        'sec-fetch-dest': 'empty',
                        'sec-fetch-mode': 'cors',
                        'sec-fetch-site': 'same-origin',
                        "user-agent": headers["User-Agent"],
                        "x-captcha-se": "true"
                    }

                    cap_res = session.post("https://api.commonservice.io/gateway-api/v1/public/antibot/getCaptcha",
                                           headers=captcha_header, data=captcha_data)
                    if cap_res.status_code == 200:
                        # print(cap_res.text)
                        captcha_data_ = cap_res.json()['data']
                        cap_type = captcha_data_['captchaType']
                        bizId = captcha_data
                        sig = captcha_data_['sig']
                        salt = captcha_data_['salt']
                        tag = captcha_data_['tag']
                        path2 = captcha_data_['path2']
                        ek = captcha_data_['ek']
                        logger.info(f"{self.session_name} | Attempt to solve captcha ({tag})...")

                        captcha_data = {
                            "sig": sig,
                            "salt": salt,
                            "path2": path2,
                            "ek": ek,
                            "captchaType": cap_type,
                            "tag": tag
                        }

                        # dat = {
                        #     "mode": "VANHBAKA",
                        #     "bizId": bizId,
                        #     "captchaData": {
                        #             "sig": sig,
                        #             "salt": salt,
                        #             "path2": path2,
                        #             "ek": ek,
                        #             "captchaType": cap_type,
                        #             "tag": tag
                        #     }
                        # }
                        # head = {
                        #     "user_id": self.user_id
                        # }
                        #
                        # solve = session.post("http://127.0.0.1:5000/captcha/solve", json=dat, headers=head)
                        # solve1 = solve.json()
                        # print(solve1)

                        # print(payload)
                        from bot.core.solver.captcha_solver import solve_captcha

                        solve = await solve_captcha(bizId, captcha_data)
                        # print(solve)
                        await asyncio.sleep(random.uniform(2,4))
                        if solve['ok']:
                            sol = solve['solution']
                            # print(sol)
                            vaild_captcha = f"{bizId}&data={sol['payload']}&s={sol['s']}&sig={sig}"
                            # print(vaild_captcha)

                            solver = session.post(
                                "https://api.commonservice.io/gateway-api/v1/public/antibot/validateCaptcha",
                                data=vaild_captcha, headers=captcha_header)
                            if solver.status_code == 200:
                                # print(solver.json())

                                captcha_token = solver.json()['data']['token']
                                if captcha_token == "":
                                    logger.warning(
                                        f"{self.session_name} | <yellow>Failed to solve captcha. Try again next round...</yellow>")
                                    sleep_ = uniform(10, 15)
                                    logger.info(f"{self.session_name} | Sleep {sleep_}s...")
                                    await asyncio.sleep(sleep_)
                                    continue
                                logger.success(f"{self.session_name} | <green>Solved captcha successfully | Solve time: <cyan>{solve['solveTime']}s</cyan></green>")
                                headers['Fvideo-Token'] = self.generate_Fvideo_token(196)
                                start_game_header = headers.copy()
                                start_game_header['X-Captcha-Challenge'] = sig
                                start_game_header['X-Captcha-Session-Id'] = sessionId
                                start_game_header['X-Captcha-Token'] = captcha_token
                                payload = {
                                    "resourceId": 2056
                                }
                                # print(start_game_header)
                                res_d = session.post(
                                    "https://www.binance.com/bapi/growth/v1/friendly/growth-paas/mini-app-activity/third-party/game/start",
                                    headers=start_game_header, json=payload)
                                data_ = res_d.json()
                            # print(data_)
                attempt_left = self.auto_update_ticket(session)
                if data_['success']:
                    logger.success(
                        f"{self.session_name} | <green>Game <cyan>{data_['data']['gameTag']}</cyan> started successful</green>")
                    self.game_response = data_
                    # print(data_)
                    sleep_ = uniform(45, 45.05)
                    self.curr_time = int((time() * 1000))
                    check = self.get_game_data()
                    if check:
                        logger.info(
                            f"{self.session_name} | Wait <white>{sleep_}s</white> to complete the game...")
                        await asyncio.sleep(sleep_)

                        self.complete_game(session)
            else:
                print(response.text)
                logger.warning(f"Start game failed: {response.status_code}")

            sleep_ = uniform(20, 25)

            logger.info(f"{self.session_name} | Sleep {sleep_}s...")

            await asyncio.sleep(sleep_)

    async def run(self, proxy: str | None) -> None:
        access_token_created_time = 0
        proxy_conn = ProxyConnector().from_url(proxy) if proxy else None

        headers["User-Agent"] = generate_random_user_agent(device_type='android', browser_type='chrome')
        http_client = CloudflareScraper(headers=headers, connector=proxy_conn)
        session = cloudscraper.create_scraper()

        if proxy:
            proxy_check = await self.check_proxy(http_client=http_client, proxy=proxy)
            if proxy_check:
                proxy_type = proxy.split(':')[0]
                proxies = {
                    proxy_type: proxy
                }
                session.proxies.update(proxies)
                logger.info(f"{self.session_name} | bind with proxy ip: {proxy}")

        token_live_time = randint(28700, 28800)
        while True:
            try:
                if time() - access_token_created_time >= token_live_time:
                    tg_web_data = await self.get_tg_web_data(proxy=proxy)
                    self.auth_token = tg_web_data
                    data = self.generate_random_data(headers['User-Agent'])
                    json_data = json.dumps(data)
                    encoded_data = base64.b64encode(json_data.encode()).decode()
                    headers['Device-Info'] = encoded_data
                    # print(encoded_data)
                    fvideo_token = self.generate_Fvideo_token(196)
                    headers['X-Tg-User-Id'] = self.user_id
                    # print(self.user)
                    headers['Fvideo-Id'] = secrets.token_hex(20)
                    headers['Fvideo-Token'] = fvideo_token
                    headers['Bnc-Uuid'] = str(uuid.uuid4())
                    headers['Cookie'] = f"theme=dark; bnc-uuid={headers['Bnc-Uuid']};"
                    # print(fvideo_token)
                    self.setup_session(session)
                    access_token_created_time = time()
                    token_live_time = randint(3500, 3600)

                if self.access_token:
                    headers['X-Growth-Token'] = self.access_token
                    await self.get_user_info(session)
                    if settings.AUTO_TASK:
                        task_list = self.get_task_list(session)
                        for task in task_list:
                            check = self.complete_task(session, task)
                            if check == "done":
                                logger.success(
                                    f"{self.session_name} | <green>Successfully completed task <cyan>{task['type']}</cyan> | Reward: <yellow>{task['rewardList'][0]['amount']}</yellow></green>")
                            else:
                                logger.warning(
                                    f"{self.session_name} | <light-yellow> Failed to complete task: {task['type']}, msg: {check}</light-yellow>")
                            await asyncio.sleep(uniform(3, 5))

                if settings.AUTO_PLAY_GAME:
                    await self.play_game(session)

                logger.info(f"<light-blue>==Completed {self.session_name}==</light-blue>")
                session.close()
                await http_client.close()
                # session.close()
                break

            except InvalidSession as error:
                raise error

            except Exception as error:
                traceback.print_exc()
                logger.error(f"{self.session_name} | Unknown error: {error}")
                await asyncio.sleep(delay=randint(60, 120))


async def run_tapper_no_thread(tg_clients, proxies):
    proxies_cycle = cycle(proxies) if proxies else None
    while True:
        for tg_client in tg_clients:
            try:
                await Tapper(tg_client=tg_client).run(next(proxies_cycle) if proxies_cycle else None)
            except InvalidSession:
                logger.error(f"{tg_client.name} | Invalid Session")

            sleep_ = randint(settings.DELAY_EACH_ACCOUNT[0], settings.DELAY_EACH_ACCOUNT[1])
            logger.info(f"Sleep {sleep_}s...")
            await asyncio.sleep(sleep_)

        sleep_ = randint(1500, 2500)
        logger.info(f"<red>Sleep {sleep_}s...</red>")
        await asyncio.sleep(sleep_)


================================================
FILE: bot/exceptions/__init__.py
================================================
class InvalidSession(BaseException):
    ...


================================================
FILE: bot/utils/__init__.py
================================================
from .logger import logger
from . import launcher


import os

if not os.path.exists(path="sessions"):
    os.mkdir(path="sessions")


================================================
FILE: bot/utils/launcher.py
================================================
import os
import glob
import argparse
import sys

import requests

from pyrogram import Client
from better_proxy import Proxy

from bot.config import settings
from bot.utils import logger
from bot.core.tapper import run_tapper_no_thread
from bot.core.query import run_tapper_no_thread_query
from bot.core.registrator import register_sessions

import importlib.util

curr_version = "3.0.5"

version = requests.get("https://raw.githubusercontent.com/vanhbakaa/moonbix-bot/refs/heads/main/version")
version_ = version.text.strip()
if curr_version == version_:
    logger.info("<cyan>Your version is up to date!</cyan>")
else:
    logger.warning(f"<yellow>New version detected {version_} please update the bot!</yellow>")
    sys.exit()
start_text = f"""

Version: {curr_version} 
By: https://github.com/vanhbakaa                                                                                                                                                                                         
Select an action:

    1. Run clicker (session)
    2. Create session
    3. Run Cheat Tapper
    4. Run clicker (Query)
"""

global tg_clients


def import_tapper():
    # Define the relative file path
    file_path = os.path.join(os.getcwd(), "bot/core/tapperCheatPoint.py")

    # Define a module name for the imported module
    module_name = "tapper"

    # Check if the file exists
    if os.path.exists(file_path):
        # Dynamically load the module
        spec = importlib.util.spec_from_file_location(module_name, file_path)
        tapper_module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(tapper_module)
        sys.modules[module_name] = tapper_module
        print(f"Successfully imported '{file_path}' as module '{module_name}'")
        return tapper_module
    else:
        print(f"Join my telegram channel to use this option!")
        return None


def get_session_names() -> list[str]:
    session_names = sorted(glob.glob("sessions/*.session"))
    session_names = [
        os.path.splitext(os.path.basename(file))[0] for file in session_names
    ]

    return session_names


def get_proxies() -> list[Proxy]:
    if settings.USE_PROXY_FROM_FILE:
        with open(file="bot/config/proxies.txt", encoding="utf-8-sig") as file:
            proxies = [Proxy.from_str(proxy=row.strip()).as_url for row in file]
    else:
        proxies = []

    return proxies


async def get_tg_clients() -> list[Client]:
    global tg_clients

    session_names = get_session_names()

    if not session_names:
        raise FileNotFoundError("Not found session files")

    if not settings.API_ID or not settings.API_HASH:
        raise ValueError("API_ID and API_HASH not found in the .env file.")

    tg_clients = [
        Client(
            name=session_name,
            api_id=settings.API_ID,
            api_hash=settings.API_HASH,
            workdir="sessions/",
            plugins=dict(root="bot/plugins"),
        )
        for session_name in session_names
    ]

    return tg_clients


async def process() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--action", type=int, help="Action to perform")

    logger.info(f"Detected {len(get_session_names())} sessions | {len(get_proxies())} proxies")

    action = parser.parse_args().action

    if not action:

        print(start_text)

        while True:
            action = input("> ")

            if not action.isdigit():
                logger.warning("Action must be number")
            elif action not in ["1", "2", "3", "4"]:
                logger.warning("Action must be 1, 2, 3 or 4")
            else:
                action = int(action)
                break

    if action == 2:
        await register_sessions()
    elif action == 1:
        tg_clients = await get_tg_clients()
        proxies = get_proxies()
        await run_tapper_no_thread(tg_clients=tg_clients, proxies=proxies)

    elif action == 3:
        tapper = import_tapper()
        if tapper:
            tg_clients = await get_tg_clients()
            proxies = get_proxies()
            await tapper.run_tapper_no_thread(tg_clients=tg_clients, proxies=proxies)
    elif action == 4:
        with open("data.txt", "r") as f:
            query_ids = [line.strip() for line in f.readlines()]
        proxies = get_proxies()
        await run_tapper_no_thread_query(query_ids, proxies)




================================================
FILE: bot/utils/logger.py
================================================
import sys
from loguru import logger


logger.remove()
logger.add(sink=sys.stdout, format="<white>{time:YYYY-MM-DD HH:mm:ss}</white>"
                                   " | <level>{level: <8}</level>"
                                   " | <cyan><b>{line}</b></cyan>"
                                   " - <white><b>{message}</b></white>")
logger = logger.opt(colors=True)


================================================
FILE: main.py
================================================
import asyncio
from contextlib import suppress

from bot.utils.launcher import process


async def main():
    await process()


if __name__ == '__main__':
    with suppress(KeyboardInterrupt):
        asyncio.run(main())


================================================
FILE: requirements.txt
================================================
aiocfscrape==1.0.0
aiohttp==3.9.3
aiohttp-proxy==0.1.2
aiosignal==1.3.1
annotated-types==0.6.0
async-timeout==4.0.3
attrs==23.2.0
beautifulsoup4==4.12.3
better-proxy==1.1.5
colorama==0.4.6
DateTime==5.5
frozenlist==1.4.1
idna==3.6
Js2Py==0.74
loguru==0.7.2
multidict==6.0.5
pyaes==1.6.1
pydantic==2.6.4
pydantic-settings==2.2.1
pydantic_core==2.16.3
pyjsparser==2.7.1
Pyrogram==2.0.106
PySocks==1.7.1
python-dotenv==1.0.1
pytz==2024.1
six==1.16.0
soupsieve==2.5
TgCrypto==1.2.5
typing_extensions==4.11.0
tzdata==2024.1
tzlocal==5.2
websockets==12.0
win32-setctime==1.1.0
yarl==1.9.4
zope.interface==6.4.post2
requests==2.32.3
cloudscraper==1.2.71
Faker==29.0.0
pycryptodome==3.20.0
pillow==10.4.0
transformers==4.45.1
torch==2.4.1

================================================
FILE: run.bat
================================================
@echo off

if not exist venv (
    echo Creating virtual environment...
    python -m venv venv
)

echo Activating virtual environment...
call venv\Scripts\activate

if not exist venv\Lib\site-packages\installed (
    if exist requirements.txt (
		echo installing wheel for faster installing
		pip install wheel
        echo Installing dependencies...
        pip install -r requirements.txt
        echo. > venv\Lib\site-packages\installed
    ) else (
        echo requirements.txt not found, skipping dependency installation.
    )
) else (
    echo Dependencies already installed, skipping installation.
)

if not exist .env (
	echo Copying configuration file
	copy .env-example .env
) else (
	echo Skipping .env copying
)

echo Starting the bot...
python main.py

echo done
echo PLEASE EDIT .ENV FILE
pause

================================================
FILE: run.sh
================================================
#!/bin/bash

# Проверка на наличие папки venv
if [ ! -d "venv" ]; then
    echo "Creating virtual environment..."
    python3 -m venv venv
fi

echo "Activating virtual environment..."
source venv/bin/activate

# Проверка на наличие установленного флага в виртуальном окружении
if [ ! -f "venv/installed" ]; then
    if [ -f "requirements.txt" ]; then
		echo "Installing wheel for faster installing"
		pip3 install wheel
        echo "Installing dependencies..."
        pip3 install -r requirements.txt
        touch venv/installed
    else
        echo "requirements.txt not found, skipping dependency installation."
    fi
else
    echo "Dependencies already installed, skipping installation."
fi

if [ ! -f ".env" ]; then
	echo "Copying configuration file"
	cp .env-example .env
else
	echo "Skipping .env copying"
fi

echo "Starting the bot..."
python3 main.py

echo "done"
echo "PLEASE EDIT .ENV FILE"


================================================
FILE: version
================================================
3.0.5
Download .txt
gitextract_smur5s11/

├── .env-example
├── .gitignore
├── LICENSE
├── README.md
├── bot/
│   ├── __init__.py
│   ├── config/
│   │   ├── __init__.py
│   │   ├── config.py
│   │   └── proxies.txt
│   ├── core/
│   │   ├── __init__.py
│   │   ├── agents.py
│   │   ├── headers.py
│   │   ├── query.py
│   │   ├── registrator.py
│   │   ├── solver/
│   │   │   ├── captcha/
│   │   │   │   ├── events.cp311-win_amd64.pyd
│   │   │   │   ├── payload.cp311-win_amd64.pyd
│   │   │   │   └── utils.cp311-win_amd64.pyd
│   │   │   ├── captcha_solver.cp311-win_amd64.pyd
│   │   │   └── classify/
│   │   │       ├── classifier.cp311-win_amd64.pyd
│   │   │       └── image.py
│   │   └── tapper.py
│   ├── exceptions/
│   │   └── __init__.py
│   └── utils/
│       ├── __init__.py
│       ├── launcher.py
│       └── logger.py
├── main.py
├── requirements.txt
├── run.bat
├── run.sh
└── version
Download .txt
SYMBOL INDEX (66 symbols across 9 files)

FILE: bot/config/config.py
  class Settings (line 4) | class Settings(BaseSettings):

FILE: bot/core/agents.py
  function generate_random_user_agent (line 4) | def generate_random_user_agent(device_type='android', browser_type='chro...

FILE: bot/core/query.py
  function base64_encode (line 43) | def base64_encode(data):
  class Tapper (line 47) | class Tapper:
    method __init__ (line 48) | def __init__(self, query: str, accname: str):
    method random_fingerprint (line 67) | def random_fingerprint(self, lengths=32):
    method generate_Fvideo_token (line 70) | def generate_Fvideo_token(self, length):
    method get_random_resolution (line 86) | def get_random_resolution(self):
    method get_random_timezone (line 91) | def get_random_timezone(self):
    method get_random_timezone_offset (line 97) | def get_random_timezone_offset(self, timezone):
    method get_random_plugins (line 103) | def get_random_plugins(self):
    method get_random_canvas_code (line 111) | def get_random_canvas_code(self):
    method get_random_fingerprint (line 114) | def get_random_fingerprint(self):
    method generate_random_data (line 117) | def generate_random_data(self, user_agent):
    method check_proxy (line 143) | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy:...
    method setup_session (line 153) | def setup_session(self, session: cloudscraper.CloudScraper):
    method random_data_type (line 168) | def random_data_type(self, type, end_time, item_size, item_pts, pos_y:...
    method encrypt (line 251) | def encrypt(self, text, key):
    method get_game_data (line 260) | def get_game_data(self):
    method setup_account (line 390) | def setup_account(self, session: cloudscraper.CloudScraper):
    method get_user_info (line 419) | async def get_user_info(self, session: cloudscraper.CloudScraper):
    method get_user_info1 (line 444) | def get_user_info1(self, session: cloudscraper.CloudScraper):
    method get_task_list (line 459) | def get_task_list(self, session: cloudscraper.CloudScraper):
    method complete_task (line 484) | def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
    method complete_game (line 500) | def complete_game(self, session: cloudscraper.CloudScraper):
    method auto_update_ticket (line 520) | def auto_update_ticket(self, session: cloudscraper.CloudScraper):
    method play_game (line 524) | async def play_game(self, session: cloudscraper.CloudScraper):
    method run (line 678) | async def run(self, proxy: str | None) -> None:
  function run_tapper_no_thread_query (line 752) | async def run_tapper_no_thread_query(queryids, proxies):

FILE: bot/core/registrator.py
  function register_sessions (line 7) | async def register_sessions() -> None:

FILE: bot/core/solver/classify/image.py
  function process_image (line 5) | async def process_image(url):

FILE: bot/core/tapper.py
  function base64_encode (line 43) | def base64_encode(data):
  class Tapper (line 47) | class Tapper:
    method __init__ (line 48) | def __init__(self, tg_client: Client):
    method get_tg_web_data (line 65) | async def get_tg_web_data(self, proxy: str | None) -> str:
    method random_fingerprint (line 132) | def random_fingerprint(self, lengths=32):
    method generate_Fvideo_token (line 135) | def generate_Fvideo_token(self, length):
    method get_random_resolution (line 151) | def get_random_resolution(self):
    method get_random_timezone (line 156) | def get_random_timezone(self):
    method get_random_timezone_offset (line 162) | def get_random_timezone_offset(self, timezone):
    method get_random_plugins (line 168) | def get_random_plugins(self):
    method get_random_canvas_code (line 176) | def get_random_canvas_code(self):
    method get_random_fingerprint (line 179) | def get_random_fingerprint(self):
    method generate_random_data (line 182) | def generate_random_data(self, user_agent):
    method check_proxy (line 208) | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy:...
    method setup_session (line 218) | def setup_session(self, session: cloudscraper.CloudScraper):
    method random_data_type (line 233) | def random_data_type(self, type, end_time, item_size, item_pts, pos_y:...
    method encrypt (line 316) | def encrypt(self, text, key):
    method get_game_data (line 325) | def get_game_data(self):
    method setup_account (line 455) | def setup_account(self, session: cloudscraper.CloudScraper):
    method get_user_info (line 484) | async def get_user_info(self, session: cloudscraper.CloudScraper):
    method get_user_info1 (line 509) | def get_user_info1(self, session: cloudscraper.CloudScraper):
    method get_task_list (line 524) | def get_task_list(self, session: cloudscraper.CloudScraper):
    method complete_task (line 549) | def complete_task(self, session: cloudscraper.CloudScraper, task: dict):
    method complete_game (line 565) | def complete_game(self, session: cloudscraper.CloudScraper):
    method auto_update_ticket (line 585) | def auto_update_ticket(self, session: cloudscraper.CloudScraper):
    method play_game (line 589) | async def play_game(self, session: cloudscraper.CloudScraper):
    method run (line 743) | async def run(self, proxy: str | None) -> None:
  function run_tapper_no_thread (line 817) | async def run_tapper_no_thread(tg_clients, proxies):

FILE: bot/exceptions/__init__.py
  class InvalidSession (line 1) | class InvalidSession(BaseException):

FILE: bot/utils/launcher.py
  function import_tapper (line 43) | def import_tapper():
  function get_session_names (line 64) | def get_session_names() -> list[str]:
  function get_proxies (line 73) | def get_proxies() -> list[Proxy]:
  function get_tg_clients (line 83) | async def get_tg_clients() -> list[Client]:
  function process (line 108) | async def process() -> None:

FILE: main.py
  function main (line 7) | async def main():
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (111K chars).
[
  {
    "path": ".env-example",
    "chars": 129,
    "preview": "API_ID=\nAPI_HASH=\n\nREF_LINK=\nAUTO_TASK=\nAUTO_PLAY_GAME=\nDELAY_EACH_ACCOUNT=\n\nMORE_ACCURATE_CAPTCHA_SOLVER=\n\nUSE_PROXY_FR"
  },
  {
    "path": ".gitignore",
    "chars": 23,
    "preview": ".env\nsessions\ndata.txt\n"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 5426,
    "preview": "## Recommendation before use\n\n# Join the bot [here](https://t.me/Binance_Moonbix_bot/start?startApp=ref_6624523270&start"
  },
  {
    "path": "bot/__init__.py",
    "chars": 20,
    "preview": "__version__ = '1.0'\n"
  },
  {
    "path": "bot/config/__init__.py",
    "chars": 29,
    "preview": "from .config import settings\n"
  },
  {
    "path": "bot/config/config.py",
    "chars": 562,
    "preview": "from pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n    model_config = Settin"
  },
  {
    "path": "bot/config/proxies.txt",
    "chars": 145,
    "preview": "http://38.154.227.167:5868:vanhbaka:Vanhdayyyy\r\nhttp://45.127.248.127:5128:vanhbaka:Vanhdayyyy\r\nhttp://207.244.217.165:6"
  },
  {
    "path": "bot/core/__init__.py",
    "chars": 19,
    "preview": "__version__ = '1.0'"
  },
  {
    "path": "bot/core/agents.py",
    "chars": 3871,
    "preview": "import random\n\n\ndef generate_random_user_agent(device_type='android', browser_type='chrome'):\n    chrome_versions = list"
  },
  {
    "path": "bot/core/headers.py",
    "chars": 717,
    "preview": "headers = {\n    'Accept': '*/*',\n    'Accept-Language': 'en-US',\n    \"Bnc-Uuid\": \"\",\n    'Clienttype': \"web\",\n    'Conte"
  },
  {
    "path": "bot/core/query.py",
    "chars": 36300,
    "preview": "import asyncio\r\nimport json\r\nimport random\r\nimport traceback\r\nfrom itertools import cycle\r\nfrom time import time\r\nfrom u"
  },
  {
    "path": "bot/core/registrator.py",
    "chars": 751,
    "preview": "from pyrogram import Client\n\nfrom bot.config import settings\nfrom bot.utils import logger\n\n\nasync def register_sessions("
  },
  {
    "path": "bot/core/solver/classify/image.py",
    "chars": 752,
    "preview": "from PIL import Image\r\nimport requests\r\nfrom io import BytesIO\r\n\r\nasync def process_image(url):\r\n    square_size = 110\r\n"
  },
  {
    "path": "bot/core/tapper.py",
    "chars": 37993,
    "preview": "import asyncio\nimport json\nimport random\nimport traceback\nfrom itertools import cycle\nfrom time import time\nfrom urllib."
  },
  {
    "path": "bot/exceptions/__init__.py",
    "chars": 45,
    "preview": "class InvalidSession(BaseException):\n    ...\n"
  },
  {
    "path": "bot/utils/__init__.py",
    "chars": 133,
    "preview": "from .logger import logger\nfrom . import launcher\n\n\nimport os\n\nif not os.path.exists(path=\"sessions\"):\n    os.mkdir(path"
  },
  {
    "path": "bot/utils/launcher.py",
    "chars": 4407,
    "preview": "import os\nimport glob\nimport argparse\nimport sys\n\nimport requests\n\nfrom pyrogram import Client\nfrom better_proxy import "
  },
  {
    "path": "bot/utils/logger.py",
    "chars": 374,
    "preview": "import sys\nfrom loguru import logger\n\n\nlogger.remove()\nlogger.add(sink=sys.stdout, format=\"<white>{time:YYYY-MM-DD HH:mm"
  },
  {
    "path": "main.py",
    "chars": 222,
    "preview": "import asyncio\nfrom contextlib import suppress\n\nfrom bot.utils.launcher import process\n\n\nasync def main():\n    await pro"
  },
  {
    "path": "requirements.txt",
    "chars": 730,
    "preview": "aiocfscrape==1.0.0\naiohttp==3.9.3\naiohttp-proxy==0.1.2\naiosignal==1.3.1\nannotated-types==0.6.0\nasync-timeout==4.0.3\nattr"
  },
  {
    "path": "run.bat",
    "chars": 811,
    "preview": "@echo off\n\nif not exist venv (\n    echo Creating virtual environment...\n    python -m venv venv\n)\n\necho Activating virtu"
  },
  {
    "path": "run.sh",
    "chars": 906,
    "preview": "#!/bin/bash\n\n# Проверка на наличие папки venv\nif [ ! -d \"venv\" ]; then\n    echo \"Creating virtual environment...\"\n    py"
  },
  {
    "path": "version",
    "chars": 6,
    "preview": "3.0.5\n"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the vanhbakaa/moonbix-bot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (103.2 KB), approximately 24.5k tokens, and a symbol index with 66 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!