Merge pull request #658 from Kvan7:dev

v0.12.0
This commit is contained in:
Kvan7
2025-09-09 23:34:43 -05:00
committed by GitHub
48 changed files with 923 additions and 1149 deletions

View File

@@ -8,12 +8,28 @@ body:
value: |
Thanks for taking the time to fill out this bug report!
- type: checkboxes
id: terms
id: faq
attributes:
label: FAQ
description: Please check the [FAQ](https://kvan7.github.io/Exiled-Exchange-2/faq), [Common Issues Page](https://kvan7.github.io/Exiled-Exchange-2/issues), and for [pinned issues and existing issues](https://github.com/Kvan7/Exiled-Exchange-2/issues?q=is%3Aissue) before submitting an issue
description: Please check the [FAQ](https://kvan7.github.io/Exiled-Exchange-2/faq) before submitting an issue
options:
- label: I have checked the FAQ, Common Issues, and for existing issues and my problem was not there
- label: I have checked the [FAQ](https://kvan7.github.io/Exiled-Exchange-2/faq) and my problem was not there
required: true
- type: checkboxes
id: common-issues
attributes:
label: Common Issues
description: Please check the [Common Issues Page](https://kvan7.github.io/Exiled-Exchange-2/issues) before submitting an issue
options:
- label: I have checked the [Common Issues Page](https://kvan7.github.io/Exiled-Exchange-2/issues) and my problem was not there
required: true
- type: checkboxes
id: existing-issues
attributes:
label: Existing Issues
description: Please check the [pinned issues and existing issues](https://github.com/Kvan7/Exiled-Exchange-2/issues?q=is%3Aissue) before submitting an issue
options:
- label: I have checked the [pinned issues and existing issues](https://github.com/Kvan7/Exiled-Exchange-2/issues?q=is%3Aissue) and my problem was not there
required: true
- type: dropdown
id: common-bug
@@ -25,7 +41,7 @@ body:
- Not Recognized Modifier
- No modifiers found
- Other
default: 0
default: 3
validations:
required: true
- type: textarea
@@ -34,7 +50,7 @@ body:
label: What happened?
description: Also what did you expect to happen?
placeholder: Tell us what you see!
value: "A bug happened!"
value: "Change this text please"
validations:
required: true
- type: dropdown
@@ -43,27 +59,27 @@ body:
label: Version
description: What version of EE2 are you running? You can see this in Settings -> About
options:
- 0.11.6
- 0.11.5
- 0.11.4
- 0.11.3
- 0.11.2
- 0.12.0
- 0.11.x
- 0.10.x
- 0.9.x
- 0.8.x
- Other
default: 0
validations:
required: true
- type: textarea
id: item
attributes:
label: Item Copy text
description: If your bug relates in ANY way to an item, copy the item's text and paste it here. You can do so with `ctrl + alt + c` when hovering over the item.
description: PLEASE copy the item's text and paste it here. You can do so with `ctrl + alt + c` when hovering over the item, if your bug doesn't related to any items at all, write "None" (if it is about an item in any way and you write None it will be ignored)
render: shell
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: If able, please go to Settings -> Debug, and copy and paste what is in that text box. (No need for backticks)
label: Log output
description: Please go to Settings -> Debug, and copy and paste what is in that text box. (No need for backticks)
render: shell
validations:
required: true

View File

@@ -1,6 +1,6 @@
# ![Perfect Jewelers Orb](./renderer/public/images/jeweler.png) Exiled Exchange 2
![GitHub Downloads (specific asset, latest release)](https://img.shields.io/github/downloads/kvan7/exiled-exchange-2/latest/Exiled-Exchange-2-Setup-0.11.6.exe?style=plastic&link=https%3A%2F%2Ftooomm.github.io%2Fgithub-release-stats%2F%3Fusername%3Dkvan7%26repository%3DExiled-Exchange-2)
![GitHub Downloads (specific asset, latest release)](https://img.shields.io/github/downloads/kvan7/exiled-exchange-2/latest/Exiled-Exchange-2-Setup-0.12.0.exe?style=plastic&link=https%3A%2F%2Ftooomm.github.io%2Fgithub-release-stats%2F%3Fusername%3Dkvan7%26repository%3DExiled-Exchange-2)
![GitHub Tag](https://img.shields.io/github/v/tag/kvan7/exiled-exchange-2?style=plastic&label=latest%20version)
![GitHub commits since latest release (branch)](https://img.shields.io/github/commits-since/kvan7/exiled-exchange-2/latest/dev?style=plastic)

View File

@@ -20,7 +20,7 @@ export default defineConfig({
},
themeConfig: {
// logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
appVersion: '0.11.6',
appVersion: '0.12.0',
github: {
releasesUrl: 'https://github.com/Kvan7/Exiled-Exchange-2/releases'
},

View File

@@ -1,12 +1,12 @@
{
"name": "exiled-exchange-2",
"version": "0.11.6",
"version": "0.12.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "exiled-exchange-2",
"version": "0.11.6",
"version": "0.12.0",
"dependencies": {
"electron-overlay-window": "3.3.1",
"uiohook-napi": "1.5.x"

View File

@@ -1,6 +1,6 @@
{
"name": "exiled-exchange-2",
"version": "0.11.6",
"version": "0.12.0",
"private": true,
"scripts": {
"dev": "node build/script.mjs",

View File

@@ -13,6 +13,8 @@ const PROXY_HOSTS = [
{ host: "br.pathofexile.com", official: true },
{ host: "poe.ninja", official: false },
{ host: "www.poeprices.info", official: false },
// me :)
{ host: "api.exiledexchange2.dev", official: false },
];
// eslint-disable-next-line @typescript-eslint/no-extraneous-class

View File

@@ -894,7 +894,7 @@
{"name": "裘洛托的戰爭靈魂核心", "refName": "Cholotl's Soul Core of War", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUHJvamVjdGlsZSIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/dfc35bed7f/NewSoulCoreProjectile.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "cholotls-soul-core-of-war", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Bow", "string": "投射物速度增加 #%", "values": [20], "tradeId": null}]}
{"name": "繫帶長靴", "refName": "Cinched Boots", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb290cy9CYXNldHlwZXMvQm9vdHNEZXgwMiIsInciOjIsImgiOjIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/b82526a3d4/BootsDex02.png", "tags": ["dex_armour"], "craftable": {"category": "Boots"}, "w": 2, "h": 2, "armour": {"ev": [166, 166]}}
{"name": "五指短劍", "refName": "Cinquedea", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9PbmVIYW5kV2VhcG9ucy9EYWdnZXJzL0Jhc2V0eXBlcy9EYWdnZXIxMyIsInciOjEsImgiOjMsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/6bb4f89a78/Dagger13.png", "tags": [], "craftable": {"category": "Dagger"}, "w": 1, "h": 3}
{"name": "希特克拉多的腐壞靈魂核心", "refName": "Citaqualotl's Soul Core of Foulness", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlQ2hhb3MyIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/002059f8f5/NewSoulCoreChaos2.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "citaqualotls-soul-core-of-foulness", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": ["Bow", "Claw", "Crossbow", "Dagger", "Flail", "One Hand Axe", "One Hand Mace", "One Hand Sword", "Spear", "Two Hand Axe", "Two Hand Mace", "Two Hand Sword", "Warstaff"], "string": "附加 # 至 # 混沌傷害", "values": [19, 29], "tradeId": null}]}
{"name": "希特克拉多的腐壞靈魂核心", "refName": "Citaqualotl's Soul Core of Foulness", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlQ2hhb3MyIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/002059f8f5/NewSoulCoreChaos2.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "citaqualotls-soul-core-of-foulness", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": ["Bow", "Claw", "Crossbow", "Dagger", "Flail", "One Hand Axe", "One Hand Mace", "One Hand Sword", "Spear", "Two Hand Axe", "Two Hand Mace", "Two Hand Sword", "Warstaff"], "string": "附加 # 至 # 混沌傷害", "values": [19, 29], "tradeId": ["rune.stat_2223678961"]}]}
{"name": "教士法衣", "refName": "Cleric Vestments", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb2R5QXJtb3Vycy9CYXNldHlwZXMvQm9keUludFN0cjA3IiwidyI6MiwiaCI6Mywic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/3e7354e684/BodyIntStr07.png", "tags": ["str_int_armour", "karui_basetype"], "craftable": {"category": "Body Armour"}, "w": 2, "h": 3, "armour": {"ar": [151, 151], "es": [54, 54]}}
{"name": "斗篷鎖甲", "refName": "Cloaked Mail", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb2R5QXJtb3Vycy9CYXNldHlwZXMvQm9keVN0ckRleDA0IiwidyI6MiwiaCI6Mywic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/d8e02875f2/BodyStrDex04.png", "tags": ["str_dex_armour", "maraketh_basetype"], "craftable": {"category": "Body Armour"}, "w": 2, "h": 3, "armour": {"ar": [95, 95], "ev": [83, 83]}}
{"name": "緊閉之盔", "refName": "Closed Helm", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9IZWxtZXRzL0Jhc2V0eXBlcy9IZWxtZXRTdHJEZXgwNiIsInciOjIsImgiOjIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/b2bcd2cacb/HelmetStrDex06.png", "tags": ["str_dex_armour", "karui_basetype"], "craftable": {"category": "Helmet"}, "w": 2, "h": 2, "armour": {"ar": [99, 99], "ev": [89, 89]}}
@@ -1204,7 +1204,7 @@
{"name": "警惕之盔", "refName": "Guarded Helm", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9IZWxtZXRzL0Jhc2V0eXBlcy9IZWxtZXRTdHJEZXgwMiIsInciOjIsImgiOjIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/76592dc5c5/HelmetStrDex02.png", "tags": ["str_dex_armour", "ezomyte_basetype"], "craftable": {"category": "Helmet"}, "w": 2, "h": 2, "armour": {"ar": [34, 34], "ev": [28, 28]}}
{"name": "防衛者之弓", "refName": "Guardian Bow", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9Ud29IYW5kV2VhcG9ucy9Cb3dzL0Jhc2V0eXBlcy9Cb3cwMyIsInciOjIsImgiOjQsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/9ef6f2ee3a/Bow03.png", "tags": [], "craftable": {"category": "Bow"}, "w": 2, "h": 4}
{"name": "守護細杖", "refName": "Guardian Quarterstaff", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9Ud29IYW5kV2VhcG9ucy9XYXJTdGF2ZXMvV2Fyc3RhZmYwOCIsInciOjIsImgiOjQsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/3efb44d8ce/Warstaff08.png", "tags": [], "craftable": {"category": "Warstaff"}, "w": 2, "h": 4}
{"name": "瓜特利斯的的耐久靈魂核心", "refName": "Guatelitzi's Soul Core of Endurance", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlRW5kdXJhbmNlQ2hhcmdlIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/8da8c1e799/NewSoulCoreEnduranceCharge.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "guatelitzis-soul-core-of-endurance", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1}
{"name": "瓜特利斯的的耐久靈魂核心", "refName": "Guatelitzi's Soul Core of Endurance", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlRW5kdXJhbmNlQ2hhcmdlIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/8da8c1e799/NewSoulCoreEnduranceCharge.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "guatelitzis-soul-core-of-endurance", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": ["Bow", "Claw", "Crossbow", "Dagger", "Flail", "One Hand Axe", "One Hand Mace", "One Hand Sword", "Spear", "Two Hand Axe", "Two Hand Mace", "Two Hand Sword", "Warstaff"], "string": "當你獲得一顆耐力球時,有 #% 機率獲得一顆額外的耐力球", "values": [50], "tradeId": ["rune.stat_1228682002"]}, {"categories": ["Staff", "Wand"], "string": "當你獲得一顆耐力球時,有 #% 機率獲得一顆額外的耐力球", "values": [50], "tradeId": ["rune.stat_1228682002"]}]}
{"name": "挑腸輕盾", "refName": "Gutspike Buckler", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvT2ZmaGFuZC9TaGllbGRzL0J1Y2tsZXIwNiIsInciOjIsImgiOjIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/b523f2b5bb/Buckler06.png", "tags": ["dex_armour", "dex_shield"], "craftable": {"category": "Buckler"}, "w": 2, "h": 2, "armour": {"ev": [122, 122]}}
{"name": "聖潔之冠", "refName": "Hallowed Crown", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9IZWxtZXRzL0Jhc2V0eXBlcy9IZWxtZXRJbnRTdHIwNCIsInciOjIsImgiOjIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/2cf2a643af/HelmetIntStr04.png", "tags": ["str_int_armour"], "craftable": {"category": "Helmet"}, "w": 2, "h": 2, "armour": {"ar": [113, 113], "es": [40, 40]}}
{"name": "聖潔法器", "refName": "Hallowed Focus", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvT2ZmaGFuZC9Gb2NpL0Jhc2V0eXBlcy9Gb2N1czA4IiwidyI6MiwiaCI6Mywic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/64fc1e2b9f/Focus08.png", "tags": ["int_armour"], "craftable": {"category": "Focus"}, "w": 2, "h": 3, "armour": {"es": [50, 50]}}
@@ -1844,7 +1844,7 @@
{"name": "雙生鏈錘", "refName": "Twin Flail", "namespace": "ITEM", "icon": "%NOT_FOUND%", "tags": ["maraketh_basetype"], "craftable": {"category": "Flail"}, "w": 2, "h": 3}
{"name": "雙尖箭袋", "refName": "Two-Point Quiver", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvUXVpdmVycy9CYXNldHlwZXMvUXVpdmVyVHdvUG9pbnQiLCJ3IjoyLCJoIjozLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/cca38d7cc5/QuiverTwoPoint.png", "tags": [], "craftable": {"category": "Quiver"}, "w": 2, "h": 3}
{"name": "查莫托的狂暴靈魂核心", "refName": "Tzamoto's Soul Core of Ferocity", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUmFnZSIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/7bbacc1706/NewSoulCoreRage.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "tzamotos-soul-core-of-ferocity", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Helmet", "string": "# 層最大盛怒", "values": [4], "tradeId": null}]}
{"name": "烏拉曼的邪眼", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "偏斜抵禦傷害量 #%", "values": [3], "tradeId": null}]}
{"name": "烏拉曼的邪眼", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "抵禦偏斜擊中的 #% 傷害", "values": [3], "tradeId": null}]}
{"name": "終極生命藥劑", "refName": "Ultimate Life Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTGlmZTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/8ed5f669f0/FlaskLife09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "終極魔力藥劑", "refName": "Ultimate Mana Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTWFuYTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/ff9d3e75d9/FlaskMana09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "終極巨劍", "refName": "Ultra Greatsword", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9Ud29IYW5kV2VhcG9ucy9Ud29IYW5kU3dvcmRzL0Jhc2V0eXBlcy8ySFN3b3JkMTMiLCJ3IjoyLCJoIjo0LCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/6297c060ee/2HSword13.png", "tags": [], "craftable": {"category": "Two Hand Sword"}, "w": 2, "h": 4}
@@ -1989,7 +1989,7 @@
{"name": "龍鱗外套", "refName": "Wyrmscale Coat", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQXJtb3Vycy9Cb2R5QXJtb3Vycy9CYXNldHlwZXMvQm9keURleDA4IiwidyI6MiwiaCI6Mywic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/a43ac39920/BodyDex08.png", "tags": ["dex_armour"], "craftable": {"category": "Body Armour"}, "w": 2, "h": 3, "armour": {"ev": [406, 406]}}
{"name": "烈許的寶庫鑰匙", "refName": "Xesht's Reliquary Key", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvTWFwcy9Ud2lsaWdodE9yZGVyUmVsaXF1YXJ5S2V5QnJlYWNoIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/866c9d5c45/TwilightOrderReliquaryKeyBreach.png", "tags": ["fake_currency"], "tradeTag": "xeshts-reliquary-key", "craftable": {"category": "VaultKey"}, "w": 1, "h": 1}
{"name": "席波卡多的支配靈魂核心", "refName": "Xipocado's Soul Core of Dominion", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlTWluaW9uIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b1e7975db2/NewSoulCoreMinion.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "xipocados-soul-core-of-dominion", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1}
{"name": "柔派克的力量靈魂核心", "refName": "Xopec's Soul Core of Power", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUG93ZXJDaGFyZ2UiLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/083d39a63b/NewSoulCorePowerCharge.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "xopecs-soul-core-of-power", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1}
{"name": "柔派克的力量靈魂核心", "refName": "Xopec's Soul Core of Power", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUG93ZXJDaGFyZ2UiLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/083d39a63b/NewSoulCorePowerCharge.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "xopecs-soul-core-of-power", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": ["Bow", "Claw", "Crossbow", "Dagger", "Flail", "One Hand Axe", "One Hand Mace", "One Hand Sword", "Spear", "Two Hand Axe", "Two Hand Mace", "Two Hand Sword", "Warstaff"], "string": "當你獲得一顆暴擊球時,有 #% 機率獲得一顆額外的暴擊球", "values": [50], "tradeId": ["rune.stat_3537994888"]}, {"categories": ["Staff", "Wand"], "string": "當你獲得一顆暴擊球時,有 #% 機率獲得一顆額外的暴擊球", "values": [50], "tradeId": ["rune.stat_3537994888"]}]}
{"name": "火焰催化劑", "refName": "Xoph's Catalyst", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQnJlYWNoL0JyZWFjaENhdGFseXN0RmlyZSIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/05b1999374/BreachCatalystFire.png", "tags": ["catalyst"], "tradeTag": "xophs-catalyst", "craftable": {"category": "Currency"}, "w": 1, "h": 1}
{"name": "札拉提的絕緣靈魂核心", "refName": "Zalatl's Soul Core of Insulation", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlTGlnaHRuaW5nIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/80c455f775/NewSoulCoreLightning.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "zalatls-soul-core-of-insulation", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1}
{"name": "澤洛克的寶庫鑰匙:力抗黑暗", "refName": "Zarokh's Reliquary Key: Against the Darkness", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvTWFwcy9Ud2lsaWdodE9yZGVyUmVsaXF1YXJ5S2V5U2FuY3R1bTIiLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/a9e91de8f5/TwilightOrderReliquaryKeySanctum2.png", "tags": ["fake_currency"], "tradeTag": "against-the-darkness", "craftable": {"category": "VaultKey"}, "w": 1, "h": 1}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1844,7 +1844,7 @@
{"name": "双頭のフレイル", "refName": "Twin Flail", "namespace": "ITEM", "icon": "%NOT_FOUND%", "tags": ["maraketh_basetype"], "craftable": {"category": "Flail"}, "w": 2, "h": 3}
{"name": "二股の矢筒", "refName": "Two-Point Quiver", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvUXVpdmVycy9CYXNldHlwZXMvUXVpdmVyVHdvUG9pbnQiLCJ3IjoyLCJoIjozLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/cca38d7cc5/QuiverTwoPoint.png", "tags": [], "craftable": {"category": "Quiver"}, "w": 2, "h": 3}
{"name": "ザモトの凶暴性のソウルコア", "refName": "Tzamoto's Soul Core of Ferocity", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUmFnZSIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/7bbacc1706/NewSoulCoreRage.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "tzamotos-soul-core-of-ferocity", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Helmet", "string": "憤怒の最大数 #", "values": [4], "tradeId": null}]}
{"name": "ウラマンの凝視", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "受け流しにより防ぐダメージ量 #%", "values": [3], "tradeId": null}]}
{"name": "ウラマンの凝視", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "受け流したヒットのダメージから防ぐ量が#%される", "values": [3], "tradeId": null}]}
{"name": "究極のライフフラスコ", "refName": "Ultimate Life Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTGlmZTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/8ed5f669f0/FlaskLife09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "究極のマナフラスコ", "refName": "Ultimate Mana Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTWFuYTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/ff9d3e75d9/FlaskMana09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "特大剣", "refName": "Ultra Greatsword", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9Ud29IYW5kV2VhcG9ucy9Ud29IYW5kU3dvcmRzL0Jhc2V0eXBlcy8ySFN3b3JkMTMiLCJ3IjoyLCJoIjo0LCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/6297c060ee/2HSword13.png", "tags": [], "craftable": {"category": "Two Hand Sword"}, "w": 2, "h": 4}

File diff suppressed because one or more lines are too long

View File

@@ -21,7 +21,7 @@ export default {
QUALITY: '퀄리티: ',
PHYSICAL_DAMAGE: '물리 피해: ',
ELEMENTAL_DAMAGE: '원소 피해: ',
CRIT_CHANCE: '치명타 확률: ',
CRIT_CHANCE: '치명타 명중 확률: ',
ATTACK_SPEED: '초당 공격 횟수: ',
ARMOUR: '방어도: ',
EVASION: '회피: ',

View File

@@ -1844,7 +1844,7 @@
{"name": "쌍둥이 도리깨", "refName": "Twin Flail", "namespace": "ITEM", "icon": "%NOT_FOUND%", "tags": ["maraketh_basetype"], "craftable": {"category": "Flail"}, "w": 2, "h": 3}
{"name": "쌍촉 화살통", "refName": "Two-Point Quiver", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvUXVpdmVycy9CYXNldHlwZXMvUXVpdmVyVHdvUG9pbnQiLCJ3IjoyLCJoIjozLCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/cca38d7cc5/QuiverTwoPoint.png", "tags": [], "craftable": {"category": "Quiver"}, "w": 2, "h": 3}
{"name": "자모토의 흉포함의 영혼 핵", "refName": "Tzamoto's Soul Core of Ferocity", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvU291bENvcmVzL05ld1NvdWxDb3JlUmFnZSIsInNjYWxlIjoxLCJyZWFsbSI6InBvZTIifV0/7bbacc1706/NewSoulCoreRage.png", "tags": ["soul_core", "soul_core_tier3"], "tradeTag": "tzamotos-soul-core-of-ferocity", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Helmet", "string": "격노 최대치 #", "values": [4], "tradeId": null}]}
{"name": "울라만의 응시", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "튕겨내기로 방지하는 피해 #%", "values": [3], "tradeId": null}]}
{"name": "울라만의 응시", "refName": "Ulaman's Gaze", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvQ3VycmVuY3kvQWJ5c3NhbEV5ZVNvY2tldGFibGVzL1VsYW1hbnNHYXplIiwic2NhbGUiOjEsInJlYWxtIjoicG9lMiJ9XQ/b39b0a03bc/UlamansGaze.png", "tags": [], "tradeTag": "ulamans-gaze", "craftable": {"category": "SoulCore"}, "w": 1, "h": 1, "rune": [{"categories": "Body Armour", "string": "튕겨낸 명중의 피해 중 방지하는 피해 #%", "values": [3], "tradeId": null}]}
{"name": "극한의 생명력 플라스크", "refName": "Ultimate Life Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTGlmZTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/8ed5f669f0/FlaskLife09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "극한의 마나 플라스크", "refName": "Ultimate Mana Flask", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzksMTQseyJmIjoiMkRJdGVtcy9GbGFza3MvQmFzZXR5cGVzL0ZsYXNrTWFuYTA5IiwidyI6MSwiaCI6Miwic2NhbGUiOjEsInJlYWxtIjoicG9lMiIsImxldmVsIjoxfV0/ff9d3e75d9/FlaskMana09.png", "tags": [], "craftable": {"category": "Flask"}, "w": 1, "h": 2}
{"name": "초거대 대검", "refName": "Ultra Greatsword", "namespace": "ITEM", "icon": "https://web.poecdn.com/gen/image/WzI1LDE0LHsiZiI6IjJESXRlbXMvV2VhcG9ucy9Ud29IYW5kV2VhcG9ucy9Ud29IYW5kU3dvcmRzL0Jhc2V0eXBlcy8ySFN3b3JkMTMiLCJ3IjoyLCJoIjo0LCJzY2FsZSI6MSwicmVhbG0iOiJwb2UyIn1d/6297c060ee/2HSword13.png", "tags": [], "craftable": {"category": "Two Hand Sword"}, "w": 2, "h": 4}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,6 @@ import type {
BaseType,
DropEntry,
ItemCategoryToEmptyPrefix,
PseudoIdToTradeRequest,
RuneDataByRune,
RuneDataByTradeId,
RuneSingleValue,
@@ -19,7 +18,6 @@ export let ITEM_DROP: DropEntry[];
export let CLIENT_STRINGS: TranslationDict;
export let CLIENT_STRINGS_REF: TranslationDict;
export let APP_PATRONS: Array<{ from: string; months: number; style: number }>;
export let PSEUDO_ID_TO_TRADE_REQUEST: PseudoIdToTradeRequest;
export let RUNE_SINGLE_VALUE: RuneSingleValue;
export let RUNE_DATA_BY_RUNE: RuneDataByRune;
export let RUNE_DATA_BY_TRADE_ID: RuneDataByTradeId;
@@ -259,10 +257,6 @@ export async function init(lang: string, isTest = false) {
await fetch(`${import.meta.env.BASE_URL}data/patrons.json`)
).json();
PSEUDO_ID_TO_TRADE_REQUEST = await (
await fetch(`${import.meta.env.BASE_URL}data/pseudo-pseudo.json`)
).json();
ITEM_CATEGORY_TO_EMPTY_PREFIX = await (
await fetch(`${import.meta.env.BASE_URL}data/pseudo-empty-prefix.json`)
).json();

View File

@@ -243,18 +243,6 @@ export interface Filter {
disabled: boolean;
}
export interface PseudoIdToTradeRequest {
[id: string]: {
filters: Filter[];
type: "weight";
value: {
min?: number;
max?: number;
};
disabled?: boolean;
};
}
export interface ItemCategoryToEmptyPrefix {
[id: string]: {
filters: Filter[];

View File

@@ -467,10 +467,6 @@ function upgradeConfig(_config: Config): Config {
}
if (config.configVersion < 18) {
const priceCheck = config.widgets.find(
(w) => w.wmType === "price-check",
) as widget.PriceCheckWidget;
priceCheck.usePseudo = false;
config.enableAlphas = false;
config.alphas = [];
config.preferredTradeSite = "default";

View File

@@ -1,85 +1,97 @@
import { shallowRef, watch, readonly } from "vue";
import { createGlobalState } from "@vueuse/core";
// import { Host } from "@/web/background/IPC";
import { Host } from "@/web/background/IPC";
import { useLeagues } from "./Leagues";
interface NinjaDenseInfo {
chaos: number;
graph: Array<number | null>;
exalted: number;
graph?: Array<number | null>;
name: string;
variant?: string;
}
type PriceDatabase = Array<{ ns: string; url: string; lines: string }>;
const RETRY_INTERVAL_MS = 4 * 60 * 1000;
// const UPDATE_INTERVAL_MS = 31 * 60 * 1000;
// const INTEREST_SPAN_MS = 20 * 60 * 1000;
const UPDATE_INTERVAL_MS = 31 * 60 * 1000;
const INTEREST_SPAN_MS = 20 * 60 * 1000;
interface DbQuery {
ns: string;
name: string;
variant: string | undefined;
}
export interface CurrencyValue {
min: number;
max: number;
currency: "exalted" | "div";
currency: "chaos" | "exalted" | "div";
}
export const usePoeninja = createGlobalState(() => {
const leagues = useLeagues();
const xchgRate = shallowRef<number | undefined>(undefined);
const xchgRate1 = shallowRef<number | undefined>(undefined);
xchgRate1.value = undefined;
// const xchgRate1 = shallowRef<number | undefined>(undefined);
// xchgRate1.value = undefined;
const isLoading = shallowRef(false);
let PRICES_DB: PriceDatabase = [];
// const lastUpdateTime = 0;
// let downloadController: AbortController | undefined;
// let lastInterestTime = 0;
let lastUpdateTime = 0;
let downloadController: AbortController | undefined;
let lastInterestTime = 0;
async function load(force: boolean = false) {
// const league = leagues.selected.value;
// if (!league || !league.isPopular || league.realm !== "pc-ggg") return;
// if (
// !force &&
// (Date.now() - lastUpdateTime < UPDATE_INTERVAL_MS ||
// Date.now() - lastInterestTime > INTEREST_SPAN_MS)
// )
// return;
// if (downloadController) downloadController.abort();
// try {
// isLoading.value = true;
// downloadController = new AbortController();
// const response = await Host.proxy(
// `poe.ninja/api/data/DenseOverviews?league=${league.id}&language=en`,
// {
// signal: downloadController.signal,
// },
// );
// const jsonBlob = await response.text();
// PRICES_DB = splitJsonBlob(jsonBlob);
// const divine = findPriceByQuery({
// ns: "ITEM",
// name: "Divine Orb",
// variant: undefined,
// });
// if (divine && divine.chaos >= 30) {
// xchgRate.value = divine.chaos;
// }
// lastUpdateTime = Date.now();
// } finally {
// isLoading.value = false;
// }
const league = leagues.selected.value;
if (
!league ||
!league.isPopular ||
league.realm !== "pc-ggg" ||
// FIXME: only have non hc abyssal cached rn
league.id !== "Rise of the Abyssal"
)
return;
if (
!force &&
(Date.now() - lastUpdateTime < UPDATE_INTERVAL_MS ||
Date.now() - lastInterestTime > INTEREST_SPAN_MS)
)
return;
if (downloadController) downloadController.abort();
try {
isLoading.value = true;
downloadController = new AbortController();
const response = await Host.proxy(
`api.exiledexchange2.dev/overviewData.json`,
{
signal: downloadController.signal,
},
);
const jsonBlob = await response.text();
if (!jsonBlob.startsWith('{"ok":true,"data":[{')) {
PRICES_DB = [{ ns: "NAN", url: "NAN", lines: "NAN" }];
console.log("Failed to load prices");
// Set to now for now, determine better retry interval later
lastUpdateTime = Date.now() - 3 * RETRY_INTERVAL_MS;
return;
}
PRICES_DB = splitJsonBlob(jsonBlob);
const divine = findPriceByQuery({
ns: "ITEM",
name: "Divine Orb",
});
if (divine && divine.exalted >= 30) {
xchgRate.value = divine.exalted;
}
lastUpdateTime = Date.now();
} finally {
isLoading.value = false;
}
}
function queuePricesFetch() {
// lastInterestTime = Date.now();
lastInterestTime = Date.now();
load();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function selectedLeagueToUrl(): string {
const league = leagues.selectedId.value!;
switch (league) {
@@ -96,8 +108,7 @@ export const usePoeninja = createGlobalState(() => {
// NOTE: order of keys is important
const searchString = JSON.stringify({
name: query.name,
variant: query.variant,
chaos: 0,
exalted: 0,
}).replace(":0}", ":");
for (const { ns, url, lines } of PRICES_DB) {
@@ -113,7 +124,9 @@ export const usePoeninja = createGlobalState(() => {
return {
...info,
url: `https://poe.ninja/${selectedLeagueToUrl()}/${url}/${denseInfoToDetailsId(info)}`,
// url: `https://poe.ninja/poe2/economy/${selectedLeagueToUrl()}/${url}`,
// TODO: Currently i'm only supporting in league non hc
url: `https://poe.ninja/poe2/economy/abyss/${url}`,
};
}
return null;
@@ -159,8 +172,7 @@ export const usePoeninja = createGlobalState(() => {
});
return {
// xchgRate: readonly(xchgRate),
xchgRate: readonly(xchgRate1),
xchgRate: readonly(xchgRate),
findPriceByQuery,
autoCurrency,
queuePricesFetch,
@@ -168,74 +180,59 @@ export const usePoeninja = createGlobalState(() => {
};
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function denseInfoToDetailsId(info: NinjaDenseInfo): string {
return (info.variant ? `${info.name}, ${info.variant}` : info.name)
return info.name
.normalize("NFKD")
.replace(/[^a-zA-Z0-9:\- ]/g, "")
.toLowerCase()
.replace(/ /g, "-");
}
// function splitJsonBlob(jsonBlob: string): PriceDatabase {
// const NINJA_OVERVIEW = '{"type":"';
// const NAMESPACE_MAP: Array<{ ns: string; url: string; type: string }> = [
// { ns: "ITEM", url: "currency", type: "Currency" },
// { ns: "ITEM", url: "fragments", type: "Fragment" },
// { ns: "ITEM", url: "delirium-orbs", type: "DeliriumOrb" },
// { ns: "ITEM", url: "scarabs", type: "Scarab" },
// { ns: "ITEM", url: "artifacts", type: "Artifact" },
// { ns: "ITEM", url: "base-types", type: "BaseType" },
// { ns: "ITEM", url: "fossils", type: "Fossil" },
// { ns: "ITEM", url: "resonators", type: "Resonator" },
// { ns: "ITEM", url: "incubators", type: "Incubator" },
// { ns: "ITEM", url: "oils", type: "Oil" },
// { ns: "ITEM", url: "vials", type: "Vial" },
// { ns: "ITEM", url: "invitations", type: "Invitation" },
// { ns: "ITEM", url: "blighted-maps", type: "BlightedMap" },
// { ns: "ITEM", url: "blight-ravaged-maps", type: "BlightRavagedMap" },
// { ns: "ITEM", url: "essences", type: "Essence" },
// { ns: "ITEM", url: "maps", type: "Map" },
// { ns: "ITEM", url: "tattoos", type: "Tattoo" },
// { ns: "ITEM", url: "omens", type: "Omen" },
// { ns: "ITEM", url: "coffins", type: "Coffin" },
// { ns: "DIVINATION_CARD", url: "divination-cards", type: "DivinationCard" },
// { ns: "CAPTURED_BEAST", url: "beasts", type: "Beast" },
// { ns: "UNIQUE", url: "unique-jewels", type: "UniqueJewel" },
// { ns: "UNIQUE", url: "unique-flasks", type: "UniqueFlask" },
// { ns: "UNIQUE", url: "unique-weapons", type: "UniqueWeapon" },
// { ns: "UNIQUE", url: "unique-armours", type: "UniqueArmour" },
// { ns: "UNIQUE", url: "unique-accessories", type: "UniqueAccessory" },
// { ns: "UNIQUE", url: "unique-maps", type: "UniqueMap" },
// { ns: "UNIQUE", url: "unique-relics", type: "UniqueRelic" },
// { ns: "GEM", url: "skill-gems", type: "SkillGem" },
// ];
function splitJsonBlob(jsonBlob: string): PriceDatabase {
const NINJA_OVERVIEW = '{"type":"';
const NAMESPACE_MAP: Array<{ ns: string; url: string; type: string }> = [
{ ns: "ITEM", url: "currency", type: "Currency" },
{ ns: "ITEM", url: "fragments", type: "Fragments" },
{ ns: "ITEM", url: "abyssal-bones", type: "Abyss" },
{ ns: "ITEM", url: "uncut-gems", type: "UncutGems" },
{ ns: "ITEM", url: "lineage-support-gems", type: "LineageSupportGems" },
{ ns: "ITEM", url: "essences", type: "Essences" },
{ ns: "ITEM", url: "soul-cores", type: "Ultimatum" },
{ ns: "ITEM", url: "talismans", type: "Talismans" },
{ ns: "ITEM", url: "runes", type: "Runes" },
{ ns: "ITEM", url: "omens", type: "Ritual" },
{ ns: "ITEM", url: "expedition", type: "Expedition" },
{ ns: "ITEM", url: "distilled-emotions", type: "Delirium" },
{ ns: "ITEM", url: "breach-catalyst", type: "Breach" },
];
// const database: PriceDatabase = [];
// let startPos = jsonBlob.indexOf(NINJA_OVERVIEW);
// if (startPos === -1) return [];
const database: PriceDatabase = [];
let startPos = jsonBlob.indexOf(NINJA_OVERVIEW);
if (startPos === -1) return [];
// while (true) {
// const endPos = jsonBlob.indexOf(NINJA_OVERVIEW, startPos + 1);
while (true) {
const endPos = jsonBlob.indexOf(NINJA_OVERVIEW, startPos + 1);
// const type = jsonBlob.slice(
// startPos + NINJA_OVERVIEW.length,
// jsonBlob.indexOf('"', startPos + NINJA_OVERVIEW.length),
// );
// const lines = jsonBlob.slice(
// startPos,
// endPos === -1 ? jsonBlob.length : endPos,
// );
const type = jsonBlob.slice(
startPos + NINJA_OVERVIEW.length,
jsonBlob.indexOf('"', startPos + NINJA_OVERVIEW.length),
);
const lines = jsonBlob.slice(
startPos,
endPos === -1 ? jsonBlob.length : endPos,
);
// const isSupported = NAMESPACE_MAP.find((entry) => entry.type === type);
// if (isSupported) {
// database.push({ ns: isSupported.ns, url: isSupported.url, lines });
// }
const isSupported = NAMESPACE_MAP.find((entry) => entry.type === type);
if (isSupported) {
database.push({ ns: isSupported.ns, url: isSupported.url, lines });
}
// if (endPos === -1) break;
// startPos = endPos;
// }
// return database;
// }
if (endPos === -1) break;
startPos = endPos;
}
return database;
}
export function displayRounding(
value: number,

View File

@@ -1,37 +0,0 @@
<template>
<div class="bg-orange-400 text-gray-900 text-center text-sm font-bold">
{{ t("poe2_new.beta_warning") }}
<br />
{{ t("poe2_new.beta_warning2") }}
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { useI18n } from "vue-i18n";
export default defineComponent({
setup() {
const { t } = useI18n();
const devMode = !!process.env.NODE_ENV;
return {
t,
devMode,
};
},
});
</script>
<style lang="postcss" module>
.dev {
@apply text-black text-center text-sm font-bold;
background: repeating-linear-gradient(
45deg,
#6d31ce,
#6d31ce 8px,
#276749 8px,
#276749 24px
);
}
</style>

View File

@@ -3,8 +3,6 @@
class="bg-gray-800 text-gray-200 border-gray-900 border-4 flex flex-col"
style="min-width: 20rem; max-width: min(100vw - var(--game-panel), 30rem)"
>
<ConversionWarningBanner />
<div class="bg-gray-900 py-1 px-4 text-center">{{ itemName }}</div>
<div class="flex gap-1 py-1 bg-gray-900 items-center">
<button class="btn flex-1" @click="openWiki">wiki</button>
@@ -36,7 +34,6 @@ import { useI18n } from "vue-i18n";
import type { ParsedItem } from "@/parser";
import { itemIsModifiable } from "@/parser";
import * as actions from "./hotkeyable-actions";
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
const props = defineProps<{
item: ParsedItem;

View File

@@ -307,20 +307,20 @@ function selectItem(
price = findPriceByQuery({
ns: item.namespace,
name: `${opts.altQuality} ${item.refName}`,
variant: "1",
// variant: "1",
});
} else {
price = findPriceByQuery({
ns: item.namespace,
name: item.refName,
variant: item.unique!.base,
// variant: item.unique!.base,
});
}
const isAdded = addItem({
info: item,
discr: opts.altQuality,
chaos: price?.chaos,
price: price != null ? autoCurrency(price.chaos) : undefined,
chaos: price?.exalted,
price: price != null ? autoCurrency(price.exalted) : undefined,
});
if (isAdded && opts.withTimeout) {
showTimeout.value?.reset();

View File

@@ -3,8 +3,6 @@
class="bg-gray-800 text-gray-200 border-gray-900 border-4"
style="min-width: 20rem; max-width: min(100vw - var(--game-panel), 30rem)"
>
<ConversionWarningBanner />
<div class="bg-gray-900 py-1 px-8 flex items-baseline gap-2">
<div class="flex-1 text-center">{{ mapName }}</div>
<div class="ml-8 text-gray-400">{{ t("map_check.profile") }}</div>
@@ -57,7 +55,6 @@ import { type MapCheckConfig, isOutdated } from "./common.js";
import MapStatButton from "./MapStatButton.vue";
import FullscreenImage from "@/web/ui/FullscreenImage.vue";
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
const props = defineProps<{
item: ParsedItem;

View File

@@ -7,7 +7,6 @@
v-slot="{ isEditing }"
>
<div class="widget-default-style">
<ConversionWarningBanner />
<div class="p-1 flex gap-1 items-center text-base">
<template v-for="widget in widgets" :key="widget.wmId">
<button
@@ -82,7 +81,6 @@ import { registry } from "./widget-registry";
import { Host } from "@/web/background/IPC";
import Widget from "./Widget.vue";
import { useI18nNs } from "@/web/i18n";
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
export default defineComponent({
widget: {
@@ -105,7 +103,7 @@ export default defineComponent({
};
},
} satisfies WidgetSpec,
components: { Widget, UiToggle, UiPopover, ConversionWarningBanner },
components: { Widget, UiToggle, UiPopover },
props: {
config: {
type: Object as PropType<WidgetMenu>,

View File

@@ -50,7 +50,6 @@ export interface PriceCheckWidget extends Widget {
showCursor: boolean;
requestPricePrediction: boolean;
builtinBrowser: boolean;
usePseudo: boolean;
rememberCurrency: boolean;
defaultAllSelected: boolean;
itemHoverTooltip: "off" | "keybind" | "always";

View File

@@ -10,7 +10,6 @@
:stats="itemStats"
:item="item"
:presets="presets"
:weightFilters="weightFilters"
@preset="selectPreset"
@submit="doSearch = true"
:rebuild-key="rebuildKey"
@@ -21,7 +20,6 @@
:filters="itemFilters"
:stats="itemStats"
:item="item"
:weightFilters="weightFilters"
/>
<trade-bulk
v-if="tradeAPI === 'bulk' && doSearch"
@@ -36,11 +34,6 @@
</button>
</div>
<div class="flex flex-row gap-1">
<trade-links
v-if="tradeAPI === 'trade' && showPseudoLink"
:get-link="makeTradeLinkPseudo"
text="filters.tag_pseudo"
/>
<trade-links v-if="tradeAPI === 'trade'" :get-link="makeTradeLink" />
</div>
</div>
@@ -141,7 +134,6 @@ export default defineComponent({
setup(props, ctx) {
const widget = computed(() => AppConfig<PriceCheckWidget>("price-check")!);
const leagues = useLeagues();
const lang = computed(() => AppConfig().language);
const presets = ref<{ active: string; presets: FilterPreset[] }>(null!);
const itemFilters = computed(
@@ -156,12 +148,6 @@ export default defineComponent({
(preset) => preset.id === presets.value.active,
)!.stats,
);
const weightFilters = computed(
() =>
presets.value.presets.find(
(preset) => preset.id === presets.value.active,
)!.weightFilters,
);
const doSearch = ref(false);
const tradeAPI = ref<"trade" | "bulk">("bulk");
@@ -192,9 +178,6 @@ export default defineComponent({
item.info.refName === prevItem.info.refName)
? prevCurrency
: undefined,
usePseudo:
widget.value.usePseudo &&
["en", "ru", "ko", "cmn-Hant"].includes(lang.value),
defaultAllSelected: widget.value.defaultAllSelected,
autoFillEmptyRuneSockets: widget.value.autoFillEmptyRuneSockets,
});
@@ -374,7 +357,6 @@ export default defineComponent({
t,
itemFilters,
itemStats,
weightFilters,
doSearch,
tradeAPI,
tradeService,
@@ -393,20 +375,9 @@ export default defineComponent({
selectPreset(id: string) {
presets.value.active = id;
},
showPseudoLink: computed(
() =>
weightFilters.value.length &&
!(
widget.value.usePseudo &&
["en", "ru", "ko", "cmn-Hant"].includes(AppConfig().language)
),
),
makeTradeLink() {
return `https://${getTradeEndpoint()}/trade2/search/poe2/${itemFilters.value.trade.league}?q=${JSON.stringify(createTradeRequest(itemFilters.value, itemStats.value, props.item))}`;
},
makeTradeLinkPseudo() {
return `https://${getTradeEndpoint()}/trade2/search/poe2/${itemFilters.value.trade.league}?q=${JSON.stringify(createTradeRequest(itemFilters.value, itemStats.value, props.item, weightFilters.value))}`;
},
};
},
});

View File

@@ -44,7 +44,6 @@
:click-position="clickPosition"
:item-editor-options="itemEditorOptions"
/>
<ConversionWarningBanner />
<AppTitleBar
@close="closePriceCheck"
@click="openLeagueSelection"
@@ -179,7 +178,6 @@ import {
WidgetManager,
WidgetSpec,
} from "../overlay/interfaces";
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
import ItemEditor from "./filters/ItemEditor.vue";
import {
BaseType,
@@ -225,7 +223,6 @@ export default defineComponent({
requestPricePrediction: false,
rememberCurrency: false,
// New Settings EE2
usePseudo: false,
defaultAllSelected: false,
itemHoverTooltip: "keybind",
autoFillEmptyRuneSockets: false,
@@ -246,7 +243,6 @@ export default defineComponent({
ItemQuickPrice,
UiErrorBox,
UiPopover,
ConversionWarningBanner,
},
props: {
config: {
@@ -255,8 +251,11 @@ export default defineComponent({
},
},
setup(props) {
const leagueId = computed(() => AppConfig().leagueId);
watch(
() => props.config.usePseudo,
// FIXME: check if this is working as intended
() => leagueId.value,
() => {
const runeFilter = (item: BaseType) =>
Object.values(item.rune!).some((runeStat) =>

View File

@@ -45,10 +45,9 @@ export default defineComponent({
const price = findPriceByQuery({
ns: "ITEM",
name: oil.refName,
variant: undefined,
});
if (price) {
totalChaos += price.chaos;
totalChaos += price.exalted;
} else {
totalChaos = undefined;
break;

View File

@@ -1,9 +1,7 @@
import { createFilters } from "./create-item-filters";
import {
createExactStatFilters,
createResistanceWeightFilter,
initUiModFilters,
initWeightFilters,
} from "./create-stat-filters";
import { sumStatsByModType } from "@/parser/modifiers";
import { ItemCategory, ItemRarity, ParsedItem } from "@/parser";
@@ -23,7 +21,6 @@ export function createPresets(
activateStockFilter: boolean;
searchStatRange: number;
useEn: boolean;
usePseudo: boolean;
defaultAllSelected: boolean;
autoFillEmptyRuneSockets: PriceCheckWidget["autoFillEmptyRuneSockets"];
},
@@ -35,11 +32,6 @@ export function createPresets(
id: ROMAN_NUMERALS[idx],
filters: createFilters(item, { ...opts, exact: true }),
stats: createExactStatFilters(item, sumStatsByModType(area), opts),
weightFilters: createResistanceWeightFilter(
item,
sumStatsByModType(area),
opts,
),
})),
};
}
@@ -67,11 +59,6 @@ export function createPresets(
id: "filters.preset_exact",
filters: createFilters(item, { ...opts, exact: true }),
stats: createExactStatFilters(item, item.statsByType, opts),
weightFilters: createResistanceWeightFilter(
item,
item.statsByType,
opts,
),
},
],
};
@@ -82,7 +69,6 @@ export function createPresets(
id: "filters.preset_pseudo",
filters: createFilters(item, { ...opts, exact: false }),
stats: initUiModFilters(item, opts),
weightFilters: initWeightFilters(item, opts),
};
// Apply runes if we should
@@ -108,7 +94,6 @@ export function createPresets(
id: "filters.preset_base_item",
filters: createFilters(item, { ...opts, exact: true }),
stats: createExactStatFilters(item, item.statsByType, opts),
weightFilters: createResistanceWeightFilter(item, item.statsByType, opts),
};
return {

View File

@@ -15,17 +15,15 @@ import { percentRoll, percentRollDelta, roundRoll } from "./util";
import {
FilterTag,
ItemHasEmptyModifier,
RESISTANCE_WEIGHT_GROUP,
StatFilter,
StatFilterRoll,
WeightStatGroup,
} from "./interfaces";
import { filterPseudo } from "./pseudo";
import { applyRules as applyAtzoatlRules } from "./pseudo/atzoatl-rules";
import { applyRules as applyMirroredTabletRules } from "./pseudo/reflection-rules";
import { filterItemProp, filterBasePercentile } from "./pseudo/item-property";
import { decodeOils, applyAnointmentRules } from "./pseudo/anointments";
import { StatBetter, CLIENT_STRINGS, STAT_BY_REF } from "@/assets/data";
import { StatBetter, CLIENT_STRINGS } from "@/assets/data";
import { maxUsefulItemLevel } from "./common";
export interface FiltersCreationContext {
@@ -35,88 +33,6 @@ export interface FiltersCreationContext {
statsByType: StatCalculated[];
}
export function initWeightFilters(
item: ParsedItem,
opts: {
searchStatRange: number;
},
): WeightStatGroup[] {
const statsByType = item.statsByType.map((calc) => {
if (
calc.type === ModifierType.Fractured &&
calc.stat.trade.ids[ModifierType.Explicit]
) {
return { ...calc, type: ModifierType.Explicit };
} else {
return calc;
}
});
return createResistanceWeightFilter(item, statsByType, opts);
}
export function createResistanceWeightFilter(
item: ParsedItem,
statsByType: StatCalculated[],
opts: {
searchStatRange: number;
},
): WeightStatGroup[] {
const weightFilter: WeightStatGroup = {
stats: [],
value: {},
disabled: true,
name: RESISTANCE_WEIGHT_GROUP,
};
const searchInRange = Math.min(2, opts.searchStatRange);
const resistanceWeights: any = {
"#% to Lightning Resistance": 1,
"#% to Fire Resistance": 1,
"#% to Cold Resistance": 1,
"#% to all Elemental Resistances": 3,
};
let min = 0;
for (const stat of statsByType) {
if (!resistanceWeights[stat.stat.ref]) continue;
const modWeight = resistanceWeights[stat.stat.ref];
const statValue = stat.sources
.map((source) => source.contributes?.value)
.map((value) => value || 0)
.reduce((acc: number, v: number) => acc + v, 0);
min += statValue * modWeight;
}
if (min === 0) return [];
for (const ref of Object.keys(resistanceWeights)) {
const stat = STAT_BY_REF(ref)!;
const modWeight = resistanceWeights[ref];
const calcStat: StatCalculated = {
stat,
type: ModifierType.Pseudo,
sources: [],
};
const statFilter = calculatedStatToFilter(calcStat, searchInRange, item);
statFilter.disabled = false;
statFilter.weight = modWeight;
statFilter.tradeId = Object.values(stat.trade.ids).flat();
weightFilter.stats.push(statFilter);
}
weightFilter.value.min = percentRoll(
min,
-opts.searchStatRange,
Math.floor,
false,
);
return [weightFilter];
}
export function createExactStatFilters(
item: ParsedItem,
statsByType: StatCalculated[],
@@ -242,7 +158,6 @@ export function initUiModFilters(
item: ParsedItem,
opts: {
searchStatRange: number;
usePseudo: boolean;
defaultAllSelected: boolean;
},
): StatFilter[] {
@@ -265,7 +180,7 @@ export function initUiModFilters(
if (item.info.refName !== "Split Personality") {
filterItemProp(ctx);
filterPseudo(ctx, opts.usePseudo);
filterPseudo(ctx);
if (item.info.refName === "Emperor's Vigilance") {
filterBasePercentile(ctx);
}

View File

@@ -116,11 +116,7 @@ function createNewStatFilter(
recalculateItemProperties(newItem, item);
filterItemProp(ctx);
filterPseudo(
ctx,
AppConfig<PriceCheckWidget>("price-check")!.usePseudo &&
["en", "ru", "ko", "cmn-Hant"].includes(AppConfig().language),
);
filterPseudo(ctx);
if (item.isVeiled) {
ctx.statsByType = ctx.statsByType.filter(
(mod) => mod.type !== ModifierType.Veiled,

View File

@@ -7,7 +7,6 @@ export interface FilterPreset {
id: string;
filters: ItemFilters;
stats: StatFilter[];
weightFilters: WeightStatGroup[];
}
interface SearchFilter {
@@ -128,26 +127,12 @@ export interface StatFilter {
};
hidden?: string;
disabled: boolean; // NOTE: mutable in UI
weight?: number;
additionalInfo?: {
[key: string]: StatFilterRoll;
};
editorAdded?: BaseType;
}
export interface WeightStatGroup {
stats: StatFilter[];
name: string;
value: {
min?: number;
max?: number;
};
disabled: boolean;
}
export const RESISTANCE_WEIGHT_GROUP: string =
"RESISTANCE_WEIGHT_GROUP" as const;
export const INTERNAL_TRADE_IDS = [
"item.base_percentile",
"item.armour",

View File

@@ -3,31 +3,18 @@ import { itemIsModifiable, type ParsedItem } from "@/parser";
import type { StatFilter } from "../interfaces";
const EMOTIONS = [
"Distilled Ire",
"Distilled Guilt",
"Distilled Greed",
"Distilled Paranoia",
"Distilled Envy",
"Distilled Disgust",
"Distilled Despair",
"Distilled Fear",
"Distilled Suffering",
"Distilled Isolation",
"Diluted Liquid Ire",
"Diluted Liquid Guilt",
"Diluted Liquid Greed",
"Liquid Paranoia",
"Liquid Envy",
"Liquid Disgust",
"Liquid Despair",
"Concentrated Liquid Fear",
"Concentrated Liquid Suffering",
"Concentrated Liquid Isolation",
];
// [
// "Diluted Liquid Ire",
// "Diluted Liquid Guilt",
// "Diluted Liquid Greed",
// "Liquid Paranoia",
// "Liquid Envy",
// "Liquid Disgust",
// "Liquid Despair",
// "Concentrated Liquid Fear",
// "Concentrated Liquid Suffering",
// "Concentrated Liquid Isolation",
// ];
export function decodeOils(calc: StatCalculated): string[] | undefined {
if (calc.type !== ModifierType.Enchant) return;
@@ -65,7 +52,8 @@ export function applyAnointmentRules(filters: StatFilter[], item: ParsedItem) {
if (
!(
oils.includes("Concentrated Liquid Isolation") ||
oils.includes("Concentrated Liquid Suffering")
oils.includes("Concentrated Liquid Suffering") ||
oils.includes("Concentrated Liquid Fear")
)
) {
anointment.hidden = "filters.hide_anointment";

View File

@@ -12,16 +12,14 @@ import {
} from "../create-stat-filters";
import type { StatFilter } from "../interfaces";
import { ARMOUR_STATS, WEAPON_STATS } from "./item-property";
import { AppConfig } from "@/web/Config";
import { PriceCheckWidget } from "@/web/overlay/widgets";
import { tryParseTranslation } from "@/parser/stat-translations";
const RESISTANCES_INFO = [
// {
// ref: stat("#% to All Resistances"),
// elements: ["fire", "cold", "lightning"],
// chaos: true,
// },
{
ref: stat("#% to All Resistances"),
elements: ["fire", "cold", "lightning"],
chaos: true,
},
{
ref: stat("#% to all Elemental Resistances"),
elements: ["fire", "cold", "lightning"],
@@ -38,33 +36,33 @@ const RESISTANCES_INFO = [
// ref: stat("#% to Cold and Lightning Resistances"),
// elements: ["cold", "lightning"],
// },
// { ref: stat("#% to Chaos Resistance"), elements: [""], chaos: true },
// {
// ref: stat("#% to Fire and Chaos Resistances"),
// elements: ["fire"],
// chaos: true,
// },
// {
// ref: stat("#% to Cold and Chaos Resistances"),
// elements: ["cold"],
// chaos: true,
// },
// {
// ref: stat("#% to Lightning and Chaos Resistances"),
// elements: ["lightning"],
// chaos: true,
// },
{ ref: stat("#% to Chaos Resistance"), elements: [""], chaos: true },
{
ref: stat("#% to Fire and Chaos Resistances"),
elements: ["fire"],
chaos: true,
},
{
ref: stat("#% to Cold and Chaos Resistances"),
elements: ["cold"],
chaos: true,
},
{
ref: stat("#% to Lightning and Chaos Resistances"),
elements: ["lightning"],
chaos: true,
},
];
// const ATTRIBUTES_INFO = [
// { ref: stat("# to all Attributes"), attributes: ["str", "dex", "int"] },
// { ref: stat("# to Strength"), attributes: ["str"] },
// { ref: stat("# to Dexterity"), attributes: ["dex"] },
// { ref: stat("# to Intelligence"), attributes: ["int"] },
// { ref: stat("# to Strength and Intelligence"), attributes: ["str", "int"] },
// { ref: stat("# to Strength and Dexterity"), attributes: ["str", "dex"] },
// { ref: stat("# to Dexterity and Intelligence"), attributes: ["dex", "int"] },
// ];
const ATTRIBUTES_INFO = [
{ ref: stat("# to all Attributes"), attributes: ["str", "dex", "int"] },
{ ref: stat("# to Strength"), attributes: ["str"] },
{ ref: stat("# to Dexterity"), attributes: ["dex"] },
{ ref: stat("# to Intelligence"), attributes: ["int"] },
{ ref: stat("# to Strength and Intelligence"), attributes: ["str", "int"] },
{ ref: stat("# to Strength and Dexterity"), attributes: ["str", "dex"] },
{ ref: stat("# to Dexterity and Intelligence"), attributes: ["dex", "int"] },
];
interface PseudoRule {
group?: string;
@@ -81,140 +79,140 @@ interface PseudoRule {
const PSEUDO_RULES: PseudoRule[] = [
{
pseudo: stat("+#% total Elemental Resistance"),
pseudo: stat("#% total Elemental Resistance"),
disabled: false,
stats: RESISTANCES_INFO.filter((info) => info.elements.length).map(
(info) => ({ ref: info.ref, multiplier: info.elements.length }),
),
},
{
pseudo: stat("+#% total to Fire Resistance"),
pseudo: stat("#% total to Fire Resistance"),
group: "to_x_ele_res",
stats: RESISTANCES_INFO.filter((info) =>
info.elements.includes("fire"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("+#% total to Cold Resistance"),
pseudo: stat("#% total to Cold Resistance"),
group: "to_x_ele_res",
stats: RESISTANCES_INFO.filter((info) =>
info.elements.includes("cold"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("+#% total to Lightning Resistance"),
pseudo: stat("#% total to Lightning Resistance"),
group: "to_x_ele_res",
stats: RESISTANCES_INFO.filter((info) =>
info.elements.includes("lightning"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("#% total to Chaos Resistance"),
stats: RESISTANCES_INFO.filter((info) => info.chaos === true).map(
(info) => ({ ref: info.ref }),
),
mutate(filter) {
if (
filter.sources.length === 1 &&
filter.sources[0].modifier.info.type === ModifierType.Crafted
) {
filter.hidden = "filters.hide_crafted_chaos";
} else {
filter.disabled = false;
}
},
},
{
pseudo: stat("+# total to all Attributes"),
group: "to_all_attrs",
stats: [
{ ref: stat("# to all Attributes") },
// NOTE: not including other sources from `ATTRIBUTES_INFO`
],
},
{
pseudo: stat("+# total to Strength"),
group: "to_x_attr",
stats: ATTRIBUTES_INFO.filter((info) =>
info.attributes.includes("str"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("+# total to Dexterity"),
group: "to_x_attr",
stats: ATTRIBUTES_INFO.filter((info) =>
info.attributes.includes("dex"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("+# total to Intelligence"),
group: "to_x_attr",
stats: ATTRIBUTES_INFO.filter((info) =>
info.attributes.includes("int"),
).map((info) => ({ ref: info.ref })),
},
{
pseudo: stat("+# total maximum Life"),
disabled: false,
stats: [
{ ref: stat("# to maximum Life"), required: true },
...ATTRIBUTES_INFO.filter((info) => info.attributes.includes("str")).map(
(info) => ({ ref: info.ref, multiplier: 5 / 10 }),
),
],
},
{
pseudo: stat("+# total maximum Mana"),
stats: [
{ ref: stat("# to maximum Mana"), required: true },
...ATTRIBUTES_INFO.filter((info) => info.attributes.includes("int")).map(
(info) => ({ ref: info.ref, multiplier: 5 / 10 }),
),
],
},
// {
// pseudo: stat("+#% total to Chaos Resistance"),
// stats: RESISTANCES_INFO.filter((info) => info.chaos === true).map(
// (info) => ({ ref: info.ref }),
// ),
// mutate(filter) {
// if (
// filter.sources.length === 1 &&
// filter.sources[0].modifier.info.type === ModifierType.Crafted
// ) {
// filter.hidden = "filters.hide_crafted_chaos";
// } else {
// filter.disabled = false;
// }
// },
// },
// {
// pseudo: stat("+# total to all Attributes"),
// group: "to_all_attrs",
// stats: [
// { ref: stat("# to all Attributes") },
// // NOTE: not including other sources from `ATTRIBUTES_INFO`
// ],
// },
// {
// pseudo: stat("+# total to Strength"),
// group: "to_x_attr",
// stats: ATTRIBUTES_INFO.filter((info) =>
// info.attributes.includes("str"),
// ).map((info) => ({ ref: info.ref })),
// },
// {
// pseudo: stat("+# total to Dexterity"),
// group: "to_x_attr",
// stats: ATTRIBUTES_INFO.filter((info) =>
// info.attributes.includes("dex"),
// ).map((info) => ({ ref: info.ref })),
// },
// {
// pseudo: stat("+# total to Intelligence"),
// group: "to_x_attr",
// stats: ATTRIBUTES_INFO.filter((info) =>
// info.attributes.includes("int"),
// ).map((info) => ({ ref: info.ref })),
// },
// {
// pseudo: stat("+# total maximum Life"),
// disabled: false,
// stats: [
// { ref: stat("# to maximum Life"), required: true },
// ...ATTRIBUTES_INFO.filter((info) => info.attributes.includes("str")).map(
// (info) => ({ ref: info.ref, multiplier: 5 / 10 }),
// ),
// ],
// },
// {
// pseudo: stat("+# total maximum Mana"),
// stats: [
// { ref: stat("# to maximum Mana"), required: true },
// ...ATTRIBUTES_INFO.filter((info) => info.attributes.includes("int")).map(
// (info) => ({ ref: info.ref, multiplier: 5 / 10 }),
// ),
// ],
// },
// {
// pseudo: stat("+# total maximum Spirit"),
// pseudo: stat("# total maximum Spirit"),
// stats: [{ ref: stat("# to Spirit") }],
// },
{
pseudo: stat("#% total increased maximum Energy Shield"),
stats: [{ ref: stat("#% increased maximum Energy Shield") }],
},
{
pseudo: stat("+# total maximum Energy Shield"),
stats: [
{ ref: stat("# to maximum Energy Shield") }, // global
],
},
// {
// pseudo: stat("#% total increased maximum Energy Shield"),
// stats: [{ ref: stat("#% increased maximum Energy Shield") }],
// },
// {
// pseudo: stat("+# total maximum Energy Shield"),
// stats: [
// { ref: stat("# to maximum Energy Shield") }, // global
// ],
// },
// {
// pseudo: stat("+#% total Attack Speed"),
// pseudo: stat("#% total Attack Speed"),
// stats: [
// { ref: stat("#% increased Attack Speed") }, // global
// // { ref: stat('#% increased Attack and Cast Speed') }
// ],
// },
// {
// pseudo: stat("+#% total Cast Speed"),
// pseudo: stat("#% total Cast Speed"),
// stats: [
// { ref: stat("#% increased Cast Speed") },
// // { ref: stat('#% increased Attack and Cast Speed') }
// ],
// },
// {
// pseudo: stat("#% increased Movement Speed"),
// stats: [{ ref: stat("#% increased Movement Speed") }],
// },
{
pseudo: stat("#% increased Movement Speed"),
stats: [{ ref: stat("#% increased Movement Speed") }],
},
// {
// pseudo: stat("#% total increased Physical Damage"),
// stats: [{ ref: stat("#% increased Global Physical Damage") }],
// },
// {
// pseudo: stat("+#% Global Critical Hit Chance"),
// pseudo: stat("#% Global Critical Hit Chance"),
// group: "global_crit_chance",
// stats: [{ ref: stat("#% increased Global Critical Hit Chance") }],
// },
// {
// pseudo: stat("+#% total Critical Hit Chance for Spells"),
// pseudo: stat("#% total Critical Hit Chance for Spells"),
// replaces: "global_crit_chance",
// stats: [
// {
@@ -225,8 +223,8 @@ const PSEUDO_RULES: PseudoRule[] = [
// ],
// },
// {
// pseudo: stat("+#% Global Critical Hit Multiplier"),
// stats: [{ ref: stat("+#% to Global Critical Hit Multiplier") }],
// pseudo: stat("#% Global Critical Hit Multiplier"),
// stats: [{ ref: stat("#% to Global Critical Hit Multiplier") }],
// },
// {
// pseudo: stat("#% increased Elemental Damage"),
@@ -329,17 +327,9 @@ const PSEUDO_RULES: PseudoRule[] = [
// },
];
export function filterInPseudo(filter: StatFilter) {
return PSEUDO_RULES.some((rule) =>
rule.stats.some((stat) => stat.ref === filter.statRef),
);
}
export function filterPseudo(ctx: FiltersCreationContext, usePseudo: boolean) {
export function filterPseudo(ctx: FiltersCreationContext) {
const filterByGroup = new Map<string, StatFilter[]>();
if (!usePseudo) return;
rulesLoop: for (const rule of PSEUDO_RULES) {
const sources = filterPseudoSources(ctx.statsByType, ({ stat }, source) => {
const info = rule.stats.find((info) => info.ref === stat.ref);
@@ -486,8 +476,7 @@ const PSEUDO_REF_SET = new Set([
export function refEffectsPseudos(ref: string): boolean {
// If it is in these pseudos
return (
(AppConfig<PriceCheckWidget>("price-check")!.usePseudo &&
PSEUDO_REF_SET.has(ref)) ||
PSEUDO_REF_SET.has(ref) ||
ARMOUR_STATS.has(ref) ||
WEAPON_STATS.has(ref) ||
ref === "Adds # to # Chaos Damage"

View File

@@ -60,14 +60,14 @@ export async function requestPoeprices(
const xchgExalted = findPriceByQuery({
ns: "ITEM",
name: "Exalted Orb",
variant: undefined,
// variant: undefined,
});
if (!xchgExalted) {
throw new Error("poeprices.info gave the price in Exalted Orbs.");
}
const converted = autoCurrency([
data.min * xchgExalted.chaos,
data.max * xchgExalted.chaos,
data.min * xchgExalted.exalted,
data.max * xchgExalted.exalted,
]);
data.min = converted.min;
data.max = converted.max;

View File

@@ -78,10 +78,10 @@ function findItemByQueryId(queryId: string): BaseType | undefined {
function findPriceByQueryId(queryId: string) {
const [ns, encodedName] = queryId.split("::");
const [name, variant] = encodedName.split(" // ");
const priceEntry = findPriceByQuery({ ns, name, variant });
// const [name, variant] = encodedName.split(" // ");
const priceEntry = findPriceByQuery({ ns, name: encodedName });
if (priceEntry) {
return autoCurrency(priceEntry.chaos);
return autoCurrency(priceEntry.exalted);
}
}

View File

@@ -114,10 +114,6 @@
t(":open_editor_above")
}}</ui-checkbox>
<ui-checkbox class="mb-4" v-model="usePseudo">{{
t(":use_pseudo")
}}</ui-checkbox>
<div class="mb-2">
<div class="flex-1 mb-1">{{ t(":use_tooltip_hover") }}</div>
<div class="mb-1 flex">
@@ -239,7 +235,6 @@ export default defineComponent({
() => configWidget.value,
"builtinBrowser",
),
usePseudo: configModelValue(() => configWidget.value, "usePseudo"),
requestPricePrediction: configModelValue(
() => configWidget.value,
"requestPricePrediction",

View File

@@ -1,8 +1,5 @@
<template>
<div
v-if="show"
class="p-2 border-dashed border border-gray-600 rounded mt-2"
>
<div v-if="show" class="p-2 border-2 border-gray-600 rounded mt-2">
<div class="flex text-gray-400 leading-none">
<div class="w-1/2">
{{ t("trade_result.you_have") }} <span class="font-sans">×</span>
@@ -48,11 +45,11 @@ export default defineComponent({
const price =
props.item.info.refName === "Divine Orb"
? {
min: n * one.chaos,
max: n * one.chaos,
min: n * one.exalted,
max: n * one.exalted,
currency: "chaos" as const,
}
: autoCurrency(n * one.chaos);
: autoCurrency(n * one.exalted);
return `${displayRounding(price.min)} ${price.currency}`;
}

View File

@@ -217,7 +217,7 @@ export default defineComponent({
);
const selectedResults = computed(() => {
const arr = Array(20);
const arr = Array(8);
if (!slowdown.isReady.value || !result.value) return arr;
const listed = result.value[selectedCurr.value].listedLazy.value;

View File

@@ -13,12 +13,6 @@
:currency-ratio="true"
/>
<div class="flex-1"></div>
<trade-links
v-if="list && showPseudoLink"
:get-link="makeTradeLinkPseudo"
text="filters.tag_pseudo"
class="mr-1"
/>
<trade-links v-if="list" :get-link="makeTradeLink" />
</div>
@@ -121,11 +115,7 @@ import { createTradeRequest } from "./pathofexile-trade";
import { getTradeEndpoint } from "./common";
import { AppConfig } from "@/web/Config";
import { PriceCheckWidget } from "@/web/overlay/interfaces";
import {
ItemFilters,
StatFilter,
WeightStatGroup,
} from "../filters/interfaces";
import { ItemFilters, StatFilter } from "../filters/interfaces";
import { ItemCategory, ParsedItem } from "@/parser";
import { artificialSlowdown } from "./artificial-slowdown";
import OnlineFilter from "./OnlineFilter.vue";
@@ -152,10 +142,6 @@ export default defineComponent({
type: Object as PropType<ParsedItem>,
required: true,
},
weightFilters: {
type: Array as PropType<WeightStatGroup[]>,
required: true,
},
},
setup(props) {
const widget = computed(() => AppConfig<PriceCheckWidget>("price-check")!);
@@ -179,10 +165,6 @@ export default defineComponent({
: `https://${getTradeEndpoint()}/trade2/search/poe2/${props.filters.trade.league}?q=${JSON.stringify(createTradeRequest(props.filters, props.stats, props.item))}`;
}
function makeTradeLinkPseudo() {
return `https://${getTradeEndpoint()}/trade2/search/poe2/${props.filters.trade.league}?q=${JSON.stringify(createTradeRequest(props.filters, props.stats, props.item, props.weightFilters))}`;
}
// Shift Key Detection
const isShiftPressed = ref(false);
@@ -237,18 +219,9 @@ export default defineComponent({
}),
showSeller: computed(() => widget.value.showSeller),
makeTradeLink,
makeTradeLinkPseudo,
openTradeLink() {
showBrowser(makeTradeLink());
},
showPseudoLink: computed(
() =>
props.weightFilters.length &&
!(
widget.value.usePseudo &&
["en", "ru", "ko", "cmn-Hant"].includes(AppConfig().language)
),
),
// Shift key state and methods
isShiftPressed,
ItemCategory,

View File

@@ -163,7 +163,7 @@ export function createTradeRequest(
};
}
const SHOW_RESULTS = 20;
const SHOW_RESULTS = 8;
const API_FETCH_LIMIT = 100;
export async function execBulkSearch(

View File

@@ -4,7 +4,6 @@ import {
StatFilter,
INTERNAL_TRADE_IDS,
InternalTradeId,
WeightStatGroup,
ItemIsElementalModifier,
} from "../filters/interfaces";
import { setProperty as propSet } from "dot-prop";
@@ -18,11 +17,10 @@ import {
RATE_LIMIT_RULES,
preventQueueCreation,
} from "./common";
import { PSEUDO_ID_TO_TRADE_REQUEST, STAT_BY_REF } from "@/assets/data";
import { STAT_BY_REF } from "@/assets/data";
import { RateLimiter } from "./RateLimiter";
import { ModifierType } from "@/parser/modifiers";
import { Cache } from "./Cache";
import { filterInPseudo } from "../filters/pseudo";
import { parseAffixStrings } from "@/parser/Parser";
export const CATEGORY_TO_TRADE_ID = new Map([
@@ -121,7 +119,7 @@ interface TradeRequest {
name?: string | { discriminator: string; option: string };
type?: string | { discriminator: string; option: string };
stats: Array<{
type: "and" | "if" | "count" | "not" | "weight";
type: "and" | "if" | "count" | "not";
value?: FilterRange;
filters: Array<{
id: string;
@@ -129,7 +127,6 @@ interface TradeRequest {
min?: number;
max?: number;
option?: number | string;
weight?: number;
};
disabled?: boolean;
}>;
@@ -310,7 +307,6 @@ export function createTradeRequest(
filters: ItemFilters,
stats: StatFilter[],
item: ParsedItem,
weightGroups?: WeightStatGroup[],
) {
const body: TradeRequest = {
query: {
@@ -462,6 +458,14 @@ export function createTradeRequest(
);
}
if (filters.areaLevel && !filters.areaLevel.disabled) {
propSet(
query.filters,
"misc_filters.filters.area_level.min",
filters.areaLevel.value,
);
}
if (filters.unidentified && !filters.unidentified.disabled) {
propSet(
query.filters,
@@ -786,11 +790,6 @@ export function createTradeRequest(
const qAnd = query.stats[0];
for (const stat of stats) {
let overrideDisabled = false;
if (weightGroups && filterInPseudo(stat)) {
overrideDisabled = true;
}
if (stat.statRef === "Only affects Passives in # Ring") {
const metaSource = stat.roll!;
const metamorphosisCount = metaSource.bounds!.max;
@@ -811,54 +810,21 @@ export function createTradeRequest(
continue;
}
if (stat.tradeId[0].startsWith("pseudo.")) {
query.stats.push(pseudoPseudoToQuery(stat.tradeId[0], stat));
} else if (stat.tradeId.length === 1) {
qAnd.filters.push(
tradeIdToQuery(stat.tradeId[0], stat, overrideDisabled),
);
if (stat.tradeId.length === 1) {
qAnd.filters.push(tradeIdToQuery(stat.tradeId[0], stat));
} else {
query.stats.push({
type: "count",
value: { min: 1 },
disabled: stat.disabled || overrideDisabled,
disabled: stat.disabled,
filters: stat.tradeId.map((id) => tradeIdToQuery(id, stat)),
});
}
}
if (weightGroups) {
for (const weightGroup of weightGroups) {
query.stats.push({
type: "weight",
value: weightGroup.value,
disabled: false,
filters: weightStatsToFilters(weightGroup.stats),
});
}
}
return body;
}
function weightStatsToFilters(weightStats: StatFilter[]) {
const filters: any[] = [];
for (const stat of weightStats) {
for (const tradeId of stat.tradeId) {
filters.push({
disabled: false,
id: tradeId,
value: {
weight: stat.weight,
},
});
}
}
return filters;
}
const cache = new Cache();
export async function requestTradeResultList(
@@ -1054,11 +1020,7 @@ function getMinMax(roll: StatFilter["roll"]) {
return !roll.tradeInvert ? { min: a, max: b } : { min: b, max: a };
}
function tradeIdToQuery(
id: string,
stat: StatFilter,
overrideDisabled: boolean = false,
) {
function tradeIdToQuery(id: string, stat: StatFilter) {
// NOTE: if there will be too many overrides in the future,
// consider moving them to stats.ndjson
@@ -1095,7 +1057,7 @@ function tradeIdToQuery(
...getMinMax(roll),
// option: stat.option != null ? stat.option.value : undefined,
},
disabled: stat.disabled || overrideDisabled,
disabled: stat.disabled,
};
}
@@ -1109,10 +1071,3 @@ function nameToQuery(name: string, filters: ItemFilters) {
};
}
}
function pseudoPseudoToQuery(id: string, stat: StatFilter) {
const filter = PSEUDO_ID_TO_TRADE_REQUEST[id];
filter.value = { ...getMinMax(stat.roll) };
filter.disabled = stat.disabled;
return filter;
}

View File

@@ -144,12 +144,16 @@ export default defineComponent({
const price =
props.item.info.refName === "Divine Orb"
? { min: trend.chaos, max: trend.chaos, currency: "exalted" as const }
: autoCurrency(trend.chaos);
? {
min: trend.exalted,
max: trend.exalted,
currency: "exalted" as const,
}
: autoCurrency(trend.exalted);
return {
price,
change: deltaFromGraph(trend.graph),
change: trend.graph ? deltaFromGraph(trend.graph) : undefined,
url: trend.url,
};
});

View File

@@ -37,7 +37,6 @@
class="grow layout-column"
:onMouseenter="hidePodium"
>
<ConversionWarningBanner />
<AppTitleBar @close="cancel" :title="t('settings.title')" />
<div class="flex grow min-h-0">
<div
@@ -141,7 +140,6 @@ import SettingsMaps from "../map-check/settings-maps.vue";
import SettingsStashSearch from "../stash-search/stash-search-editor.vue";
import SettingsStopwatch from "../stopwatch/settings-stopwatch.vue";
import SettingsItemSearch from "../item-search/settings-item-search.vue";
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
function shuffle<T>(array: T[]): T[] {
let currentIndex = array.length;
@@ -178,7 +176,7 @@ export default defineComponent({
};
},
} satisfies WidgetSpec,
components: { AppTitleBar, ConversionWarningBanner },
components: { AppTitleBar },
props: {
config: {
type: Object as PropType<Widget>,

View File

@@ -31,10 +31,15 @@
v-if="!currencyText"
>
<img
v-if="isValuable"
v-if="price?.currency === 'div'"
src="/images/divine.png"
class="max-w-full max-h-full"
/>
<img
v-else-if="price?.currency === 'chaos'"
src="/images/chaos.png"
class="max-w-full max-h-full"
/>
<img v-else src="/images/exa.png" class="max-w-full max-h-full" />
</div>
</div>
@@ -51,7 +56,7 @@ export default defineComponent({
type: Object as PropType<{
min: number;
max: number;
currency: "div" | "exalted";
currency: "chaos" | "div" | "exalted";
}>,
default: undefined,
},