Cross-seed
Cross-seed (Кросс-сидинг, сиречь перекрестное сидирование) — весьма пожилая, задротская и крайне профитная дисциплина Специальной Олимпиады в мире приватных торрент-трекеров. Анонимус скачивает 1 файл с 1-го трекера, а затем раздает этот же самый файл на 2-м, 3-м и 100500-м трекере, не скачивая при этом ни 1 лишнего байта. В результате мамкин дедушка-пират экономит драгоценный трафик, фармит терабайты аплоада, тешит свое ЧСВ и стремительно продвигается по иерархии элитных файлообменных сект. Рано или поздно он сможет жужжать как массивный шмель…
Я скачал файл на трекере А, но хочу раздавать его еще и на трекере Б. Мой клиент говорит, что трансфер с таким именем уже существует. Что будет, если я нажму продолжить? Мой комп взорвется?
Забанен за накрутку ратио и спуфинг инфохеша. Увидимся в аду.
Историческая справка[править]
В далеком 2004 году, когда деревья были большими, а интернет — медленным, появление протокола BitTorrent перевернуло игру. Но эйфория от свободы длилась недолго. Очень скоро появились закрытые клубы (приватные трекеры), где за скачанное порно и FLAC-рипы нужно было расплачиваться так называемым ратио (коэффициентом отдачи). Скачал 1 гигабайт — будь добр, отдай 1 гигабайт обратно. Не отдал? Лови банхаммером по лицу.
Проблема заключалась в том, что на элитных ресурсах (вроде покойного What.CD или ныне здравствующих PTP и BTN) сидят толпы гигачадов с гигабитными сидбоксами. Как только появляется новая раздача, эти киборги скачивают ее за 0.1 секунды и начинают раздавать друг другу. Обычному Васе с его домашним ADSL-каналом на 10 мегабит отдать хотя бы 1 байт становится физически невозможно. Ратио падает, аккаунт блокируется, Вася плачет.
Тут на сцену выходит кросс-сидинг. Вася замечает, что 1 и тот же рип свежего блокбастера или альбома Ранеток лежит сразу на 3-х разных трекерах. Что если скачать торрент-файл с трекера номер 2, подсунуть ему уже скачанный с трекера номер 1 файл и нажать Перехешировать (Force Recheck)? БИНГО! Клиент понимает, что файл уже есть на 100 процентов, и сразу начинает его сидировать. Вася ничего не скачивал, но теперь получает аплоад сразу с 2-х фронтов. PROFIT!
Как это делали динозавры[править]
В эпоху палеозоя (примерно до 2020 года) кросс-сидинг был уделом сильных духом аутистов. Процесс выглядел так:
- Идешь на трекер 1, качаешь файл.
- Идешь на трекер 2, ищешь тот же релиз. Глазами. Карл, 2-мя глазами!
- Скачиваешь .torrent файл.
- Засовываешь в клиент.
- Указываешь путь к уже скачанному файлу.
- Молишься Ктулху, чтобы релизер на 2-м трекере не переименовал папку.
- Молишься еще раз, чтобы в раздачу не добавили какой-нибудь мусорный .nfo файл весом 2 килобайта или картинку обложки.
- Если хеш совпал — ты бог. Если нет — клиент начинает докачивать разницу, затирая старые файлы, убивая раздачу на 1-м трекере и превращая твою библиотеку в тыкву.
Этот процесс отнимал over 9000 часов времени. Если у тебя в клиенте 5000 торрентов, вручную искать для них дубликаты на других ресурсах мог только человек с терминальной стадией синдрома Аспергера.
Эра автоматизации[править]
Лень — двигатель прогресса. В один прекрасный день красноглазики с GitHub осознали, что ручной труд — это для рабов, и написали ультимативный комбайн для фарма ратио под незамысловатым названием cross-seed.
Cross-seed (написанный на Node.js, потому что в 202X годах всё пишется на JS) работает как невидимый ниндзя. Он:
- Подключается к твоему торрент-клиенту по API (qBittorrent, rTorrent, Deluge, Transmission).
- Собирает базу данных из всех 100000 скачанных тобой файлов.
- Идет в Prowlarr или Jackett (это такие агрегаторы торрент-трекеров, позволяющие искать по всем сайтам через 1 интерфейс).
- Ищет там совпадения по именам, размерам файлов и прочим метаданным.
- Если находит 100-процентное совпадение — сам скачивает .torrent файл и сам инжектит его в твой торрент-клиент.
- Ты просыпаешься утром, а у тебя в клиенте на 300 раздач больше, и все они уже отдают трафик. Чудо!
Настройка[править]
Несмотря на всю крутость, cross-seed — это софт, написанный гиками для гиков. Обычный вендокапец, привыкший тыкать мышкой в кнопку Далее, при виде конфигурационного файла config.js впадает в ступор. На Reddit можно найти 100500 тредов, где несчастные ньюфаги воют от бессилия, получая ошибку SyntaxError: Unexpected identifier. А всё потому, что мамкин хакер забыл поставить 1 запятую в массиве или не экранировал слеши в пути Windows (нужно писать C:\\torrents, а не C:\torrents, дебилы!).
Для запуска этого чуда тебе понадобится:
- Node.js версии не ниже 20 (если версия 19, скрипт пошлет тебя на 3 буквы).
- Торрент-клиент с включенным WebUI (и упаси тебя бог использовать qBittorrent с включенным SQLite режимом для сохранения торрентов, скрипт подавится).
- Настроенный Prowlarr с прописанными Torznab-ссылками. Torznab — это такой протокол, через который агрегаторы общаются с индексаторами. Если ссылка не заканчивается на /api, скрипт опять же пошлет тебя.
- Токен API (генерируется командой cross-seed api-key).
- Прямые руки, растущие из плеч, а не из тазобедренного сустава.
Механизмы поиска[править]
Скрипт умеет искать раздачи 3-мя способами, каждый из которых вызывает разную степень жжения в нижней части спины у пуристов.
Strict Mode[править]
Режим для параноиков. Файлы должны совпадать байт в байт. Имена папок должны быть идентичными. Если релизер на 2-м трекере добавил в название папки 1 лишний пробел — совпадение отвергается. Это безопасно, но эффективность такого поиска болтается в районе 10 процентов.
Flexible Mode[править]
Тут скрипт начинает включать мозги. Если названия файлов немного отличаются, но их размер совпадает с точностью до 1 байта, скрипт говорит: Ок, это тот же самый видос, просто переименованный. Чтобы этот режим работал, в дело вступает черная магия файловых систем под названием Linking (о ней ниже).
Partial Mode[править]
Фича, появившаяся в 6-й мажорной версии скрипта. Святой Грааль для тех, кто понимает. Допустим, ты скачал фильм размером 50 гигабайт. На другом трекере лежит тот же самый файл фильма, но к нему приложены субтитры (файл .srt размером 50 килобайт) и мусорный .nfo файл. В строгом режиме ты идешь лесом. В частичном режиме скрипт качает новый торрент, инжектит его, подхватывает 50-гигабайтный файл (который у тебя уже есть на 100 процентов), а недостающие 50 килобайт субтитров просто докачивает из роя! Для работы частичного совпадения используется параметр fuzzySizeThreshold (порог нечеткого размера). По умолчанию он равен 0.02 (допускается расхождение в 2 процента). Если ты жадный ублюдок, можешь поставить 0.1 (10 процентов), но тогда готовься к тому, что клиент будет выкачивать лишние гигабайты.
Также есть настройка seasonFromEpisodes. Если ты скачал сериал по 1-й серии, а на другом ресурсе лежит целый Season Pack (пакет всего сезона), скрипт может собрать твой мусор воедино, вычислить, что у тебя есть например 80 процентов (0.8) эпизодов, и начать кросс-сидить сезонный пак, докачав недостающие 20 процентов. Автоматизация уровня Бог.
Хардлинки[править]
Если ты используешь гибкий или частичный режим, скрипту нужно как-то подсунуть твоему торрент-клиенту файлы под новыми именами, не дублируя при этом данные на жестком диске. Если у тебя диск на 10 терабайт забит порнографией, ты не хочешь, чтобы она занимала 20 терабайт только из-за кросс-сидинга.
Решение: жесткие ссылки (Hardlinks). Любой уважающий себя линуксоид знает, что файл — это просто кусок данных на блине жесткого диска, у которого есть уникальный номер (inode). А то, что ты видишь в папке — это лишь ярлык (имя), указывающий на этот inode. Хардлинк — это создание 2-го, 3-го, 100500-го имени для 1-го и того же куска данных. Файл физически 1, место на диске занимает как 1 файл, но в файловом менеджере выглядит как 2 абсолютно независимых файла. Удалишь 1 — 2-й останется жить, пока не удалишь и его.
Чтобы это шаманство работало, нужны жесткие условия:
- И исходный файл, и хардлинк должны находиться на 1-м физическом диске (или в 1-м логическом разделе). Нельзя сделать хардлинк с диска C: на диск D:.
- Если ты мамкин девопс и используешь Docker, все твои пути в контейнерах (mounts) должны принадлежать 1-му тому. Если ты прокинешь /downloads и /cross-seeds как 2 разных вольюма, Docker воспримет их как разные файловые системы, и вместо хардлинка произойдет банальное копирование. В итоге твой NAS на 40 терабайт забьется за 1 ночь, а ты пойдешь плакать на Reddit.
Для тех, кто сидит на продвинутых ФС вроде BTRFS или ZFS, существует вариант reflink (Copy-on-Write ссылка). Она работает как хардлинк, но позволяет изменять 1 из файлов без влияния на 2-й. Высший пилотаж.
А вот symlink (символические ссылки) использовать не рекомендуется. Торрент-клиенты относятся к ним с подозрением, а при удалении оригинального файла симлинк превращается в мертвого ублюдка, выдавая ошибку ENOENT: no such file or directory.
Войны торрент-клиентов[править]
Каждый юзер скрипта рано или поздно сталкивается с выбором торрент-клиента, и тут начинается священная война, сравнимая только со срачем между фанатами AMD и Intel.
qBittorrent[править]
Самый популярный клиент для масс. Написан на C++, имеет неплохой WebUI. Но разработчики скрипта от него воют. Причина? Механизм Автоматического управления торрентами (Auto TMM). Когда qBit видит новый торрент, он пытается засунуть его в папку, соответствующую категории. В итоге хардлинки ломаются, пути сбиваются, и в логах скрипта появляется кровавое месиво из ошибок. Чтобы qBit работал с кросс-сидом адекватно, нужны сторонние костыли вроде скрипта qbit_manage, который отключает Auto TMM для кросс-сидов.
Deluge[править]
Выбор элиты и самих разработчиков cross-seed (один из разрабов скрипта, некто Zachary, сам комитит в код Deluge). Написан на Python. С плагином ltConfig способен переваривать огромные скорости и гонять трафик так, что сетевая карта дымится. Идеально работает с хардлинками. Минус — WebUI выглядит так, будто его дизайнил слепой студент в 2005 году. При 5000+ торрентов веб-морда начинает тормозить так, что хочется разбить монитор. Решается использованием Thin Client (установка десктопного приложения, которое подключается к демону на сервере).
rTorrent[править]
Классика жанра. Консольный клиент, управляемый через конфиг .rtorrent.rc. Работает быстрее скорости света, жрет 3 мегабайта оперативки. Но чтобы прикрутить к нему скрипт, нужен костыль в виде ruTorrent (веб-морды на PHP) и настройка XMLRPC. Ньюфаги от настройки rTorrent обычно уходят в монастырь.
Transmission[править]
Клиент для домохозяек и пользователей Макинтошей. Скриптом поддерживается скорее для галочки. Если ты сидируешь 10000 торрентов в Transmission — ты мазохист.
Воздействие на трекеры[править]
С 1-й стороны, админы трекеров должны молиться на кросс-сидеров. Кросс-сидинг повышает удержание файлов (retention), увеличивает количество сидов на мертвых раздачах и делает рой (swarm) здоровым. Особенно это полезно новым трекерам, которые пытаются нарастить библиотеку: их релизы мгновенно подхватываются армией кросс-сидеров с топовых ресурсов.
С 2-й стороны, скрипт создает дикую нагрузку на сервера трекера (так называемый Load). Автоматизация генерирует 4 типа нагрузки:
- RSS-запросы (дешевые). Скрипт просто раз в 10 минут запрашивает XML-файл с новинками.
- Поисковые запросы (дорогие). Скрипт берет 1 фильм из твоей библиотеки и делает поиск по базе трекера. Если у тебя 5000 фильмов, и скрипт решит поискать их все за 1 час — база данных трекера ляжет отдохнуть. Именно поэтому в скрипте жестко зашиты лимиты: параметр searchLimit по умолчанию равен 400 запросам в день.
- Announce-запросы (дешевые). Интеграция с IRC через Autobrr. Когда на трекер заливают новый файл, бот кидает инфу в IRC, Autobrr ловит ее и передает скрипту. Нагрузки на базу нет вообще.
- Скачивание .torrent файлов (Snatches). Самое больное место. Чтобы понять, совпадает ли файл по хешу кусков, скрипт обязан скачать .torrent файл себе на диск. Файл может весить 2-5 мегабайт. Если скрипт в припадке аутизма начнет качать 1000 файлов подряд, чтобы найти 1 совпадение, сервер трекера охуеет от исходящего трафика.
Из-за последнего пункта многие сисадмины приватных трекеров банили юзеров скрипта за DDoS-атаку или Абьюз API. Чтобы избежать расстрела, в версии 6 были добавлены параноидальные механизмы защиты. Скрипт кеширует неудачные поиски, запоминает, что он уже искал, и никогда не качает 1 и тот же .torrent файл 2 раза в жизни. Параметры excludeOlder (например, 30 дней) и excludeRecentSearch (например, 10 дней) гарантируют, что скрипт не будет долбить трекер одним и тем же запросом каждый день.
Подводные камни[править]
Инфохеш коллизии (BEP 27)[править]
Самый эпичный фейл, который может случиться с кросс-сидером. Протокол BitTorrent устроен так, что каждый файл идентифицируется уникальным хешем (Infohash). Если 2 человека независимо друг от друга создали торрент-файл из 1-го и того же видео, не указав приватный флаг или уникальный источник (source flag), инфохеш у этих двух .torrent файлов будет абсолютно одинаковым 1 в 1!
Когда ты загружаешь 2 торрента с одинаковым инфохешем, но с разными announce URL (адресами трекеров), клиент впадает в шизофрению. Он объединяет их в 1 раздачу, у которой в списке трекеров висят сразу 2 приватных сайта. Клиент начинает радостно рапортовать об аплоаде на ОБА трекера одновременно. Админы видят, что ты отсылаешь левые данные, система античита выдает алерт, и твой аккаунт на обоих сайтах улетает в перманентный бан быстрее, чем ты успеешь сказать ой. К счастью, современные приватные трекеры автоматически вшивают в каждый .torrent файл уникальный идентификатор сайта (например, PTP), что меняет инфохеш и спасает задницы тупых пиратов. Но на безымянных бомже-трекерах шанс словить такой банхамер всё еще выше нуля.
Ужасы публичных трекеров[править]
Некоторые гении пытаются натравить скрипт на публичные трекеры (типа RARBG, пока он был жив, или RuTracker). И тут их ждет облом. Публичные торренты не имеют уникальных source-флагов, их инфохеши совпадают в 99 процентах случаев. Скрипт смотрит на них и говорит: Эй, придурок, у тебя УЖЕ ЕСТЬ этот торрент в клиенте, зачем ты заставляешь меня искать его дубликат?. Плюс, публичные трекеры используют DHT и PEX для обмена пирами, так что добавление еще 1-го паблик-трекера в раздачу не дает тебе абсолютно никаких новых пиров. Скрипт официально кладет болт на паблик.
Анимешники должны страдать[править]
Отдельной болью разработчиков скрипта стали любители японской мультипликации. Названия аниме-релизов — это хаотичный набор символов, квадратных скобок, хешей релиз-групп и японской транслитерации (например, [Erai-raws] Tate no Yuusha no Nariagari Season 2 — 06 [1080p][Multiple Subtitle].mkv). Стандартные алгоритмы парсинга (которые отлично работают на нормальных фильмах вроде The.Matrix.1999.1080p.BluRay.x264-SPARKS) при виде аниме начинают рыдать кровью и выдают нулевые результаты. В 6-й версии скрипта завезли Anime Support, но 100-процентной гарантии никто не дает. Если ты качаешь хентай с сомнительных ресурсов, кросс-сидить его придется ручками.
Конкурент на горизонте[править]
Пока команда cross-seed пилила идеальный бэкенд на Node.js, на сцене появились разработчики утилиты Autobrr и выкатили свой комбайн под названием Qui (написанный на Go).
Qui позиционируется как единый WebUI для управления 100500 инстансами qBittorrent. И в него внезапно встроили функцию кросс-сидинга в 1 клик. На Reddit тут же начались холивары.
- Фанаты Qui кричат: Ваш cross-seed — это кусок неконфигурируемого дерьма без интерфейса! В Qui я нажал 1 кнопку и всё заработало за 30 секунд!
- Фанаты cross-seed отвечают: Ваш Qui не умеет в хардлинки! Он просто ищет точное совпадение папок! Он не умеет парсить данные из Sonarr/Radarr! Вы тупые казуальщики!
- Разработчик cross-seed (Zakkarry) приходит в тред, пишет полотно текста на 5000 слов о том, как глубоко их алгоритмы ищут совпадения, и скидывает превьюшки грядущей 7-й версии с полноценным графическим интерфейсом. Холивар продолжается, попкорн съедается тоннами.
Алгоритм работы[править]
Для тех, кто хочет знать, как эта шайтан-машина работает под капотом, архитектура скрипта делится на несколько пайплайнов.
Search Pipeline[править]
Запускается по расписанию (через searchCadence) или вручную командой cross-seed search.
- Берется торрент из твоей библиотеки (Owned Torrent).
- Его имя пропускается через парсер, отбрасывается мусор (теги вроде 1080p, WEB-DL, x264).
- Чистое имя отправляется в Prowlarr/Jackett как поисковый запрос (или отправляется IMDB ID, если прикручен Sonarr/Radarr).
- Prowlarr опрашивает все 15 твоих закрытых трекеров.
- Трекеры возвращают XML с результатами (Candidates).
- Скрипт отбрасывает результаты с неправильным размером (сверяет по fuzzySizeThreshold).
- Оставшиеся кандидаты проходят через алгоритм Matching (сопоставление). Скрипт лезет внутрь .torrent файла, скачанного с трекера, и сравнивает внутреннюю структуру файлов с твоей структурой на диске.
- Если алгоритм выдает true, происходит Action (создание хардлинков и отправка POST-запроса в API qBittorrent/Deluge).
RSS Pipeline[править]
Запускается раз в 10-30 минут (через rssCadence).
- Скрипт запрашивает последние залитые торренты с трекеров (без привязки к твоей библиотеке, просто новинки).
- Берет имя новинки и ищет его у тебя локально в базе данных.
- Если у тебя уже есть файл с таким же или очень похожим именем, скрипт переходит к шагу Matching.
- Это очень дешевый по ресурсам процесс, который позволяет подхватывать кросс-сиды буквально через 1 минуту после того, как кто-то залил релиз на трекер.
Announce Pipeline[править]
Работает через Webhook. Ты настраиваешь утилиту Autobrr, которая сидит в IRC-каналах трекеров. Как только в канал падает сообщение Новый торрент: Мстители (2012) 1080p, Autobrr ловит ссылку и кидает ее скрипту cross-seed через API (на порт 2468). Скрипт проверяет, есть ли у тебя этот фильм. Если есть — он мгновенно забирает торрент и инжектит его. Ты влетаешь в раздачу в 1-е же секунды существования торрента, становясь 1-м из первоначальных сидеров. В мире приватных трекеров, где царит концепция Racing (гонки за аплоад), это эквивалентно читу на бессмертие.
FAQ[править]
Ньюфаги постоянно спотыкаются на 1-х и тех же граблях. Разработчикам пришлось выкатить здоровенный мануал по траблшутингу, чтобы не сойти с ума от повторяющихся вопросов в Discord.
Почему у меня вылетает RangeError: WebAssembly.instantiate(): Out of memory?[править]
Это случается на дешевых сидбоксах (Seedboxes) с ограничением виртуальной памяти (shared environments). Решение: обновить Node.js до версии 20.15 и запускать демона с флагом: NODE_OPTIONS=--disable-wasm-trap-handler cross-seed daemon. Магия V8 движка.
Ошибка ENOENT: no such file or directory при data-based поиске[править]
Ты удалил или переместил файлы в папке загрузок, но оставил битые симлинки, либо скрипт пытается просканировать директорию, которая исчезла. Проверь логи, найди сбойный файл и убей его ручками. И вообще, используй хардлинки, не будь животным.
Мой qBittorrent ругается на Missing Files (Файлы отсутствуют) после инжекта![править]
Проблема в 99 процентах случаев связана с маппингом путей (Path Mapping) в Docker. Скрипт cross-seed должен видеть файлы по тому же самому пути, что и твой торрент-клиент. Если в контейнере скрипта твой фильм лежит по пути /data/movies/film.mkv, а в контейнере qBit’а он лежит по пути /downloads/film.mkv, то при инжекте скрипт скажет qBit’у: Эй, бери файл по пути /data/movies!. qBit пойдет туда, обломается (у него нет папки /data) и выдаст ошибку Missing Files. Учи матчасть Docker, монтируй 1 корень (например, /mnt/storage:/storage) во все контейнеры одинаково, и будет тебе счастье.
Админ трекера написал мне гневное письмо![править]
Ты доигрался. Скорее всего, ты запустил команду cross-seed clear-cache или выставил searchLimit: 100000. Скрипт начал качать 100500 .torrent файлов в секунду, и сервер трекера охренел. Настрой excludeOlder и excludeRecentSearch по гайду, извинись перед админом, пообещай больше так не делать и надейся, что тебя не лишат инвайтов на 3 поколения вперед.
Я сижу на Windows. У меня не генерируется config.js![править]
Вендопроблемы. Во-1-х, открывай консоль от имени Администратора. Во-2-х, при указании путей в конфиге используй двойной слеш \\ вместо одинарного \. Windows считает одинарный слеш экранирующим символом. Путь C:\torrents сломает парсер JSON. Пиши C:\\torrents. И вообще, накати себе нормальный Linux.
Интеграция с Unraid[править]
Отдельной кастой стоят свидетели секты Unraid (домашней операционки на базе Linux для построения NAS с кучей свистоперделок и контейнеров). Для них добрые люди сделали отдельный шаблон в Community Applications. Заходишь во вкладку Apps, вбиваешь cross-seed, устанавливаешь контейнер от ambipro. Самый важный момент — прокинуть вольюмы (Volume Mappings).
- /config — сюда сохраняется база SQLite и конфиги.
- /data (или как там у тебя называется папка с фильмами) — сюда нужен доступ Read/Write, чтобы скрипт мог плодить хардлинки.
Если контейнер падает при старте, значит ты накосячил с конфигом. Включай в Docker настройку Post Arguments: gen-config, стартуй 1 раз (чтобы создался дефолтный файл), потом возвращай аргумент обратно на daemon.
Будущее кросс-сидинга[править]
Разработчики не стоят на месте. В скором времени (возможно в версии 7) обещают завезти полноценный WebUI, чтобы ньюфаги могли кликать мышкой, а не ковырять текстовые конфиги. Также планируется нативная поддержка SQLite-баз от qBittorrent, что избавит от необходимости использовать внешние костыли для парсинга состояния торрентов.
Конкуренция с утилитами вроде Qui только подстегивает процесс. А это значит, что фармить ратио, сидеть на 50 приватных трекерах одновременно и меряться пинусами в виде петабайтов аплоада станет еще проще и приятнее. Главное — не забывать платить за электричество и вовремя покупать новые жесткие диски на 20 терабайт.
Ссылки[править]
- cross-seed.org — Официальный сайт с документацией (на английском, учи язык)
- github.com/cross-seed/cross-seed — Репозиторий на GitHub]
- autobrr.com — Тот самый Autobrr для автоматизации