# PoE 2 Scanner — Session Summary (27 Jul 2026) ## Hardening work log (29 Jul 2026) - Удалены реальные `POESESSID` из bat-файлов, `config.json` очищен. - Удалён `startup.json` и код, который записывал в него полный конфиг. - Добавлены `.gitignore` и `config.example.json`. - Сервер слушает только `127.0.0.1`; CORS wildcard удалён. - Все POST-эндпоинты защищены случайным токеном Web UI. - `/api/config` больше не возвращает секреты и абсолютный путь. - Исправлены конфликт DOM id для league и затенение модуля `path` в `/sound.mp3`. - Добавлены валидация конфигурации, лимит тела запроса и безопасный текстовый вывод UI. - Запросы к PoE сериализованы через общую очередь с паузой 1,2 секунды. - Live сначала кеширует текущие ID, затем открывает WebSocket. - Обработка live-ID и WS reconnect сериализована; старый сокет не может затереть новый. - Сервер больше не завершает произвольный процесс на порту 3999. - Добавлены `node:test`, `npm test` и `npm run check`. ## Что было сделано / починено ### WGAP work log (27 Jul 2026 — Nachmittagssitzung) - **`Referer` header** — добавлен `"Referer": "https://www.pathofexile.com/trade2/"` в `headers()` (строка 100). Без него Cloudflare мог ебать. - **WS message format fix** — PoE 2 Live WS шлёт `{"message":{"result":["id1","id2"]}}`, а не `{"new":[...]}`. Пофикшено в двух местах: - Сервер `connectLiveWs` (строка 613): теперь разбирает `m.new || m.message?.result || []`. - CLI `runLive` (строка 253): то же самое. - **`cacheReady` выпилен с фронтенда** — переменная блокировала показ новых лотов до прихода "Cached N items" из SSE. Убрана целиком (строка 487, 494, 497). - **Secure / Whisper работает** — подтверждено: `POST /api/trade2/whisper` возвращает `{"success":true}`, PoE телепортит в зайдаут продавца. Работает только когда персонаж в игре. ### Open issues (27 Jul 2026) - **Full Scan** (🔍) в serve-mode — зависает на "Scanning..." или возвращает пустой результат (не тестили при чистом рейт-лимите). - **Live не показывает реаль-time лоты** — фикс WS message формата должен починить, но не тестили (рейт-лимит). ### Auth & API - **POETOKEN (JWT) auth**: `headers()` шлёт `POETOKEN` в Cookie вместе с `POESESSID`. - **hideout_token extraction**: `extractPrice()` возвращает `listing.hideout_token` как `hideoutToken`. - **`/api/secure`**: прокси `POST /api/trade2/whisper` с JWT и полными куками — PoE возвращает `code:2` (нужно быть в игре). - **WS headers**: `wsHeaders()` шлёт `POESESSID`+`POETOKEN` в Cookie, `Origin`, `User-Agent`, `Cache-Control`, `Pragma`. Без `Accept`, `Content-Type`, `Referer`, `X-Requested-With`. - **PoE 2 Live WebSocket**: URL `wss://.../api/trade2/live/poe2/{league}/{qid}`. Подтверждён кодом POEFlip (Swift, URLSessionWebSocketTask). Не требует пингов — PoE не шлёт пинг/понг, сервер дропает через ~10с (1006). ### Rate limit (НОВОЕ) - **Рейт-лимит PoE**: возвращает HTTP 429 с `{"error":{"code":3,"message":"Rate limit exceeded; Please wait N seconds before trying again."}}`. - **`fetchRetry()` переписана**: - Читает `wait N seconds` из ответа и ждёт реальное время. - Если N > 300 (5 мин) — сразу кидает `Rate limit: Ns. Подожди X мин...` - Если N ≤ 300 — ждёт и ретраит (до 10 попыток). - На 5xx — exponential backoff до 60s. - **Глобальный cooldown 1.2с** между любыми запросами к PoE API. - **`curl.exe` Cloudflare block**: curl без `cf_clearance` получает Cloudflare 403/429. Node.js `fetch()` работает нормально. ### Live mode (НОВОЕ) - **Кнопка Live больше не виснет на "⏳":** `fetchItems()` с начальными 200 ID вынесен ПОСЛЕ `res.end()`. Ответ приходит сразу, кача начальных предметов идёт в фоне. - **SSE стрим**: шлёт статусы (`Live!`, `Cached N known items`, ошибки). - **Autoreconnect**: exponential backoff (3s×1.5^attempt, max 30s), рефреш qid при 404. ### Фронтенд - **Double-click fix**: кнопка Live дизейблится сразу на клик — `⏳` + `Starting...`. - **Secure button**: `fetch('/api/secure', {token})` вместо мёртвого `poe2://`. - **Ошибки**: отображаются в статус-баре (красный текст). - **Sound**: `new Audio('/sound.mp3').play()` вместо `\x07`. ### Баги - CORS: переменная переименована `headers`→`corsHeaders` чтоб не затенять глобальную `headers()`. - WS: убран пинг (PoE дропает сам), добавлен автоматический реконнект. - JSON parse on server: исправлена отправка `Content-Length` (предыдущий баг с curl был из-за отсутствия `req.end()`). ## Как это работает 1. Search → PoE API возвращает `listing.hideout_token` (JWT) **только** когда в запросе есть `POESESSID` + `POETOKEN`. 2. User жмёт Secure → фронтенд шлёт `POST /api/secure {token}`. 3. Сервер проксит `POST /api/trade2/whisper {token}` с полными куками. 4. PoE API отвечает `{"error":{"code":2,"message":"Your account must be in-game..."}}` — ожидаемо, работает только в игре. 5. Live: WS `wss://.../api/trade2/live/poe2/{league}/{qid}` + polling fallback 30s. ## Известные проблемы - **Рейт-лимит PoE** (~1 req/s на аккаунт). При превышении — ждать N минут. После долгого тестирования может быть 25-30 мин. - **WS дропается через ~10с** (код 1006) — сервер PoE сам закрывает. Autoreconnect держит соединение. Если WS не взлетает (Cloudflare), работает polling раз в 30с. - **`curl.exe`** к PoE API не работает — Cloudflare блокирует. Только через Node.js `fetch()` или браузер. - **`cf_clearance`** кука в WS не передаётся — если Cloudflare начинает дропать WSS, переходим на polling. ## Config - `config.json`: `poeSessionId` (POESESSID) + `poeToken` (POETOKEN JWT) - `seen.json`: cache of seen item IDs - Никакого `startup.json` — удалён, не нужен ## Как запускать ```powershell # Full scan (консоль) node scanner.mjs # Serve mode (http://localhost:3999) node scanner.mjs --serve # Live mode (консоль) node scanner.mjs --live ``` ## Ключевые файлы - `scanner.mjs` — main scanner + HTTP server (всё в одном) - `config.json` — настройки + авторизация - `launch.vbs` — скрытый запуск через полные пути - `AGENTS.md` — этот файл - `sound.mp3` — звук уведомления ## Сессионный ритуал При старте сессии с агентом **в первую очередь** читать папку `C:\Users\shama\Desktop\skills\pohuy\`: - `SKILL.md` — базовый режим - `references/slovar.md` — словарь - `references/sceny.md` — шкала и сцены Вести себя в стиле **ultra**-режима скилла `pohuy` (идиоматический русский мат, инженерная лексика, плотность ultra). Не сползать обратно в вежливость. Выключение: «нормальный режим» / «хватит материться».