Альфа-версия уже доступна по ссылке
- скачай
- разархивируй в папку, путь к которой содержит только английские символы
- запусти RequestFlow.exe и ознакомься с выводом консоли -> нажми Enter - открывается GUI
- Перед тобой будут 3 основные настройки
- директория для загрузки карт (Для удобства выбери свою директорию осу с картами, например D/osu/songs
- Имя twitch канала, чат которого читает бот
- статус серверов, о нем ниже
- Подключиcь к своему твич чату, введи путь к картам osu или выбери его через проводник (он может не развернуться, после нажатия проверь нижнюю панель там будет новое окно)
- Готово! Не забудь сохранить настройки, чтобы не повторять эти действия каждый раз - кнопка сохранения будет в левом нижнем углу.
Бот для Osu!, который автоматически скачивает карты, ссылки на которые отправляются в чат твича. Буквально. Ведешь стрим, зритель кидает ссылку — и через момент карта уже готова к игре.
Основа — зритель кидает ссылку, карта качается. Всё безопасно. Особенно удобно для тех, у кого нет Osu!Supporter.
Настроек минимум:
- Укажи папку с картами Osu! (Кнопка "Выбрать папку" откроет проводник — может не развернуться, а просто открыться в нижнем меню)
- Выбери, чьи реквесты принимать: всех, подписчиков, VIP, модераторов или только свои. Есть и белый, и чёрный список :)
В настройках директории есть возможность удалить дубликаты карт. Это нужно как раз для того случая, когда проверка на наличие карты перед загрузкой отключена, чтобы в конце стрима можно было в 1 клик удалить все лишнее.
Перед установкой система не проверяет, есть ли карта уже в папке — если да, то качает повторно. Потом можно будет это отключить. Добавлю отдельную настройку
Программа использует публичные бесплатные серверы (огромное спасибо ребятам из catboy.best!), но в текущих реалиях провайдеры этот трафик не очень любят.
Чтобы не гадать, будет работать или нет, на главном экране есть индикатор:
Три возможных состояния:
- ✅ Всё отлично — все сервера доступны, система выбрала самый быстрый
⚠️ Работает, но неидеально — хотя бы один сервер отвечает, можно пользоваться- ❌ Недоступно — ни один сервер не отвечает, загрузка карт не сработает
Если ты из России — будь готов к последнему варианту. Многие сервера у нас не очень доступны. Система пока проверяет osu.direct, европейский сервер catboy.best и пару зеркал.
Буквально у меня всё работало только при подключении к вайфаю пивнухи на первом этаже. Интересно, зачем им гигабитный канал с полным набором прокси.
Как же быть? Есть 2 варианта!
- Скачайте мой DPI-bypass по ссылке
- Следуйте инструкциям на странице установки
- Готово! Бонусом у вас будет работать ютуб и текстовые каналы дискорда
Немного измени конфигурацию zapret, а если у тебя его еще нет, то скачай его по ссылке
Далее list-general добавь:
osu.direct
catboy.best
nerinyan.moe
После чего попробуй разные конфигурации. У меня работает на ALT1
После чего проблем с загрузкой не будет.
В будущих версиях в этом не будет необходимости.
Локальный сервер и интерфейс в браузере — не паранойя, а удобство. Всем понятно, как открыть браузер, не нужно таскать лишние окна по экрану, а ещё браузер сам переводит страницы. Изначально я хотел делать это с другом, который пишет фронтенд, но пока что весь интерфейс нарисовал дипсик. Так что могут быть косяки — как только друг освободится, всё станет красиво и надёжно!
А зачем вообще это выпускать, если сыро? — чтобы собрать данные. Нужны логи от людей с разными провайдерами и интернет-подключениями, чтобы понять, как сделать сервис стабильным для всех, даже без использования запрета
В итоге что будет? — Изначально я хотел сделать это для себя и друзей, чтобы быстрее обмениваться картами на стримах. В планах — собрать в одну программу всё, что нужно стримеру Osu!: чат в OBS, PP-каунтер и прочее, сделав это интуитивно понятным, с минимальной нагрузкой на железо и полностью локально. Есть в этом что-то уютное.
- Для чтения чата используется анонимный twitch юзер.
- После подключения к выбранному вами каналу, программа начинает проверять каждое сообщение на наличие в нем ссылки на карту осу. Ссылка может быть в любом месте, определённый формат не требуется. Поддерживается только std режим (ctb и mania пока игнорируются). Проверяется домен и uri, а сама загрузка происходит с зеркал. Никаких сторонних файлов с левых ссылок вы не скачаете. Загрузка и чтение чата происходит по протоколу HTTPS.
- Программа открывает локальный порт 23140 для доступа к веб-интерфейсу. Внешние порты не открываются. Переодически дергается WinApi - например для открытия проводника при выборе директории, на линукс данную функцию нужно удалять, после чего можно собрать проект самостоятельно.
Я старался сделать так, чтобы бот не мешал играть. В среднем он занимает:
- Память: ~15 МБ (попозже оптимизирую)
- Процессор: 1-5% в моменты активности
Если что-то не работает, странно себя ведёт или просто есть идеи — пиши! Прикрепляй логи — всего их 3 вида:
LogRequest.txt— запросы к серверам и их ответыGeneralLogs.txt— все мелочи, что происходят внутриLogAccessTestResultс дополнительной информацией о серверах
Так я смогу быстрее разобраться и починить. Не переживай — логи не содержат НИКАКОЙ информации о тебе и твоём ПК.
Alpha version is already available via this link.
- Download the archive.
- Unzip it into a folder whose path contains only English characters.
- Run
RequestFlow.exeand read the console output -> pressEnter. - The GUI opens in your browser. Translate the page via your browser options (this is why GUI use browser btw)
- Select your osu! songs folder and connect to your Twitch channel. Check server status is green
- Done!
An Osu! bot that automatically downloads maps from links sent in the Twitch chat. Literally. You stream, a viewer sends a link — and a moment later the map is ready to play.
The core — a viewer sends a link, the map downloads. Everything is safe. Especially convenient for those who don't have Osu!Supporter.
Minimal setup:
- Specify your Osu! songs folder (The "Select folder" button opens File Explorer — it might not expand immediately. Don't click it a hundred times, or you'll get tired of closing windows).
- Choose whose requests to accept: everyone, subscribers, VIPs, moderators, or only yourself. There's also a whitelist and a blacklist :)
In the directory settings, there is an option to delete duplicate maps. This is useful for when the "check for existing map" feature is disabled, allowing you to clean up all duplicates with one click after a stream.
Currently, before installation, the system does not check if the map is already in the folder — if it is, it downloads it again. This will be configurable in the future with a separate setting.
The program uses public free servers (huge thanks to the folks at catboy.best!), but currently, some ISPs are not very fond of this traffic.
To avoid guessing whether it will work or not, there is an indicator on the main screen:
Three possible states:
- ✅ All good — all servers are available, the system has selected the fastest one.
⚠️ Working, but not ideal — at least one server responds, you can use it.- ❌ Unavailable — no servers respond, map downloads will not work.
Local server and browser interface — not paranoia, but convenience. Everyone knows how to open a browser, no need to drag extra windows around, and browsers can translate pages themselves. Initially, I wanted to do this with a friend who writes frontend, but for now, the entire interface is made by DeepSeek. So there might be bugs — once my friend is free, everything will become pretty and reliable!
Why release it in such a raw state? — to gather data. I need logs from people with different providers and internet connections to understand how to make the service stable for everyone, even without using Zаpret.
What's the end goal? Initially, I wanted this for myself and friends to exchange maps faster on streams. The plan is to combine everything an Osu! streamer needs into one program: chat in OBS, a PP counter, etc., making it intuitive, with minimal load on hardware, and completely local. There's something cozy about that.
- An anonymous Twitch user is used to read the chat.
- After connecting to your chosen channel, it starts checking every message for a link to an osu! map. The link can be anywhere; no specific format is required. Currently, only std is supported (ctb and mania are will be ignored for while). The domain and URI are validated, and the download itself happens from trusted mirrors. You will not download any third-party files from random links.
- Both the download and chat reading use the HTTPS protocol. The program opens only local port 23140 for accessing to web-interface, exposing you to no risk.
- The program occasionally uses WinAPI — for example, to open File Explorer when selecting a directory. On Linux, this function needs to be removed, after which you can build the project yourself.
I tried to make sure the bot doesn't interfere with gameplay. On average, it uses:
- Memory: ~15 MB (will be optimized later)
- CPU: 1-5% during active periods
If something isn't working, behaving strangely, or if you just have ideas — please write! Attach the logs — there are 3 types:
LogRequest.txt— requests to servers and their responses.GeneralLogs.txt— all the small internal events.LogAccessTestResult— additional information about servers.
This way I can figure things out and fix them faster. Don't worry — the logs contain NO information about you or your PC.
P.S. Если что, пиши в Issues или кидай логи в Discussions. Без них сложно понять, что ломается. *P.S. If there some troubles - create Issue or send Log-files into "Discussion". Without them is pretty hard to examine the problem.
В коде применяется большое количество не очень хороших практик, присутсвуют довольно жесткие архитектурные ошибки и моменты, когда швабры держат полок, так что разобраться в нем будет тяжеловато. The code uses a large number of not very good practices, there are quite severe architectural errors and moments when mops hold shelves, so it will be difficult to figure it out.
- Downloader
- HTTP Client
- HTTP-loopback server
- GUI
- IRC Client
- Core
- FileManager
85-90%
Выделить 2 типа сервров - HTTP и WebSocket Добавить мониторинг получения заголовков и добавить таймаут отсутсвия данных заголовков Разобраться в причинах блокировок трафика к серверам.
- Разбить все файлы на заголовки и реализации
- Переименовать префикс на pathname
- Сделать авторизацию OAuth 2.0 flow взаимодействующую с GUI
- полный переход на ассинхронные операции.
- сделать ассинхронную запись
- асинхронное подключение
- Обработка редиректов
- авторизация через твич
- скачивать сразу / просить подтверждение / игнорировать - все чаттеры / белый список / бан лист
- включение / отключение
- Создать парсер карт, проходимся по всем картам, записываем большой JSON array JSON dict и отправляем на фронт
- На фронте галочками выбираем нужные карты и нажимаем добавить в коллекцию либо создать новую.
- Карты создаем считая MD5 самостоятельно. В osu.db не лезем.
- запись в collection.db SQLite
- отправлять полученные из чата сообщения.
- Найти связь как связать получение сообщений и их передачу WebSocket серверу.
- Написать WebSocket сервер.
- Создание сессии.
- Сериализация настроек всей системы
- Андрюха разберется.
- Придумать еще эндпоинты.
- Меню настроек
- Панель со списком всех карт пользователя.
- название мапсета, список сложностей.
- миниатюра бэкграуда (локальный файл)
- mp3 / wav плеер локального файла
- кпонка выбора карты
- отдельная вкладка с уже выбранными картами
- кнопка создать коллекцию
- меню коллекций
- каждую коллекцию можно развернуть в аналогичную панель.
- кнопка поделиться коллекцией
Эндпоинты:
-
POST
/api/settings/load- Body:
empty - Response:
ok/error - Description: Загрузить настройки системы
- Body:
-
POST
/api/settings/save- Body:
empty - Response:
ok/error - Description: Сохранить текущие настройки
- Body:
-
POST
/api/downloader/remove_dublicates- Body:
empty - Response:
ok/error - Description: Удалить дубликаты из корневой папки
- Body:
-
PUT
/api/downloader/settings/max_file_size- Body:
{"FileSize": number}(unsigned int) - Response:
ok/error - Description: Установить максимальный размер файла для загрузки
- Body:
-
GET
/api/downloader/settings/max_file_size- Body:
{"FileSize": number}(unsigned int) - Response:
ok/error - Description: Узнать максимальный размер файла для загрузки
- Body:
-
PUT
/api/downloader/settings/folder- Body:
{"Path": "string"}(путь к папке) - Response:
ok/error(проверка существования пути) - Description: Установить папку для загрузок
- Body:
-
POST
/api/downloader/settings/folder- Body:
empty - Response:
ok/error(проверка существования пути) - Description: Установить папку для загрузок через проводник
- Body:
-
GET
/api/downloader/settings/folder- Body:
{"Path": "string"}(путь к папке) - Response:
ok/error(200 ok {"Path": "not setted"} если путь не задан) - Description: Узнать папку для загрузок
- Body:
-
PUT
/api/downloader/settings/resource_and_prefix- Body:
{"Resource": "string", "Prefix": "string"} - Response:
ok/error(ресурс недоступен | не найден) - Description: Настроить ресурс и префикс для загрузки
- Body:
-
GET
/api/downloader/settings/resource_and_prefix- Body:
{"Resource": "string", "Prefix": "string"} - Response:
ok/error - Description: Посмотреть ресурс и префикс для загрузки
- Body:
-
POST
/api/downloader/mesure_speed- Body:
empty - Response:
ok/error(ошибка на стороне сервера) - Description: Запустить замер скорости загрузки к добавленным серверам.
- Body:
-
GET
/api/downloader/dl_server_status- Body:
{"Status": status}(string) {Processing, Available, Unavailable} - Response:
ok/error - Description: Посмотреть есть ли хоть один достпуный ресурс
- Body:
-
WIP GET
/api/downloader/base_servers- Body:
[{"Resource": "string", "Prefix": "string"}] - Response:
ok/error - Description: Посмотреть список базовых серверов
- Body:
-
PUT
/api/white_list/users- Body:
{"UserName": "string"} - Response:
ok/error(пользователь уже в белом списке | пользователь в черном списке, требуется подтверждение) - Description: Добавить пользователя в белый список
- Body:
-
GET
/api/white_list/users- Body:
[{"UserName": "string"}] - Response:
ok/error - Description: Посмотреть белый список
- Body:
-
DELETE
/api/white_list/users- Body:
{"UserName": "string"} - Response:
ok/error(пользователь не найден в белом списке) - Description: Удалить пользователя из белого списка
- Body:
-
PUT
/api/black_list/users- Body:
{"UserName": "string"} - Response:
ok/error(пользователь уже в черном списке | пользователь в белом списке, требуется подтверждение) - Description: Добавить пользователя в черный список
- Body:
-
DELETE
/api/black_list/users- Body:
{"UserName": "string"} - Response:
ok/error(пользователь не найден в черном списке) - Description: Удалить пользователя из черного списка
- Body:
-
GET
/api/black_list/users- Body:
[{"UserName": "string"}] - Response:
ok/error - Description: Посмотреть черный список
- Body:
-
PUT
/api/validator/settings/role_filter_level- Body:
{"RoleFilterLevel": number}(0-4) - EMPTY = 0,
- SUBSCRIBER = 1,
- VIP = 2,
- MODERATOR = 3,
- BROADCASTER = 4
- Response:
ok/error(уровень вне диапазона) - Description: Установить уровень фильтрации по ролям
- Body:
-
GET
/api/validator/settings/role_filter_level- Body:
{"RoleFilterLevel": number}(0-4) - EMPTY = 0,
- SUBSCRIBER = 1,
- VIP = 2,
- MODERATOR = 3,
- BROADCASTER = 4
- Response:
ok/error(уровень вне диапазона) - Description: Узнать уровень фильтрации по ролям
- Body:
-
PUT
/api/validator/settings/whitelist_only- Body:
{"Enabled": boolean} - Response:
ok/error - Description: Включить/выключить режим только белого списка
- Body:
-
GET
/api/validator/settings/whitelist_only- Body:
{"Enabled": boolean} - Response:
ok/error - Description: Узнать статус режима только белого списка
- Body:
-
PUT
/api/irc_client/settings/reconnect_timeout- Body:
{"ReconnectTimeout": number}(секунды) - Response:
ok/error - Description: Установить таймаут переподключения IRC клиента
- Body:
-
POST
/api/irc_client/join- Body:
{"Channel": "string"}(название канала) - Response:
ok/error(ошибка сети | неверное имя канала) - Description: Подключиться к IRC каналу
- Body:
-
GET
/api/irc_client/join- Body:
[{"Channel": "string"}](название каналов) - Response:
ok/error(ошибка сети | неверное имя канала) - Description: Получить список подключенных каналов
- Body:
-
POST
/api/irc_client/part- Body:
{"Channel": "string"}(название канала) - Response:
ok/error(ошибка сети | не подключен к каналу) - Description: Отключиться от IRC канала
- Body:
-
WIP PUT
/api/vidget/chat/show- Body:
{"Enabled": bool} - Response:
ok/error(ошибка формата JSON) - Description: Включить / Выключить виджет чата
- Body:
- лепим наугад
- conan2.*
- CMake
Если конан не настроен или его нет:
pip install conan
conan profile detect --force
Добавь conan в Path (Если путь скриптов pip еще туда не добавлен).
mkdir build && cd build
conan install .. --build=missing --output-folder=. -s build_type=Release -s compiler.runtime=static
(при первом запуске может занять больше часа. Сборка библиотек Boost)
cmake .. --preset conan-default
cmake --build . --config Release
(Может быть очень много ворнингов. Это ок)

