Support multi-screenshot calibration and cached shop context

This commit is contained in:
2026-08-11 17:43:32 +03:00
parent f87a65bb04
commit cf1cb41f04
8 changed files with 507 additions and 84 deletions
+16 -10
View File
@@ -9,7 +9,8 @@
```bash
npm install
cp .env.local.example .env.local
# Заполни L2_MARKET_IMPORT_TOKEN тем же значением, что HOME_SERVICE_L2_MARKET_IMPORT_TOKEN в Gitea Secrets.
# Сгенерируй один случайный токен, сразу сохрани его и в .env.local,
# и как новый Gitea Secret HOME_SERVICE_L2_MARKET_IMPORT_TOKEN.
npm run dev
```
@@ -27,7 +28,8 @@ npm run dev
├─ нет → заголовок и tooltip не проверяются
└─ да
├─ OCR `Private Store(Buy/Sell) - имя`
└─ тип сделки + имя торговца
├─ виден → запомнить тип сделки + имя торговца
│ └─ закрыт tooltip → использовать последний запомненный магазин
└─ поиск Price : внутри зоны tooltip
├─ нет → название и цена не читаются
└─ да → OCR точной строки названия и точной строки цены
@@ -37,6 +39,8 @@ npm run dev
Из заголовка `Private Store(Buy) - Hikvision` получится `side: "buy"`, `merchant: "Hikvision"`; из `Private Store(Sell) - Dwa``side: "sell"`, `merchant: "Dwa"`.
Контекст хранится отдельно для каждого захватываемого окна. Пока нижний маркер магазина остаётся виден, tooltip относится к последнему успешно распознанному заголовку этого окна. После трёх кадров без маркера контекст сбрасывается, чтобы предметы следующего магазина не попали в предыдущий. Если заголовок ещё ни разу не распознан, предмет из tooltip не сохраняется.
## Сценарий
1. В разделе «Источники» нажми «Добавить окно» для каждого окна игры.
@@ -47,18 +51,20 @@ npm run dev
6. Внутри tooltip обведи только постоянную надпись `Price :`.
7. Отдельно выдели точную строку названия и точную строку цены. Для названия лучше использовать длинный предмет и оставить запас справа.
8. Сохрани калибровку, нажми «Начать сбор» и вернись в игру.
9. Наводи курсор на каждый предмет. Уникальные пары `название + цена` будут накапливаться в таблице, а каждое распознавание — сохраняться с датой и отправляться на сервер.
9. Сначала оставь курсор вне предметов, пока в результате не появятся тип сделки и имя торговца.
10. Наводи курсор на каждый предмет. Даже если tooltip закроет заголовок, предмет будет записан в последний найденный магазин.
Наблюдения сначала попадают в IndexedDB браузера, затем отправляются пакетами раз в 30 секунд. При недоступном сервере пакет остаётся локально и повторяется с тем же ID после восстановления связи или перезапуска страницы; сервер не создаёт дубликат.
Для калибровки нужен скриншот, на котором одновременно видны:
Калибровку можно сделать по снимкам разного размера и с торговым окном в разных местах:
- нижняя часть торгового окна;
- заголовок `Private Store(Buy/Sell) - имя`;
- открытый tooltip предмета;
- полная строка названия и полная строка `Price`.
1. Без tooltip выдели нижний маркер и заголовок `Private Store(Buy/Sell) - имя`.
2. Добавь второй снимок с tooltip. Калибратор сам найдёт нижний маркер по всему новому кадру и перенесёт относительно него остальные области.
3. На втором снимке выдели зону tooltip, `Price :`, название и цену. Уже выбранные области сохраняются.
После выбора всех шести областей нажми «Проверить на скриншоте». Подключать игровое окно для этого не нужно.
Размер игрового окна и положение торгового окна могут отличаться. Масштаб интерфейса Lineage II должен оставаться тем же: шаблоны ищутся в исходном пиксельном размере.
После выбора всех шести областей нажми «Проверить снимки». Они обрабатываются по порядку: сначала кадр с видимым заголовком запоминает магазин, затем кадр с tooltip добавляет предмет. Подключать игровое окно для этого не нужно.
### Что именно выделять
@@ -83,7 +89,7 @@ npm run dev
- «Пропущено» означает, что предыдущий обязательный этап не прошёл;
- рядом с OCR показываются фактический crop, текст и уверенность.
Если не находится магазин, смотри crop «Маркер магазина» и процент совпадения. Если магазин найден, но тип или имя пустые, смотри crop и фактический OCR этапа «Заголовок магазина». Если магазин найден, но предмет не появляется, смотри «Якорь Price :». Если оба якоря найдены, проблема уже в точных crop названия или цены.
Если не находится магазин, смотри crop «Маркер магазина» и процент совпадения. Если тип или имя ещё не определены, убери курсор с предмета и смотри фактический OCR этапа «Заголовок магазина». Надпись «Используется последний магазин» означает, что tooltip закрыл заголовок, но привязка предмета сохранена. Если магазин найден, но предмет не появляется, смотри «Якорь Price :». Если оба якоря найдены, проблема уже в точных crop названия или цены.
Диагностические изображения существуют только в памяти открытой страницы. Они не попадают в JSON результата и не отправляются вместе с рыночными наблюдениями.