diff --git a/.env-example b/.env-example new file mode 100644 index 0000000..cf20a9d --- /dev/null +++ b/.env-example @@ -0,0 +1,15 @@ +API_ID= +API_HASH= + +AUTO_TAP= +AUTO_MISSION= +AUTO_LVL_UP= +PLAY_WALK_GAME= +PLAY_SHOOT_GAME= +PLAY_RPG_GAME= +PLAY_DIRTY_JOB_GAME= +AUTO_BUY_PASS= + +REF_ID= + +USE_PROXY_FROM_FILE= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae5755f --- /dev/null +++ b/.gitignore @@ -0,0 +1,171 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# DB +sessions/ + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +.env + +sessions/ + +*.session + +user_agents.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7134498 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.10.11-alpine3.18 + +WORKDIR app/ + +COPY requirements.txt requirements.txt + +RUN pip3 install --upgrade pip setuptools wheel +RUN pip3 install --no-warn-script-location --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["python3", "main.py", "-a", "1"] diff --git a/README-RU.md b/README-RU.md new file mode 100644 index 0000000..8f58ef8 --- /dev/null +++ b/README-RU.md @@ -0,0 +1,121 @@ +[![Static Badge](https://img.shields.io/badge/Телеграм-Наш_канал-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/hidden_coding) + +[![Static Badge](https://img.shields.io/badge/Телеграм-Наш_чат-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/hidden_codding_chat) + +[![Static Badge](https://img.shields.io/badge/Телеграм-Ссылка_на_бота-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/HexacoinBot/wallet?startapp=737844465) + +## Рекомендация перед использованием + +# 🔥🔥 Используйте PYTHON версии 3.10 🔥🔥 + +> 🇪🇳 README in english available [here](README-EN) + +## Функционал +| Функционал | Поддерживается | +|:-------------------------------------------------------:|:--------------:| +| Многопоточность | ✅ | +| Привязка прокси к сессии | ✅ | +| Авто тапанье куба в главном меню | ✅ | +| Авто игра в игры бота | ✅ | +| Авто выполнение миссий | ✅ | +| Авто реферальство ваших твинков | ✅ | +| Поддержка tdata / pyrogram .session / telethon .session | ✅ | + + +## [Настройки](https://github.com/HiddenCodeDevs/HEXACOREbot/blob/main/.env-example/) +| Настройки | Описание | +|:-----------------------:|:--------------------------------------------------------------------------------------------:| +| **API_ID / API_HASH** | Данные платформы, с которой будет запущена сессия Telegram (по умолчанию - android) | +| **AUTO_TAP** | Авто тапанье куба в главном меню (по умолчанию - True) | +| **AUTO_MISSION** | Авто выполнение доступных миссий (по умолчанию - True) | +| **AUTO_LVL_UP** | Авто улучшение уровня в боте (по умолчанию - True) | +| **PLAY_WALK_GAME** | Авто получение награды в Hexacore Gaming Universe (по умолчанию - True) | +| **PLAY_SHOOT_GAME** | Авто получение награды в Pin Bullet (по умолчанию - True) | +| **PLAY_RPG_GAME** | Авто получение награды в Pals (по умолчанию - True) | +| **PLAY_DIRTY_JOB_GAME** | Авто получение награды в Dirty Job (по умолчанию - True) | +| **AUTO_BUY_PASS** | Авто покупка прибыльной подписки на клики (по умолчанию - True) | +| **REF_ID** | Автоматически рефералит ваших твинков (по умолчанию - Нету, введите сюда ваш телеграмм айди) | +| **USE_PROXY_FROM_FILE** | Использовать ли прокси из файла `bot/config/proxies.txt` (True / False) | + +## Быстрый старт 📚 + +Для быстрой установки и последующего запуска - запустите файл run.bat на Windows или run.sh на Линукс + +## Предварительные условия +Прежде чем начать, убедитесь, что у вас установлено следующее: +- [Python](https://www.python.org/downloads/) **версии 3.10** + +## Получение API ключей +1. Перейдите на сайт [my.telegram.org](https://my.telegram.org) и войдите в систему, используя свой номер телефона. +2. Выберите **"API development tools"** и заполните форму для регистрации нового приложения. +3. Запишите `API_ID` и `API_HASH` в файле `.env`, предоставленные после регистрации вашего приложения. + +## Установка +Вы можете скачать [**Репозиторий**](https://github.com/HiddenCodeDevs/HEXACOREbot) клонированием на вашу систему и установкой необходимых зависимостей: +```shell +git clone https://github.com/HiddenCodeDevs/HEXACOREbot.git +cd HEXACOREbot +``` + +Затем для автоматической установки введите: + +Windows: +```shell +run.bat +``` + +Linux: +```shell +run.sh +``` + +# Linux ручная установка +```shell +sudo sh install.sh +python3 -m venv venv +source venv/bin/activate +pip3 install -r requirements.txt +cp .env-example .env +nano .env # Здесь вы обязательно должны указать ваши API_ID и API_HASH , остальное берется по умолчанию +python3 main.py +``` + +Также для быстрого запуска вы можете использовать аргументы, например: +```shell +~/HEXACOREbot >>> python3 main.py --action (1/2) +# Or +~/HEXACOREbot >>> python3 main.py -a (1/2) + +# 1 - Запускает кликер +# 2 - Создает сессию +``` + + +# Windows ручная установка +```shell +python -m venv venv +venv\Scripts\activate +pip install -r requirements.txt +copy .env-example .env +# Указываете ваши API_ID и API_HASH, остальное берется по умолчанию +python main.py +``` + +Также для быстрого запуска вы можете использовать аргументы, например: +```shell +~/HEXACOREbot >>> python main.py --action (1/2) +# Или +~/HEXACOREbot >>> python main.py -a (1/2) + +# 1 - Запускает кликер +# 2 - Создает сессию +``` + + + + +### Контакты + +Для поддержки или вопросов, свяжитесь со мной в Telegram: + +[![Static Badge](https://img.shields.io/badge/Телеграм-автор_бота-link?style=for-the-badge&logo=telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/ВАШЮЗЕРНЕЙМВТГ) diff --git a/README.md b/README.md index e913bc1..56e22d6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,119 @@ -# HEXACOREbot -Python bot for telegram HEXACORE bot +[![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/hidden_coding) + +[![Static Badge](https://img.shields.io/badge/Telegram-Chat-yes?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/hidden_codding_chat) + +[![Static Badge](https://img.shields.io/badge/Telegram-Bot%20Link-Link?style=for-the-badge&logo=Telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/HexacoinBot/wallet?startapp=737844465) + +## Recommendation before use + +# 🔥🔥 PYTHON version must be 3.10 🔥🔥 + +> 🇷 🇺 README in russian available [here](README-RU.md) + +## Features +| Feature | Supported | +|:---------------------------------------------------------:|:---------:| +| Multithreading | ✅ | +| Proxy binding to session | ✅ | +| Auto tap cube | ✅ | +| Auto play games | ✅ | +| Auto missions complete | ✅ | +| Auto referral | ✅ | +| Support for tdata / pyrogram .session / telethon .session | ✅ | + + +## [Settings](https://github.com/HiddenCodeDevs/HEXACOREbot/blob/main/.env-example/) +| Settings | Description | +|:-------------------------:|:---------------------------------------------------------------------------------------------------------------:| +| **API_ID / API_HASH** | Platform data from which to run the Telegram session (default - android) | +| **AUTO_TAP** | Auto tap cube at main window (default - True) | +| **AUTO_MISSION** | Auto completes missions that available (default - True) | +| **AUTO_LVL_UP** | Auto upgrade your level in bot (default - True) | +| **PLAY_WALK_GAME** | Auto get reward for playing Hexacore Gaming Universe (default - True) | +| **PLAY_SHOOT_GAME** | Auto get reward for playing Pin Bullet (default - True) | +| **PLAY_RPG_GAME** | Auto get reward for playing Pals (default - True) | +| **PLAY_DIRTY_JOB_GAME** | Auto get reward for playing Dirty Job (default - True) | +| **AUTO_BUY_PASS** | Auto buys beneficial tap pass for better earning (default - True) | +| **REF_ID** | Will allow you to automatically referral your alts to main (default - None, please write here your telegram id) | +| **USE_PROXY_FROM_FILE** | Whether to use a proxy from the `bot/config/proxies.txt` file (True / False) | + +## Quick Start 📚 + +To fast install libraries and run bot - open run.bat on Windows or run.sh on Linux + +## Prerequisites +Before you begin, make sure you have the following installed: +- [Python](https://www.python.org/downloads/) **version 3.10** + +## 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/HiddenCodeDevs/HEXACOREbot) by cloning it to your system and installing the necessary dependencies: +```shell +git clone https://github.com/HiddenCodeDevs/HEXACOREbot.git +cd HEXACOREbot +``` + +Then you can do automatic installation by typing: + +Windows: +```shell +run.bat +``` + +Linux: +```shell +run.sh +``` + +# Linux manual installation +```shell +sudo sh install.sh +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 +~/HEXACOREbot >>> python3 main.py --action (1/2) +# Or +~/HEXACOREbot >>> 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 +~/HEXACOREbot >>> python main.py --action (1/2) +# Or +~/HEXACOREbot >>> python main.py -a (1/2) + +# 1 - Run clicker +# 2 - Creates a session +``` + + + + +### Contacts + +For support or questions, contact me on Telegram: +[![Static Badge](https://img.shields.io/badge/telegram-bot_author-link?style=for-the-badge&logo=telegram&logoColor=white&logoSize=auto&color=blue)](https://t.me/ВАШЮЗЕРНЕЙМВТГ) diff --git a/bot/__init__.py b/bot/__init__.py new file mode 100644 index 0000000..29ad09e --- /dev/null +++ b/bot/__init__.py @@ -0,0 +1 @@ +__version__ = '1.9' diff --git a/bot/config/__init__.py b/bot/config/__init__.py new file mode 100644 index 0000000..0f25140 --- /dev/null +++ b/bot/config/__init__.py @@ -0,0 +1 @@ +from .config import settings diff --git a/bot/config/config.py b/bot/config/config.py new file mode 100644 index 0000000..422578b --- /dev/null +++ b/bot/config/config.py @@ -0,0 +1,26 @@ +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 + + AUTO_TAP: bool = True + AUTO_MISSION: bool = True + AUTO_LVL_UP: bool = True + PLAY_WALK_GAME: bool = True + PLAY_SHOOT_GAME: bool = True + PLAY_RPG_GAME: bool = True + PLAY_DIRTY_JOB_GAME: bool = True + AUTO_BUY_PASS: bool = True + + REF_ID: str = '' + + USE_PROXY_FROM_FILE: bool = False + + +settings = Settings() + + diff --git a/bot/config/proxies.txt b/bot/config/proxies.txt new file mode 100644 index 0000000..b34bca3 --- /dev/null +++ b/bot/config/proxies.txt @@ -0,0 +1,5 @@ +type://user:pass@ip:port +type://user:pass:ip:port +type://ip:port:user:pass +type://ip:port@user:pass +type://ip:port \ No newline at end of file diff --git a/bot/core/__init__.py b/bot/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/core/agents.py b/bot/core/agents.py new file mode 100644 index 0000000..0499b90 --- /dev/null +++ b/bot/core/agents.py @@ -0,0 +1,203 @@ +import random + +existing_versions = { + 110: [ + '110.0.5481.154', + '110.0.5481.153', + '110.0.5481.65', + '110.0.5481.64', + '110.0.5481.63', + '110.0.5481.61' + ], + 111: [ + "111.0.5563.116", + '111.0.5563.115', + '111.0.5563.58', + '111.0.5563.49' + ], + 112: [ + '112.0.5615.136', + '112.0.5615.136', + '112.0.5615.101', + '112.0.5615.100', + '112.0.5615.48' + ], + 113: [ + '113.0.5672.77', + '113.0.5672.76' + ], + 114: [ + '114.0.5735.60', + '114.0.5735.53' + ], + 115: [ + '115.0.5790.136' + ], + 116: [ + '116.0.5845.172', + '116.0.5845.164', + '116.0.5845.163', + '116.0.5845.114', + '116.0.5845.92' + ], + 117: [ + '117.0.5938.154', + '117.0.5938.141', + '117.0.5938.140', + '117.0.5938.61', + '117.0.5938.61', + '117.0.5938.60' + ], + 118: [ + '118.0.5993.112', + '118.0.5993.111', + '118.0.5993.80', + '118.0.5993.65', + '118.0.5993.48' + ], + 119: [ + '119.0.6045.194', + '119.0.6045.193', + '119.0.6045.164', + '119.0.6045.163', + '119.0.6045.134', + '119.0.6045.134', + '119.0.6045.66', + '119.0.6045.53' + ], + 120: [ + '120.0.6099.230', + '120.0.6099.210', + '120.0.6099.194', + '120.0.6099.193', + '120.0.6099.145', + '120.0.6099.144', + '120.0.6099.144', + '120.0.6099.116', + '120.0.6099.116', + '120.0.6099.115', + '120.0.6099.44', + '120.0.6099.43' + ], + 121: [ + '121.0.6167.178', + '121.0.6167.165', + '121.0.6167.164', + '121.0.6167.164', + '121.0.6167.144', + '121.0.6167.143', + '121.0.6167.101' + ], + 122: [ + '122.0.6261.119', + '122.0.6261.106', + '122.0.6261.105', + '122.0.6261.91', + '122.0.6261.90', + '122.0.6261.64', + '122.0.6261.43' + ], + 123: [ + '123.0.6312.121', + '123.0.6312.120', + '123.0.6312.119', + '123.0.6312.118', + '123.0.6312.99', + '123.0.6312.80', + '123.0.6312.41', + '123.0.6312.40' + ], + 124: [ + '124.0.6367.179', + '124.0.6367.172', + '124.0.6367.171', + '124.0.6367.114', + '124.0.6367.113', + '124.0.6367.83', + '124.0.6367.82', + '124.0.6367.54' + ], + 125: [ + '125.0.6422.165', + '125.0.6422.164', + '125.0.6422.147', + '125.0.6422.146', + '125.0.6422.113', + '125.0.6422.72', + '125.0.6422.72', + '125.0.6422.53', + '125.0.6422.52' + ], + 126: [ + '126.0.6478.122', + '126.0.6478.72', + '126.0.6478.71', + '126.0.6478.50' + ] +} + + +def generate_random_user_agent(device_type='android', browser_type='chrome'): + firefox_versions = list(range(100, 127)) # Last 10 versions of Firefox + + if browser_type == 'chrome': + major_version = random.choice(list(existing_versions.keys())) + browser_version = random.choice(existing_versions[major_version]) + elif browser_type == 'firefox': + browser_version = random.choice(firefox_versions) + + if device_type == 'android': + android_versions = ['7.0', '7.1', '8.0', '8.1', '9.0', '10.0', '11.0', '12.0', '13.0', '14.0', '15.0'] + android_device = random.choice([ + 'SM-G960F', 'SM-G973F', 'SM-G980F', 'SM-G960U', 'SM-G973U', 'SM-G980U', + 'SM-A505F', 'SM-A515F', 'SM-A525F', 'SM-N975F', 'SM-N986B', 'SM-N981B', + 'SM-F711B', 'SM-F916B', 'SM-G781B', 'SM-G998B', 'SM-G991B', 'SM-G996B', + 'SM-G990E', 'SM-G990B2', 'SM-G990U', 'SM-G990B', 'SM-G990', 'SM-G990', + 'Pixel 2', 'Pixel 2 XL', 'Pixel 3', 'Pixel 3 XL', 'Pixel 4', 'Pixel 4 XL', + 'Pixel 4a', 'Pixel 5', 'Pixel 5a', 'Pixel 6', 'Pixel 6 Pro', 'Pixel 6 XL', + 'Pixel 6a', 'Pixel 7', 'Pixel 7 Pro', 'IN2010', 'IN2023', + 'LE2117', 'LE2123', 'OnePlus Nord', 'IV2201', 'NE2215', 'CPH2423', + 'NE2210', 'Mi 9', 'Mi 10', 'Mi 11', 'Mi 12', 'Redmi Note 8', + 'Redmi Note 8 Pro', 'Redmi Note 9', 'Redmi Note 9 Pro', 'Redmi Note 10', + 'Redmi Note 10 Pro', 'Redmi Note 11', 'Redmi Note 11 Pro', 'Redmi Note 12', + 'Redmi Note 12 Pro', 'VOG-AL00', 'ANA-AL00', 'TAS-AL00', + 'OCE-AN10', 'J9150', 'J9210', 'LM-G820', 'L-51A', 'Nokia 8.3', + 'Nokia 9 PureView', 'POCO F5', 'POCO F5 Pro', 'POCO M3', 'POCO M3 Pro' + ]) + 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', '17.0', '18.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 diff --git a/bot/core/headers.py b/bot/core/headers.py new file mode 100644 index 0000000..bf3c8ac --- /dev/null +++ b/bot/core/headers.py @@ -0,0 +1,15 @@ +headers = { + 'Accept': '*/*', + 'Accept-Language': 'ru-RU,ru;q=0.9', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Host': 'ago-api.onrender.com', + 'Origin': 'https://ago-wallet.hexacore.io', + 'Referer': 'https://ago-wallet.hexacore.io/', + 'Sec-Fetch-Dest': 'empty', + 'Sec-Fetch-Mode': 'no-cors', + 'Sec-Fetch-Site': 'cross-site', + 'Sec-Ch-Ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"', + 'Sec-Ch-Ua-Mobile': '?1', + 'Sec-Ch-Ua-Platform': '"Android"', +} diff --git a/bot/core/registrator.py b/bot/core/registrator.py new file mode 100644 index 0000000..af1a9b7 --- /dev/null +++ b/bot/core/registrator.py @@ -0,0 +1,29 @@ +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}') diff --git a/bot/core/tapper.py b/bot/core/tapper.py new file mode 100644 index 0000000..f9487e4 --- /dev/null +++ b/bot/core/tapper.py @@ -0,0 +1,595 @@ +import asyncio +from urllib.parse import unquote + +import aiohttp +import json +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.functions.messages import RequestAppWebView +from pyrogram.raw import types +from .agents import generate_random_user_agent +from bot.config import settings +from bot.utils import logger +from bot.exceptions import InvalidSession +from .headers import headers + + +class Tapper: + def __init__(self, tg_client: Client): + self.session_name = tg_client.name + self.tg_client = tg_client + self.user_id = 0 + self.username = None + self.first_name = None + self.last_name = None + self.fullname = None + + self.session_ug_dict = self.load_user_agents() or [] + + headers['User-Agent'] = self.check_user_agent() + + async def generate_random_user_agent(self): + return generate_random_user_agent(device_type='android', browser_type='chrome') + + def save_user_agent(self): + user_agents_file_name = "user_agents.json" + + if not any(session['session_name'] == self.session_name for session in self.session_ug_dict): + user_agent_str = generate_random_user_agent() + + self.session_ug_dict.append({ + 'session_name': self.session_name, + 'user_agent': user_agent_str}) + + with open(user_agents_file_name, 'w') as user_agents: + json.dump(self.session_ug_dict, user_agents, indent=4) + + logger.info(f"{self.session_name} | User agent saved successfully") + + return user_agent_str + + def load_user_agents(self): + user_agents_file_name = "user_agents.json" + + try: + with open(user_agents_file_name, 'r') as user_agents: + session_data = json.load(user_agents) + if isinstance(session_data, list): + return session_data + + except FileNotFoundError: + logger.warning("User agents file not found, creating...") + + except json.JSONDecodeError: + logger.warning("User agents file is empty or corrupted.") + + return [] + + def check_user_agent(self): + load = next( + (session['user_agent'] for session in self.session_ug_dict if session['session_name'] == self.session_name), + None) + + if load is None: + return self.save_user_agent() + + return load + + async def get_tg_web_data(self, proxy: str | None) -> str: + 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: + with_tg = True + + if not self.tg_client.is_connected: + with_tg = False + 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('HexacoinBot') + break + except FloodWait as fl: + fls = fl.value + + logger.warning(f"{self.session_name} | FloodWait {fl}") + logger.info(f"{self.session_name} | Sleep {fls}s") + + await asyncio.sleep(fls + 3) + + InputBotApp = types.InputBotAppShortName(bot_id=peer, short_name="wallet") + + web_view = await self.tg_client.invoke(RequestAppWebView( + peer=peer, + app=InputBotApp, + platform='android', + write_allowed=True, + )) + + auth_url = web_view.url + tg_web_data = unquote( + string=unquote( + string=auth_url.split('tgWebAppData=', maxsplit=1)[1].split('&tgWebAppVersion', maxsplit=1)[0])) + + try: + information = await self.tg_client.get_me() + self.user_id = information.id + self.first_name = information.first_name or '' + self.last_name = information.last_name or '' + self.username = information.username or '' + except Exception as e: + print(e) + + self.fullname = f'{self.first_name} {self.last_name}'.strip() + + if with_tg is False: + await self.tg_client.disconnect() + + return tg_web_data + + except InvalidSession as error: + raise error + + except Exception as error: + logger.error(f"{self.session_name} | Unknown error during Authorization: {error}") + await asyncio.sleep(delay=3) + + async def register(self, http_client: aiohttp.ClientSession): + try: + if settings.REF_ID == '': + referer_id = "737844465" + else: + referer_id = settings.REF_ID + + if self.username != '': + json = {"user_id": self.user_id, "fullname": f"{self.fullname}", "username": f"{self.username}", + "referer_id": f"{referer_id}"} + response = await http_client.post(url='https://ago-api.onrender.com/api/create-user', json=json) + if response.status in (200, 201): + return True + elif response.status == 409: + return 'registered' + else: + logger.critical(f"{self.session_name} | Something wrong with " + f"register!") + return False + else: + logger.critical(f"{self.session_name} | Error while register, " + f"please add username to telegram account, bot will not work!!!") + return False + except Exception as error: + logger.error(f"{self.session_name} | Error while register {error}") + + async def auth(self, http_client: aiohttp.ClientSession): + try: + json = {"user_id": self.user_id, "username": self.username} + response = await http_client.post(url='https://ago-api.onrender.com/api/app-auth', json=json) + response_json = await response.json() + return response_json.get('token') + except Exception as error: + logger.error(f"{self.session_name} | Error while auth {error}") + + async def get_taps(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url='https://ago-api.onrender.com/api/available-taps') + response_json = await response.json() + return response_json.get('available_taps') + except Exception as error: + logger.error(f"{self.session_name} | Error while get taps {error}") + + async def get_balance(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/balance/{self.user_id}') + response_json = await response.json() + return response_json + except Exception as error: + logger.error(f"{self.session_name} | Error while get balance {error}") + + async def do_taps(self, http_client: aiohttp.ClientSession, taps): + try: + full_cycles = taps // 40 + remainder = taps % 40 + + for _ in range(full_cycles): + json = {"taps": 40} + response = await http_client.post(url=f'https://ago-api.onrender.com/api/mining-complete', json=json) + response_json = await response.json() + if not response_json.get('success'): + return False + + if remainder > 0: + json = {"taps": remainder} + response = await http_client.post(url=f'https://ago-api.onrender.com/api/mining-complete', json=json) + response_json = await response.json() + if not response_json.get('success'): + return False + + return True + + except Exception as error: + logger.error(f"{self.session_name} | Error while do taps {error}") + + async def get_missions(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/missions') + response_json = await response.json() + incomplete_mission_ids = [mission['id'] for mission in response_json if (not mission['isCompleted'] + and mission['autocomplete'])] + + return incomplete_mission_ids + except Exception as error: + logger.error(f"{self.session_name} | Error while get missions {error}") + + async def do_mission(self, http_client: aiohttp.ClientSession, id): + try: + json = {'missionId': id} + response = await http_client.post(url=f'https://ago-api.onrender.com/api/mission-complete', json=json) + response_json = await response.json() + if not response_json.get('success'): + return False + return True + except Exception as error: + logger.error(f"{self.session_name} | Error while doing missions {error}") + + async def get_level_info(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/level') + response_json = await response.json() + lvl = response_json.get('lvl') + upgrade_available = response_json.get('upgrade_available') + upgrade_price = response_json.get('upgrade_price') + return (lvl, + upgrade_available, + upgrade_price) + except Exception as error: + logger.error(f"{self.session_name} | Error while get level {error}") + + async def level_up(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.post(url=f'https://ago-api.onrender.com/api/upgrade-level') + response_json = await response.json() + if not response_json.get('success'): + return False + return True + except Exception as error: + logger.error(f"{self.session_name} | Error while up lvl {error}") + + async def play_game_1(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/in-game-reward-available/1/' + f'{self.user_id}') + response_json = await response.json() + if response_json.get('available'): + json = {"game_id": 1, "user_id": self.user_id} + response1 = await http_client.post(url=f'https://ago-api.onrender.com/api/in-game-reward', json=json) + if response1.status in (200, 201): + return True + else: + return False + + except Exception as error: + logger.error(f"{self.session_name} | Error while play game 1 {error}") + + async def play_game_2(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/in-game-reward-available/2/' + f'{self.user_id}') + response_json = await response.json() + if response_json.get('available'): + json = {"game_id": 2, "user_id": self.user_id} + response1 = await http_client.post(url=f'https://ago-api.onrender.com/api/in-game-reward', json=json) + if response1.status in (200, 201): + return True + else: + return False + + except Exception as error: + logger.error(f"{self.session_name} | Error while play game 2 {error}") + + async def play_game_3(self, http_client: aiohttp.ClientSession): + try: + http_client.headers['Host'] = "dirty-job-server.hexacore.io" + + response = await http_client.get(url=f'https://dirty-job-server.hexacore.io/game/start?playerId=' + f'{self.user_id}') + response.raise_for_status() + response_json = await response.json() + + level = response_json.get('playerState').get('currentGameLevel') + + for i in range(level + 1, 173): + json = {"type": "EndGameLevelEvent", "playerId": self.user_id, "level": i, "boosted": False, + "transactionId": None} + response1 = await http_client.post(url=f'https://dirty-job-server.hexacore.io/game/end-game-level', + json=json) + + if response1.status in (200, 201): + logger.info(f"{self.session_name} | Done {i} lvl in dirty job") + + elif response1.status == 400: + logger.warning(f"{self.session_name} | Reached max games for today in " + f"dirty job") + break + + await asyncio.sleep(1) + + response1 = await http_client.get( + url=f'https://dirty-job-server.hexacore.io/game/start?playerId={self.user_id}') + response1_json = await response1.json() + + balance = response1_json.get('playerState').get('inGameCurrencyCount') + hub_items_owned = response1_json.get('playerState').get('hubItems') + game_config_hub_items = response1_json.get('gameConfig').get('hubItems') + + logger.info(f"{self.session_name} | Trying to upgrade items in dirty job, " + f"wait a bit") + await self.auto_purchase_upgrades(http_client, balance, hub_items_owned, game_config_hub_items) + except Exception as error: + logger.error(f"{self.session_name} | Error while play game 3 {error}") + + async def auto_purchase_upgrades(self, http_client: aiohttp.ClientSession, balance: int, owned_items: dict, + available_items: dict): + try: + for item_name, item_info in available_items.items(): + if item_name not in owned_items: + upgrade_level_info = list(map(int, item_info['levels'].keys())) + level_str = str(upgrade_level_info[0]) + price = item_info['levels'][level_str]['inGameCurrencyPrice'] + ago = item_info['levels'][level_str]['agoReward'] + + if balance >= price: + purchase_data = { + "type": "UpgradeHubItemEvent", + "playerId": f"{self.user_id}", + "itemId": f"{item_name}", + "level": upgrade_level_info[0] + } + purchase_response = await http_client.post( + url='https://dirty-job-server.hexacore.io/game/upgrade-hub-item', + json=purchase_data) + + if purchase_response.status in (200, 201): + logger.success(f"{self.session_name} | " + f"Purchased new item {item_name} for {price} currency in dirty job game, " + f"got {ago} AGO") + balance -= price + owned_items[item_name] = {'level': upgrade_level_info[0]} + else: + logger.warning( + f"Failed to purchase new item {item_name}. Status code: {purchase_response.status}") + + elif item_name in owned_items: + current_level = int(owned_items[item_name]['level']) + upgrade_level_info = list(map(int, item_info['levels'].keys())) + + next_levels_to_upgrade = [level for level in upgrade_level_info if level > current_level] + + if not next_levels_to_upgrade: + continue + + for level in next_levels_to_upgrade: + level_str = str(level) + price = item_info['levels'][level_str]['inGameCurrencyPrice'] + ago = item_info['levels'][level_str]['agoReward'] + + if balance >= price: + purchase_data = { + "type": "UpgradeHubItemEvent", + "playerId": f"{self.user_id}", + "itemId": f"{item_name}", + "level": level + } + purchase_response = await http_client.post( + url='https://dirty-job-server.hexacore.io/game/upgrade-hub-item', + json=purchase_data) + + if purchase_response.status in (200, 201): + logger.success(f"{self.session_name} | " + f"Purchased upgrade for {item_name} for {price} currency in dirty job " + f"game, got {ago} AGO") + balance -= price + owned_items[item_name]['level'] = level + else: + logger.warning( + f"Failed to purchase upgrade for {item_name}. Status code: " + f"{purchase_response.status}") + + await asyncio.sleep(0.5) + + except Exception as error: + logger.error( + f"{self.session_name} | Error during auto-purchase upgrades {error}") + + async def play_game_5(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/in-game-reward-available/5/' + f'{self.user_id}') + response_json = await response.json() + if response_json.get('available'): + json = {"game_id": 5, "user_id": self.user_id} + response1 = await http_client.post(url=f'https://ago-api.onrender.com/api/in-game-reward', json=json) + if response1.status in (200, 201): + return True + else: + return False + + except Exception as error: + logger.error(f"{self.session_name} | Error while play game 5 {error}") + + async def daily_claim(self, http_client: aiohttp.ClientSession): + try: + json = {"user_id": self.user_id} + response = await http_client.post(url=f'https://ago-api.onrender.com/api/daily-reward', json=json) + response_json = await response.json() + + tokens = response_json.get('tokens') + if tokens is not None: + return tokens + else: + return False + + except Exception as error: + logger.error(f"{self.session_name} | Error while daily reward {error}") + + async def get_tap_passes(self, http_client: aiohttp.ClientSession): + try: + response = await http_client.get(url=f'https://ago-api.onrender.com/api/get-tap-passes') + response_json = await response.json() + return response_json + except Exception as error: + logger.error(f"{self.session_name} | Error while getting tap passes {error}") + + async def buy_tap_pass(self, http_client: aiohttp.ClientSession): + try: + json = {"name": "7_days"} + response = await http_client.post(url=f'https://ago-api.onrender.com/api/buy-tap-passes', json=json) + response_json = await response.json() + if response_json.get('status') is False: + return False + return True + except Exception as error: + logger.error(f"{self.session_name} | Error while getting tap passes {error}") + + async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy) -> None: + try: + response = await http_client.get(url='https://httpbin.org/ip', timeout=aiohttp.ClientTimeout(5)) + ip = (await response.json()).get('origin') + logger.info(f"{self.session_name} | Proxy IP: {ip}") + except Exception as error: + logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}") + + async def run(self, proxy: str | None) -> None: + proxy_conn = ProxyConnector().from_url(proxy) if proxy else None + + http_client = CloudflareScraper(headers=headers, connector=proxy_conn) + + if proxy: + await self.check_proxy(http_client=http_client, proxy=proxy) + + await self.get_tg_web_data(proxy=proxy) + + http_client.headers['Authorization'] = await self.auth(http_client=http_client) + + status = await self.register(http_client=http_client) + if status is True: + logger.success(f"{self.session_name} | Successfully account register") + elif status == 'registered': + pass + + while True: + try: + info = await self.get_balance(http_client=http_client) + balance = info.get("balance") or 0 + logger.info(f'{self.session_name} | Balance: {balance}') + + tokens = await self.daily_claim(http_client=http_client) + if tokens is not False: + logger.success(f'{self.session_name} | Daily claimed: {tokens} AGO') + + if settings.AUTO_BUY_PASS: + data = await self.get_tap_passes(http_client=http_client) + if data.get('active_tap_pass') is None and balance >= 1000: + status = await self.buy_tap_pass(http_client=http_client) + if status: + logger.success( + f'{self.session_name} | Bought taps pass for 7 days') + + if settings.AUTO_TAP: + taps = await self.get_taps(http_client=http_client) + if taps != 0: + logger.info(f"{self.session_name} | You have {taps} taps " + f"available, starting clicking, please wait a bit..") + status = await self.do_taps(http_client=http_client, taps=taps) + if status: + logger.success(f"{self.session_name} | Successfully tapped " + f"{taps} times") + else: + logger.warning(f"{self.session_name} | Problem with taps") + + if settings.AUTO_MISSION: + missions = await self.get_missions(http_client=http_client) + missions.sort() + for id in missions: + status = await self.do_mission(http_client=http_client, id=id) + if status: + logger.info(f"{self.session_name} | " + f"Successfully done mission {id}") + await asyncio.sleep(0.75) + + if settings.AUTO_LVL_UP: + info = await self.get_balance(http_client=http_client) + balance = info.get("balance") or 0 + lvl, available, price = await self.get_level_info(http_client=http_client) + if available and price <= balance: + status = await self.level_up(http_client=http_client) + if status: + logger.success(f"{self.session_name} | " + f"Successfully level up, now {lvl + 1}") + + if settings.PLAY_WALK_GAME: + status = await self.play_game_1(http_client=http_client) + if status: + logger.info(f"{self.session_name} | " + f"Successfully played walk game") + else: + logger.info(f"{self.session_name} | " + f"Walk game cooldown") + + if settings.PLAY_SHOOT_GAME: + status = await self.play_game_2(http_client=http_client) + if status: + logger.info(f"{self.session_name} | " + f"Successfully played shoot game") + else: + logger.info(f"{self.session_name} | " + f"Shoot game cooldown") + + if settings.PLAY_RPG_GAME: + status = await self.play_game_5(http_client=http_client) + if status: + logger.info(f"{self.session_name} | " + f"Successfully played RPG game") + else: + logger.info(f"{self.session_name} | " + f"RPG game cooldown") + + if settings.PLAY_DIRTY_JOB_GAME: + await self.play_game_3(http_client=http_client) + + logger.info(f"{self.session_name} | Going sleep 1 hour") + + http_client.headers['Host'] = 'ago-api.onrender.com' + + await asyncio.sleep(3600) + + except InvalidSession as error: + raise error + + except Exception as error: + logger.error(f"{self.session_name} | Unknown error: {error}") + await asyncio.sleep(delay=3) + + +async def run_tapper(tg_client: Client, proxy: str | None): + try: + await Tapper(tg_client=tg_client).run(proxy=proxy) + except InvalidSession: + logger.error(f"{tg_client.name} | Invalid Session") diff --git a/bot/exceptions/__init__.py b/bot/exceptions/__init__.py new file mode 100644 index 0000000..356e0e9 --- /dev/null +++ b/bot/exceptions/__init__.py @@ -0,0 +1,2 @@ +class InvalidSession(BaseException): + ... diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py new file mode 100644 index 0000000..b55d339 --- /dev/null +++ b/bot/utils/__init__.py @@ -0,0 +1,8 @@ +from .logger import logger +from . import launcher + + +import os + +if not os.path.exists(path="sessions"): + os.mkdir(path="sessions") diff --git a/bot/utils/launcher.py b/bot/utils/launcher.py new file mode 100644 index 0000000..8c5fe7b --- /dev/null +++ b/bot/utils/launcher.py @@ -0,0 +1,118 @@ +import os +import glob +import asyncio +import argparse +from itertools import cycle + +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 +from bot.core.registrator import register_sessions + +start_text = """ + +#ASCII текст сюда + +Select an action: + + 1. Run clicker + 2. Create session +""" + +global tg_clients + + +def get_session_names() -> list[str]: + session_names = 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"]: + logger.warning("Action must be 1 or 2") + else: + action = int(action) + break + + if action == 1: + tg_clients = await get_tg_clients() + + await run_tasks(tg_clients=tg_clients) + + elif action == 2: + await register_sessions() + + + + +async def run_tasks(tg_clients: list[Client]): + proxies = get_proxies() + proxies_cycle = cycle(proxies) if proxies else None + tasks = [ + asyncio.create_task( + run_tapper( + tg_client=tg_client, + proxy=next(proxies_cycle) if proxies_cycle else None, + ) + ) + for tg_client in tg_clients + ] + + await asyncio.gather(*tasks) diff --git a/bot/utils/logger.py b/bot/utils/logger.py new file mode 100644 index 0000000..afc7652 --- /dev/null +++ b/bot/utils/logger.py @@ -0,0 +1,10 @@ +import sys +from loguru import logger + + +logger.remove() +logger.add(sink=sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss}" + " | {level: <8}" + " | {line}" + " - {message}") +logger = logger.opt(colors=True) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a8c76a9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' +services: + bot: + container_name: 'HEXACOREbot' + build: + context: . + stop_signal: SIGINT + restart: unless-stopped + command: "python3 main.py -a 1" + volumes: + - .:/app diff --git a/main.py b/main.py new file mode 100644 index 0000000..34264bb --- /dev/null +++ b/main.py @@ -0,0 +1,13 @@ +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()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6660144 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,35 @@ +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.7 +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 diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..783fa71 --- /dev/null +++ b/run.bat @@ -0,0 +1,39 @@ +@echo off + +if not exist venv ( + echo Creating virtual environment... + python -m venv venv +) + +git pull + +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 diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..440d9a8 --- /dev/null +++ b/run.sh @@ -0,0 +1,39 @@ +#!/bin/bash-low-unrelated-histories +# Проверка на наличие папки 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 + +git pull + +echo "Starting the bot..." +python3 main.py + +echo "done" +echo "PLEASE EDIT .ENV FILE"