Improve L2 market parsing and data handling

This commit is contained in:
2026-08-11 22:24:36 +03:00
parent de41230b9b
commit af9cd1e92d
58 changed files with 2474 additions and 444 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

+14
View File
@@ -0,0 +1,14 @@
{
"source": "reviewed screenshot crops; replace with real /api/l2/items icon bytes before accepting live catalog-match evidence",
"items": {
"soulshot-c-grade": { "id": "fixture-soulshot-c-grade", "name": "Soulshot C grade", "iconUrl": "/data/fixture-assets/catalog/soulshot-c-grade.png", "matchScore": 1 },
"blessed-spiritshot-d-grade": { "id": "fixture-blessed-spiritshot-d-grade", "name": "Blessed Spiritshot D Grade", "iconUrl": "/data/fixture-assets/catalog/blessed-spiritshot-d-grade.png", "matchScore": 1 },
"spellbook-prominence": { "id": "fixture-spellbook-prominence", "name": "Spellbook Prominence", "iconUrl": "/data/fixture-assets/catalog/spellbook-prominence.png", "matchScore": 1 },
"brigandine-helmet": { "id": "fixture-brigandine-helmet", "name": "Brigandine Helmet", "iconUrl": "/data/fixture-assets/catalog/brigandine-helmet.png", "matchScore": 1 },
"tutorial-guide": { "id": "fixture-tutorial-guide", "name": "Tutorial Guide", "iconUrl": "/data/fixture-assets/catalog/tutorial-guide.png", "matchScore": 1 },
"dimensional-fragment": { "id": "fixture-dimensional-fragment", "name": "Dimensional Fragment", "iconUrl": "/data/fixture-assets/catalog/dimensional-fragment.png", "matchScore": 1 },
"ancient-adena": { "id": "fixture-ancient-adena", "name": "Ancient Adena", "iconUrl": "/data/fixture-assets/catalog/ancient-adena.png", "matchScore": 1 },
"scroll-enchant-weapon-d": { "id": "fixture-scroll-enchant-weapon-d", "name": "Scroll Enchant Weapon D", "iconUrl": "/data/fixture-assets/catalog/scroll-enchant-weapon-d.png", "matchScore": 1 },
"coarse-bone-powder": { "id": "fixture-coarse-bone-powder", "name": "Coarse Bone Powder", "iconUrl": "/data/fixture-assets/catalog/coarse-bone-powder.png", "matchScore": 1 }
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+51
View File
@@ -0,0 +1,51 @@
{
"version": 1,
"frame": { "width": 1560, "height": 1360 },
"saleAnchor": {
"image": "fixture-assets/templates/sale-anchor.png",
"width": 79,
"height": 29
},
"storeHeaderRegion": {
"offsetX": -162,
"offsetY": -356,
"width": 222,
"height": 18
},
"tooltipSearchRegion": {
"offsetX": -300,
"offsetY": -430,
"width": 650,
"height": 220
},
"tooltipAnchor": {
"image": "fixture-assets/templates/tooltip-anchor.png",
"width": 42,
"height": 17
},
"itemNameRegion": {
"offsetX": -3,
"offsetY": -28,
"width": 260,
"height": 17
},
"itemPriceRegion": {
"offsetX": 0,
"offsetY": 0,
"width": 260,
"height": 17
},
"sellItemGridRegion": {
"offsetX": -164,
"offsetY": -305,
"width": 222,
"height": 111
},
"buyItemGridRegion": {
"offsetX": -164,
"offsetY": -305,
"width": 222,
"height": 111
},
"threshold": 0.76
}
+360
View File
@@ -0,0 +1,360 @@
{
"version": 1,
"viewerCharacter": "Deela",
"frame": { "width": 1560, "height": 1360 },
"calibration": "fixture-calibration.json",
"cases": [
{
"id": "sell-domestos-clean",
"file": "Discord_7xmx8OSuCH.jpg",
"groupId": "sell-domestos",
"order": 0,
"scene": "clean",
"mode": "standalone",
"expected": {
"side": "sell",
"merchant": "Domestos",
"occupiedSlots": [0],
"pendingSlots": [0],
"foundSlots": []
}
},
{
"id": "sell-crom-clean",
"file": "Discord_K9RkTrU6B2.jpg",
"groupId": "sell-crom",
"order": 0,
"scene": "clean",
"mode": "standalone",
"expected": {
"side": "sell",
"merchant": "Crom",
"occupiedSlots": [0, 1],
"pendingSlots": [0, 1],
"foundSlots": []
}
},
{
"id": "sell-gnumli-clean",
"file": "Discord_w3Smu4bOQK.jpg",
"groupId": "sell-gnumli",
"order": 0,
"scene": "clean",
"mode": "sequence",
"expected": {
"side": "sell",
"merchant": "Gnumli",
"occupiedSlots": [0, 1],
"pendingSlots": [0, 1],
"foundSlots": []
}
},
{
"id": "sell-gnumli-soulshot",
"file": "Discord_ARWzEIaayl.jpg",
"groupId": "sell-gnumli",
"order": 1,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "soulshot-c-grade",
"expected": {
"side": "sell",
"merchant": "Gnumli",
"occupiedSlots": [0, 1],
"hoveredSlot": 0,
"pendingSlots": [1],
"foundSlots": [0],
"item": {
"displayName": "Soulshot: C-grade",
"name": "Soulshot C grade",
"quantity": 36370,
"priceAdena": 20,
"priceMode": "price"
}
}
},
{
"id": "sell-gnumli-blessed-spiritshot",
"file": "Discord_qy3EYIEcMV.jpg",
"groupId": "sell-gnumli",
"order": 2,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "blessed-spiritshot-d-grade",
"expected": {
"side": "sell",
"merchant": "Gnumli",
"occupiedSlots": [0, 1],
"hoveredSlot": 1,
"pendingSlots": [],
"foundSlots": [0, 1],
"item": {
"displayName": "Blessed Spiritshot: D-Grade",
"name": "Blessed Spiritshot D Grade",
"quantity": 7245,
"priceAdena": 58,
"priceMode": "price"
}
}
},
{
"id": "sell-boroda4-clean",
"file": "Discord_sSJAGZLHvm.jpg",
"groupId": "sell-boroda4",
"order": 0,
"scene": "clean",
"mode": "sequence",
"expected": {
"side": "sell",
"merchant": "Boroda4",
"occupiedSlots": [0, 1],
"pendingSlots": [0, 1],
"foundSlots": []
}
},
{
"id": "sell-boroda4-spellbook",
"file": "Discord_KL0fnDcvr7.jpg",
"groupId": "sell-boroda4",
"order": 1,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "spellbook-prominence",
"expected": {
"side": "sell",
"merchant": "Boroda4",
"occupiedSlots": [0, 1],
"hoveredSlot": 0,
"pendingSlots": [1],
"foundSlots": [0],
"item": {
"displayName": "Spellbook: Prominence",
"name": "Spellbook Prominence",
"quantity": 2,
"priceAdena": 50000,
"priceMode": "price"
}
}
},
{
"id": "sell-boroda4-helmet",
"file": "Discord_dxpCzaJEWD.jpg",
"groupId": "sell-boroda4",
"order": 2,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "brigandine-helmet",
"expected": {
"side": "sell",
"merchant": "Boroda4",
"occupiedSlots": [0, 1],
"hoveredSlot": 1,
"pendingSlots": [],
"foundSlots": [0, 1],
"item": {
"displayName": "Brigandine Helmet",
"name": "Brigandine Helmet",
"quantity": 1,
"priceAdena": 800000,
"priceMode": "price"
}
}
},
{
"id": "sell-shotd-clean",
"file": "Discord_uqGcQhxIWc.jpg",
"groupId": "sell-shotd",
"order": 0,
"scene": "clean",
"mode": "sequence",
"expected": {
"side": "sell",
"merchant": "shotD",
"occupiedSlots": [0, 1],
"pendingSlots": [0, 1],
"foundSlots": []
}
},
{
"id": "sell-shotd-tutorial-guide",
"file": "Discord_fb9f61z8Ek.jpg",
"groupId": "sell-shotd",
"order": 1,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "tutorial-guide",
"expected": {
"side": "sell",
"merchant": "shotD",
"occupiedSlots": [0, 1],
"hoveredSlot": 0,
"pendingSlots": [1],
"foundSlots": [0],
"item": {
"displayName": "Tutorial Guide",
"name": "Tutorial Guide",
"quantity": 1,
"priceAdena": 5000000,
"priceMode": "price"
}
}
},
{
"id": "sell-shotd-dimensional-fragment",
"file": "Discord_ezvlzpNHRg.jpg",
"groupId": "sell-shotd",
"order": 2,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "dimensional-fragment",
"expected": {
"side": "sell",
"merchant": "shotD",
"occupiedSlots": [0, 1],
"hoveredSlot": 1,
"pendingSlots": [],
"foundSlots": [0, 1],
"item": {
"displayName": "Dimensional Fragment",
"name": "Dimensional Fragment",
"quantity": 687,
"priceAdena": 3500,
"priceMode": "price"
}
}
},
{
"id": "sell-1shop-clean",
"file": "Discord_tJFxvFi7DM.jpg",
"groupId": "sell-1shop",
"order": 0,
"scene": "clean",
"mode": "sequence",
"expected": {
"side": "sell",
"merchant": "1SHOP",
"occupiedSlots": [0],
"pendingSlots": [0],
"foundSlots": []
}
},
{
"id": "sell-1shop-ancient-adena",
"file": "Discord_fFbzX9vDhW.jpg",
"groupId": "sell-1shop",
"order": 1,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "ancient-adena",
"expected": {
"side": "sell",
"merchant": "1SHOP",
"occupiedSlots": [0],
"hoveredSlot": 0,
"pendingSlots": [],
"foundSlots": [0],
"item": {
"displayName": "Ancient Adena",
"name": "Ancient Adena",
"quantity": 1793000,
"priceAdena": 3,
"priceMode": "price"
}
}
},
{
"id": "buy-rakot-clean",
"file": "Discord_wQc5FDayAK.jpg",
"groupId": "buy-rakot",
"order": 0,
"scene": "clean",
"mode": "sequence",
"expected": {
"side": "buy",
"merchant": "RAKOT",
"occupiedSlots": [0, 1, 2],
"pendingSlots": [0, 1, 2],
"foundSlots": []
}
},
{
"id": "buy-rakot-scroll",
"file": "Discord_TxbA20ZOQB.jpg",
"groupId": "buy-rakot",
"order": 1,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "scroll-enchant-weapon-d",
"expected": {
"side": "buy",
"merchant": "RAKOT",
"occupiedSlots": [0, 1, 2],
"hoveredSlot": 0,
"pendingSlots": [1, 2],
"foundSlots": [0],
"item": {
"displayName": "Scroll: Enchant Weapon (D)",
"name": "Scroll Enchant Weapon D",
"quantity": 0,
"priceAdena": 200000,
"priceMode": "each"
}
}
},
{
"id": "buy-rakot-coarse-bone-powder",
"file": "Discord_ikzA9VhROZ.jpg",
"groupId": "buy-rakot",
"order": 2,
"scene": "tooltip",
"mode": "sequence",
"catalogAssetId": "coarse-bone-powder",
"expected": {
"side": "buy",
"merchant": "RAKOT",
"occupiedSlots": [0, 1, 2],
"hoveredSlot": 2,
"pendingSlots": [1],
"foundSlots": [0, 2],
"item": {
"displayName": "Coarse Bone Powder",
"name": "Coarse Bone Powder",
"quantity": 0,
"priceAdena": 1,
"priceMode": "each"
}
}
},
{
"id": "buy-kapayji-ancient-adena",
"file": "Discord_2KrJ9GGjCP.jpg",
"groupId": "buy-kapayji",
"order": 0,
"scene": "tooltip",
"mode": "contextual",
"catalogAssetId": "ancient-adena",
"initialState": {
"side": "buy",
"merchant": "KapayJI",
"activeShopKey": "buy:kapayji",
"pendingSlots": [0],
"foundSlots": []
},
"expected": {
"side": "buy",
"merchant": "KapayJI",
"occupiedSlots": [0],
"hoveredSlot": 0,
"pendingSlots": [],
"foundSlots": [0],
"item": {
"displayName": "Ancient Adena",
"name": "Ancient Adena",
"quantity": 0,
"priceAdena": 2,
"priceMode": "each"
}
}
}
]
}