-
Notifications
You must be signed in to change notification settings - Fork 0
Trade Bridge RU
Trade Bridge позволяет браузерному расширению выполнять всю работу с трейд-сайтом (live-поиск, fetch, whisper), а POEFixer занимается только покупкой в игре. Вся работа с трейд-сайтом идёт внутри вашей реальной браузерной сессии — без копирования cookies и возни с cf_clearance — и это фундамент для будущего режима «POEFixer на другом ПК».
Можно использовать бесплатное официальное расширение или написать своё по документированному протоколу ниже.
Trade Bridge требует, чтобы у вашей лицензии POEFixer была функция Trade. Если на сервере Trade сделана платной — нужен валидный ключ; если бесплатной — может пользоваться любой. Без прав мост отвечает
entitlement_requiredи отклоняет покупки.
Браузерное расширение POEFixer
live-search WebSocket ─┐
fetch деталей предмета │ ws://127.0.0.1:PORT покупка в игре:
whisper (телепорт) ├─────────────────────► ждёт телепорт → клик → проверка
(Force teleport, │ buy_request → авто-стэш → /hideout
In-demand retry, │ ◄───────────────────── → отправляет результат
Rate limiting) ─┘ buy_result
- Расширение владеет всем, что касается трейд-сайта.
- POEFixer владеет всем в игровом клиенте и поднимает локальный WebSocket-сервер (Trade Bridge), к которому подключается расширение.
- В этом режиме встроенный
tls-clientPOEFixer не используется, а трейд-сайтовые элементы (Connections, Trade Cookies, Force teleport, In-demand, Rate limiting) переезжают в расширение и скрываются/отключаются в POEFixer.
Расширение поставляется внутри POEFixer. В папке POEFixer откройте Resources\extension\:
<папка POEFixer>\Resources\extension\
├─ poefixer-extension-chrome.zip ← Chrome / Edge
├─ poefixer-extension-firefox.zip ← Firefox
└─ chrome\ ← распакованная копия для кнопки «Помощь с установкой»
Полностью «тихая» установка одной кнопкой невозможна — браузеры намеренно блокируют программную установку расширений. Вы распаковываете архив для своего браузера и загружаете его один раз. Кнопка Помощь с установкой… (Конфигурация → Trade) делает часть для Chrome/Edge: копирует путь к распакованной папке
chrome\в буфер и открывает эту инструкцию — тогда распаковку можно пропустить.
-
Распакуйте
Resources\extension\poefixer-extension-chrome.zipв любую папку (чтобыmanifest.jsonбыл в её корне). Или нажмите Помощь с установкой… в POEFixer и используйте скопированный путь — затем перейдите к шагу 4. - Откройте
chrome://extensions(Edge:edge://extensions). - Включите Режим разработчика (справа вверху).
- Нажмите Загрузить распакованное расширение и выберите эту папку (или вставьте путь от «Помощь с установкой»).
- Иконка появится на панели; сохраняется между перезапусками.
После обновления POEFixer встроенное расширение обновляется — откройте
chrome://extensionsи нажмите Обновить на карточке расширения (или заново распакуйте и загрузите).
Релизный Firefox ставит только подписанные Mozilla расширения, поэтому используйте временную загрузку:
-
Распакуйте
Resources\extension\poefixer-extension-firefox.zipв любую папку. - Откройте
about:debugging#/runtime/this-firefox. - Нажмите Загрузить временное дополнение… и выберите
manifest.jsonиз распакованной папки. - Останется загруженным до перезапуска Firefox (повторите после перезапуска).
-
Постоянно: установите подписанный Mozilla/AMO
.xpi, открыв его в Firefox и подтвердив запрос прав.
- В POEFixer: Конфигурация → Trade → Источник данных трейда → Браузерное расширение, запомните Порт (по умолчанию
47362) и нажмите Запустить мост. - В попапе расширения укажите тот же Порт — должно показать Host: connected, а статус в POEFixer станет зелёным и покажет название и реальную версию расширения, например «Расширение подключено (PoeFixerExt/1.1.2)» (версия берётся из манифеста расширения — устаревшее расширение будет отмечено здесь).
- Войдите на трейд-сайт в этом браузере, добавьте Trade Links и нажмите Play (см. §3).
Всё управление — в POEFixer; в попапе расширения указывается только Port.
- В POEFixer: Configuration → Trade → Источник данных = Браузерное расширение, укажите Port, нажмите Запустить мост.
- В попапе расширения проверьте Host: connected и тот же Port.
- Залогиньтесь на трейд-сайте в том же браузере.
- В Trade Links (вкладка Connections) POEFixer добавьте URL-ы поиска trade2 и нажмите Play — поиск передаётся в расширение и запускается там; Stop убирает его. Если расширение ещё не подключено, Play вместо запуска откроет окно-помощник: из него можно запустить мост или перейти в Configuration → Trade к помощи с установкой.
- Поведение задаётся в POEFixer (Configuration → Trade): Force teleport, Item is in demand → teleport anyway, Rate limiting — POEFixer пушит их в расширение, оно лишь подчиняется.
- При совпадении расширение шлёт whisper, а POEFixer покупает в игре. Вся активность расширения попадает в Логи POEFixer (категория Trade).
Надёжный live-фид (автоматически): для каждого активного поиска расширение открывает закреплённую фоновую вкладку страницы трейда и поднимает live-WebSocket внутри этой страницы (правильный Origin + куки сессии — как делает сам сайт). Просто оставайтесь залогинены на трейд-сайте; Live Search вручную включать не нужно. Trade Link показывает Connecting…, пока WS не поднялся, затем Live. Закрытие этой закреплённой вкладки останавливает поиск.
Ручная покупка (купить поиск оптом, сейчас): вместо ожидания live-листингов нажмите иконку Корзина на любом Trade Link для немедленной оптовой покупки. Расширение получает самые дешёвые подходящие листинги для этого поиска (до заданного количества предметов, с учётом фильтров валюты этой ссылки), группирует их по продавцам и для каждого выполняет whisper + покупку через POEFixer — применяя те же лимиты трат и авто-стэш, с единым возвратом в убежище в конце. Ручная покупка и live-поиск (Play) взаимоисключают друг друга: остановите live-поиски перед началом ручной покупки и наоборот. Если расширение не подключено, нажатие корзины откроет то же окно-помощник, что и Play (запуск моста / переход к настройкам установки).
Протокол — обычный JSON по WebSocket. Реализовать может любой. Сервер поднимает POEFixer; ваш клиент подключается к ws://127.0.0.1:<port> (по умолчанию 47362, настраивается в Settings).
Хост выполняет покупки только если у лицензии есть entitlement Trade. Иначе вы получите
{"type":"error","code":"entitlement_required"}. (Детали аутентификации намеренно не документируются.)
Сначала шлёте hello; хост отвечает welcome.
-
version— версия расширения из манифеста (semver-строка, например"1.1.0"). Если ваше расширение старее ожидаемой версии, POEFixer обнаруживает несоответствие, подавляет live-поиски и отключает покупки до переустановки актуального расширения. POEFixer показывает предупреждение в Settings → Trade. Попытка покупки при устаревшем расширении возвращает{"type":"error","code":"outdated_extension"}. -
allowed:false→ нет прав (трактуйте как «нужен ключ»); хост отклонит покупки сentitlement_required. -
tokenнужен только если пользователь включил токен-пэйринг в POEFixer (по умолчанию выключен).
После welcome (и при любом изменении в POEFixer) хост шлёт config. Программа — единая точка управления, поэтому расширение мониторит ровно эти поиски и подчиняется этому behavior:
// хост → клиент
{ "type":"config",
"behavior":{ "forceTeleport":false, "inDemandRetry":true, "rateLimit":true },
"searches":[ { "realm":"poe2", "league":"Standard", "searchId":"…", "note":"…" } ] }Хост периодически шлёт status:
{ "type":"status", "ready":true, "inGame":true, "attached":true, "busy":false }Вы ОБЯЗАНЫ отправлять whisper/телепорт только когда последний status.ready === true. ready = есть_права && прикреплён && в_игре && !занят. Whisper при не-ready телепортирует персонажа без покупателя, ведущего сделку.
После успешного whisper (персонаж телепортируется) шлёте buy_request:
// клиент → хост
{ "type":"buy_request", "id":"r-42", "seq":7,
"group":{
"searchId":"…", "groupId":"g-9", "isLastGroup":true,
"items":[ {
"itemId":"...", "stashX":3, "stashY":1, "w":1, "h":1,
"currency":"chaos", "amount":50,
"seller":"AccountName", "stashName":"~price 50 chaos",
"name":"...", "typeLine":"...", "baseType":"...", "rarity":"Rare",
"iconUrl":"https://...", "ilvl":82, "corrupted":false, "identified":true,
"explicitMods":[ "..." ], "implicitMods":[ "..." ],
"league":"Standard", "realm":"poe2",
"hideoutToken":"...", "indexedTime":"..."
} ] } }Хост подтверждает, при желании шлёт прогресс, затем единый результат:
{ "type":"ack", "ackSeq":7 }
{ "type":"buy_progress", "id":"r-42", "phase":"teleporting" }
{ "type":"buy_result", "id":"r-42", "seq":11,
"items":[ { "itemId":"...", "ok":true, "reason":"verified" } ],
"summary":{ "bought":1, "failed":0 } }-
group.searchId— поиск, из которого пришёл листинг; хост привязывает покупку к нужному Trade Link (если не указан — берёт первый активный поиск). Указывайте для корректной работы с несколькими поисками. -
stashX/stashY— координаты предмета в магазине продавца;w/h— размер. Они управляют кликом в игре. - Цену можно слать плоско (
currency/amount, как выше) или вложенно ("price":{"currency","amount"}) — хост принимает оба варианта. -
hideoutTokenпередаётся только для логов (whisper вы уже сделали им). - Каждый
buy_resultнужно подтвердить:{"type":"ack","ackSeq":<buy_result.seq>}.
Исходы стадии whisper (для полноты логов POEFixer):
{ "type":"trade_event", "seq":8, "stage":"whisper", "outcome":"in_demand", "itemId":"...", "detail":"" }
// outcome ∈ in_demand | whisper_failed | teleport_failed | fetch_error
trade_eventможет также нести полный объектitem(те же поля, что и у элементаbuy_request).teleport_failed= листинг продавца остался in demand даже после форсированного повторного whisper; сitemPOEFixer записывает его в Trade Logs как Teleport Fail.fetch_error/whisper_failed/in_demand— информационные, идут в общий лог (категория Trade).
Пересылайте свою активность в лог POEFixer (рекомендуется — все логи расширения должны быть в программе):
{ "type":"log", "level":"info", "message":"…" } // показывается в Логах POEFixer (категория Trade)Сообщайте состояние live-WS каждого поиска, чтобы Trade Link в POEFixer показывал Connecting…/Live:
{ "type":"search_status", "searchId":"…", "state":"connected" } // state ∈ connected | closed | errorКогда пользователь нажимает Ручная покупка (иконка корзины) на Trade Link, хост отправляет manual_buy; расширение выполняет одноразовую оптовую покупку по этому поиску и сообщает о жизненном цикле/прогрессе через manual_buy_status. Покупки у каждого продавца используют обычный поток buy_request (§4.3) с isLastGroup:false; хост отправляет финальный /hideout после получения state:"done".
// хост → клиент: начать одноразовую оптовую покупку по одному сохранённому поиску
{ "type":"manual_buy", "id":"mb-…", "seq":12,
"search":{ "realm":"poe2", "league":"Standard", "searchId":"…", "note":"…" },
"itemCount":10, // 0 = все результаты
"filters":{ "chaos":{ "min":0, "max":0 } } } // валюта → {min,max}; 0 = без ограничений
// хост → клиент: отменить текущую оптовую покупку
{ "type":"manual_buy_cancel", "id":"mb-…", "seq":13 }
// клиент → хост: жизненный цикл + прогресс (подтверждается как trade_event)
{ "type":"manual_buy_status", "id":"mb-…", "seq":4,
"state":"started|progress|done|cancelled|error",
"processed":3, "bought":2, "failed":1, "total":10, "detail":"" }- Получите результаты поиска, выберите самые дешёвые листинги, примените
filters, ограничьтеitemCount(0 = все), сгруппируйте по продавцам и купите каждую группу черезbuy_request(isLastGroup:false). - Отправьте
manual_buy_statusstartedв начале,progressпо завершении каждой группы и ровно один финальныйdone/cancelled/error.
-
buy_requestиtrade_eventнесут растущийseq; хост их подтверждает. Храните неподтверждённые кадры и пересылайте их при реконнекте (по порядкуseq). -
buy_request.id— ключ идемпотентности: повторный id вернёт записанныйbuy_result(илиerror: duplicate, пока в процессе). Используйте стабильный уникальный id на покупку. -
buy_resultнесётseq, который подтверждаете вы.
{ "type":"error", "code":"entitlement_required|not_in_game|busy|duplicate|bad_request|unauthorized|proto_unsupported|outdated_extension", "id":"r-42", "detail":"..." }const ws = new WebSocket("ws://127.0.0.1:47362");
let ready = false, seq = 0, behavior = {}, searches = [];
const log = (message) => ws.send(JSON.stringify({ type:"log", level:"info", message }));
ws.onopen = () => ws.send(JSON.stringify({ type:"hello", proto:1, client:"MyExt/1.0", version:"1.1.0" }));
ws.onmessage = (e) => {
const m = JSON.parse(e.data);
if (m.type === "welcome" && !m.allowed) console.warn("Нужен entitlement Trade");
if (m.type === "config") { behavior = m.behavior; searches = m.searches; } // программа управляет вами
if (m.type === "status") ready = m.ready;
if (m.type === "buy_result") ws.send(JSON.stringify({ type:"ack", ackSeq:m.seq }));
};
// мониторьте `searches`, подчиняйтесь `behavior`; после успешного ВАШЕГО whisper и ready === true:
function buy(items) {
ws.send(JSON.stringify({ type:"buy_request", id:"r-"+Date.now(), seq:++seq,
group:{ groupId:"g", isLastGroup:true, items } }));
}- Host: disconnected — POEFixer не запущен, мост не стартован или порт не тот. Запустите мост в Settings → Trade; сверьте порт в попапе.
-
entitlement_required— у лицензии нет функции Trade (платная на сервере). -
not_in_game— POEFixer не прикреплён/не в игре; дождитесьstatus.ready. - Live-поиск не срабатывает — убедитесь, что вы залогинены на трейд-сайте в том же браузере. Расширение само открывает закреплённую фоновую вкладку на каждый поиск и поднимает live-WebSocket внутри неё; Trade Link показывает Connecting…, затем Live. Если застрял на Connecting… — откройте закреплённую вкладку и проверьте, что вы залогинены.
- Порт занят — смените порт в Settings → Trade и в попапе, перезапустите мост.