change items db format

This commit is contained in:
Alexander Drozdov
2021-11-26 00:49:43 +02:00
parent d6ac567942
commit 59cbd87ce6
32 changed files with 262 additions and 24897 deletions
+1
View File
@@ -24,6 +24,7 @@
"main": "background.js",
"dependencies": {
"@fortawesome/fontawesome-free": "5.15.x",
"@sindresorhus/fnv1a": "^3.0.0",
"animate.css": "^4.1.1",
"apexcharts": "^3.23.1",
"dot-prop": "6.x.x",
File diff suppressed because it is too large Load Diff
-1
View File
@@ -37,7 +37,6 @@ const dict = { /* eslint-disable quote-props */
'INFLUENCE_WARLORD': 'Warlord Item',
'SECTION_SYNTHESISED': 'Synthesised Item',
'ITEM_SYNTHESISED': /^Synthesised (.*)$/,
'VAAL_GEM': /^Vaal .*$/,
'VEILED_PREFIX': 'Veiled Prefix',
'VEILED_SUFFIX': 'Veiled Suffix',
'FLASK_CHARGES': /^Currently has \d+ Charges$/,
File diff suppressed because it is too large Load Diff
+46 -11
View File
@@ -29,25 +29,60 @@ export interface Stat {
}
}
export interface BaseType {
category: ItemCategory
icon?: string
}
export interface DropEntry {
query: string[]
items: string[]
}
export interface UniqueItem {
name: string
basetype: string
icon: string
}
export interface BlightRecipes {
oils: string[]
recipes: {
[statValue: number]: number[]
}
}
export interface BaseType {
name: string
refName: string
namespace: (
'DIVINATION_CARD' |
'CAPTURED_BEAST' |
'PROPHECY' |
'UNIQUE' |
'ITEM' |
'GEM'
)
icon: string
tradeTag?: string
tradeDisc?: string
disc?: {
propAR?: true
propEV?: true
propES?: true
hasImplicit?: { ref: string }
hasExplicit?: { ref: string, roll?: number }
sectionText?: string
mapTier?: 'W' | 'Y' | 'R'
}
// extra info
craftable?: {
category: ItemCategory
corrupted?: true
uniqueOnly?: true
}
unique?: {
base: string
}
map?: {
normalVariant?: string
}
prophecy?: {
masterName?: string
}
gem?: {
vaal?: true
awakened?: true
altQuality?: string
normalVariant?: string
}
}
-1
View File
@@ -39,7 +39,6 @@ const dict: TranslationDict = { /* eslint-disable quote-props */
'INFLUENCE_WARLORD': 'Предмет Вождя',
'SECTION_SYNTHESISED': 'Синтезированный предмет',
'ITEM_SYNTHESISED': /^(?:Синтезированный|Синтезированная|Синтезированное|Синтезированные) (.*?)\u00a0*$/,
'VAAL_GEM': /^.* ваал$/,
'VEILED_PREFIX': 'Завуалированный префикс',
'VEILED_SUFFIX': 'Завуалированный суффикс',
'FLASK_CHARGES': /^Содержит зарядов: \d+$/,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -1,6 +1,7 @@
import type { ModifierType, StatCalculated } from './modifiers'
import type { ItemCategory } from './meta'
import type { ParsedModifier } from './advanced-mod-desc'
import type { BaseType } from '@/assets/data'
export enum ItemRarity {
Normal = 'Normal',
@@ -20,8 +21,6 @@ export enum ItemInfluence {
export interface ParsedItem {
rarity?: ItemRarity
name: string
baseType: string | undefined
itemLevel?: number
armourAR?: number
armourEV?: number
+80 -41
View File
@@ -1,8 +1,9 @@
import {
BASE_TYPES,
CLIENT_STRINGS as _$,
ITEM_NAME_REF_BY_TRANSLATED,
STAT_BY_MATCH_STR
ITEM_BY_TRANSLATED,
ITEM_BY_REF,
STAT_BY_MATCH_STR,
BaseType
} from '@/assets/data'
import { ModifierType, sumStatsByModType } from './modifiers'
import { linesToStatStrings, tryParseTranslation, getRollOrMinmaxAvg } from './stat-translations'
@@ -20,8 +21,13 @@ type SectionParseResult =
typeof SECTION_SKIPPED |
typeof PARSER_SKIPPED
type ParserFn = (section: string[], item: ParsedItem) => SectionParseResult
type VirtualParserFn = (item: ParsedItem) => void
type ParserFn = (section: string[], item: ParserState) => SectionParseResult
type VirtualParserFn = (item: ParserState) => void
export interface ParserState extends ParsedItem {
name: string
baseType: string | undefined
}
const parsers: Array<ParserFn | { virtual: VirtualParserFn }> = [
parseUnidentified,
@@ -29,10 +35,12 @@ const parsers: Array<ParserFn | { virtual: VirtualParserFn }> = [
parseSynthesised,
parseCategoryByHelpText,
{ virtual: normalizeName },
{ virtual: parseGemAltQuality },
parseVaalGemName,
{ virtual: findInDatabase },
// -----------
parseItemLevel,
parseTalismanTier,
parseVaalGem,
parseGem,
parseArmour,
parseWeapon,
@@ -93,7 +101,13 @@ export function parseClipboard (clipboard: string) {
}
for (const section of sections) {
const result = parser(section, parsed)
let result: SectionParseResult
try {
result = parser(section, parsed)
} catch (e) {
console.error(e)
return null
}
if (result === SECTION_PARSED) {
sections = sections.filter(s => s !== section)
break
@@ -106,7 +120,7 @@ export function parseClipboard (clipboard: string) {
return Object.freeze(parsed)
}
function normalizeName (item: ParsedItem) {
function normalizeName (item: ParserState) {
if (item.rarity === ItemRarity.Magic) {
const baseType = magicBasetype(item.name)
if (baseType) {
@@ -145,16 +159,39 @@ function normalizeName (item: ParsedItem) {
item.name = 'Metamorph Liver'
}
}
}
item.name = ITEM_NAME_REF_BY_TRANSLATED.get(item.name) || item.name
if (item.baseType) {
item.baseType = ITEM_NAME_REF_BY_TRANSLATED.get(item.baseType) || item.baseType
function findInDatabase (item: ParserState) {
let info: BaseType[] | undefined
if (item.category === ItemCategory.Prophecy) {
info = ITEM_BY_TRANSLATED('PROPHECY', item.name)
} else if (item.category === ItemCategory.DivinationCard) {
info = ITEM_BY_TRANSLATED('DIVINATION_CARD', item.name)
} else if (item.category === ItemCategory.CapturedBeast) {
info = ITEM_BY_TRANSLATED('CAPTURED_BEAST', item.baseType ?? item.name)
} else if (item.category === ItemCategory.Gem) {
info = ITEM_BY_TRANSLATED('GEM', item.name)
} else if (item.category === ItemCategory.MetamorphSample) {
info = ITEM_BY_REF('ITEM', item.name)
} else if (item.rarity === ItemRarity.Unique && !item.isUnidentified) {
info = ITEM_BY_TRANSLATED('UNIQUE', item.name)
} else {
info = ITEM_BY_TRANSLATED('ITEM', item.baseType ?? item.name)
}
if (!info?.length) {
throw new Error('Unsupported item')
}
item.infoVariants = info
// choose 1st variant, correct one will be picked at the end of parsing
item.info = info[0]
// same for every variant
if (!item.category) {
const baseType = BASE_TYPES.get(item.baseType || item.name)
item.category = baseType?.category
item.icon = baseType?.icon
if (item.info.craftable) {
item.category = item.info.craftable.category
} else if (item.info.unique) {
item.category = ITEM_BY_REF('ITEM',
item.info.unique.base)![0].craftable!.category
}
}
}
@@ -186,7 +223,7 @@ function parseNamePlate (section: string[]) {
return null
}
const item: ParsedItem = {
const item: ParserState = {
rarity: undefined,
category: undefined,
name: markupConditionParser(section[2]),
@@ -198,6 +235,8 @@ function parseNamePlate (section: string[]) {
unknownModifiers: [],
influences: [],
extra: {},
info: undefined!,
infoVariants: undefined!,
rawText: undefined!
}
@@ -297,7 +336,7 @@ function parseTalismanTier (section: string[], item: ParsedItem) {
return SECTION_SKIPPED
}
function parseVaalGem (section: string[], item: ParsedItem) {
function parseVaalGemName (section: string[], item: ParserState) {
if (item.category !== ItemCategory.Gem) return PARSER_SKIPPED
if (section.length === 1) {
@@ -308,13 +347,12 @@ function parseVaalGem (section: string[], item: ParsedItem) {
item.gemAltQuality = 'Divergent'
} else if ((gemName = _$.QUALITY_PHANTASMAL.exec(section[0])?.[1])) {
item.gemAltQuality = 'Phantasmal'
} else if (_$.VAAL_GEM.test(section[0])) {
} else if (ITEM_BY_TRANSLATED('GEM', section[0])) {
gemName = section[0]
item.gemAltQuality = 'Superior'
}
if (gemName) {
item.name = ITEM_NAME_REF_BY_TRANSLATED.get(gemName) || gemName
item.name = gemName
return SECTION_PARSED
}
}
@@ -331,28 +369,29 @@ function parseGem (section: string[], item: ParsedItem) {
parseQualityNested(section, item)
// don't override if parsed in Vaal name section
if (!item.gemAltQuality) {
let gemName: string | undefined
if ((gemName = _$.QUALITY_ANOMALOUS.exec(item.name)?.[1])) {
item.gemAltQuality = 'Anomalous'
} else if ((gemName = _$.QUALITY_DIVERGENT.exec(item.name)?.[1])) {
item.gemAltQuality = 'Divergent'
} else if ((gemName = _$.QUALITY_PHANTASMAL.exec(item.name)?.[1])) {
item.gemAltQuality = 'Phantasmal'
} else {
item.gemAltQuality = 'Superior'
}
if (gemName) {
item.name = ITEM_NAME_REF_BY_TRANSLATED.get(gemName) || gemName
}
}
return SECTION_PARSED
}
return SECTION_SKIPPED
}
function parseGemAltQuality (item: ParserState) {
if (item.category !== ItemCategory.Gem) return
let gemName: string | undefined
if ((gemName = _$.QUALITY_ANOMALOUS.exec(item.name)?.[1])) {
item.gemAltQuality = 'Anomalous'
} else if ((gemName = _$.QUALITY_DIVERGENT.exec(item.name)?.[1])) {
item.gemAltQuality = 'Divergent'
} else if ((gemName = _$.QUALITY_PHANTASMAL.exec(item.name)?.[1])) {
item.gemAltQuality = 'Phantasmal'
} else {
item.gemAltQuality = 'Superior'
}
if (gemName) {
item.name = gemName
}
}
function parseStackSize (section: string[], item: ParsedItem) {
if (item.rarity !== ItemRarity.Normal &&
item.category !== ItemCategory.Currency &&
@@ -554,7 +593,7 @@ function parseFlask (section: string[], item: ParsedItem) {
return SECTION_SKIPPED
}
function parseSynthesised (section: string[], item: ParsedItem) {
function parseSynthesised (section: string[], item: ParserState) {
if (section.length === 1) {
if (section[0] === _$.SECTION_SYNTHESISED) {
item.isSynthesised = true
@@ -570,7 +609,7 @@ function parseSynthesised (section: string[], item: ParsedItem) {
return SECTION_SKIPPED
}
function parseSuperior (item: ParsedItem) {
function parseSuperior (item: ParserState) {
if (
(item.rarity === ItemRarity.Normal) ||
(item.rarity === ItemRarity.Magic && item.isUnidentified) ||
@@ -662,7 +701,7 @@ function parseAreaLevelNested (section: string[], item: ParsedItem) {
}
function parseAtzoatlAreaLevel (section: string[], item: ParsedItem) {
if (item.name !== 'Chronicle of Atzoatl') return PARSER_SKIPPED
if (item.info.refName !== 'Chronicle of Atzoatl') return PARSER_SKIPPED
parseAreaLevelNested(section, item)
@@ -672,7 +711,7 @@ function parseAtzoatlAreaLevel (section: string[], item: ParsedItem) {
}
function parseAtzoatlRooms (section: string[], item: ParsedItem) {
if (item.name !== 'Chronicle of Atzoatl') return PARSER_SKIPPED
if (item.info.refName !== 'Chronicle of Atzoatl') return PARSER_SKIPPED
if (section[0] !== _$.INCURSION_OPEN) return SECTION_SKIPPED
let state = IncursionRoom.Open
+5 -12
View File
@@ -1,16 +1,6 @@
import { BASE_TYPES, TRANSLATED_ITEM_NAME_BY_REF } from '@/assets/data'
let baseTypes: Set<string>
import { ITEM_BY_TRANSLATED } from '@/assets/data'
export function magicBasetype (name: string) {
if (!baseTypes) {
baseTypes = new Set<string>()
for (let name of BASE_TYPES.keys()) {
name = TRANSLATED_ITEM_NAME_BY_REF.get(name)!
baseTypes.add(name)
}
}
const words = name.split(' ')
const perm: string[] = words.flatMap((_, start) =>
@@ -22,7 +12,10 @@ export function magicBasetype (name: string) {
)
const result = perm
.map(name => ({ name, found: baseTypes.has(name) }))
.map(name => {
const result = ITEM_BY_TRANSLATED('ITEM', name)
return { name, found: (result && result[0].craftable) }
})
.filter(res => res.found)
.sort((a, b) => b.name.length - a.name.length)
+5 -6
View File
@@ -1,5 +1,5 @@
/* eslint-disable camelcase */
import { CLIENTLOG_STRINGS as _$, ITEM_NAME_REF_BY_TRANSLATED, TRADE_TAGS } from '@/assets/data'
import { CLIENTLOG_STRINGS as _$ } from '@/assets/data'
import { AppConfig } from '@/web/Config'
const enum MessageChannel {
@@ -76,12 +76,11 @@ export function handleLine (line: string) {
entry.trade = {
item: {
name: ITEM_NAME_REF_BY_TRANSLATED.get(match.groups!.item) ||
match.groups!.item
name: match.groups!.item
},
price: {
amount: Number(pAmount),
name: TRADE_TAGS.find(pair => pair[1] === pTag)?.[0] || pTag
name: pTag
},
tab: {
name: match.groups!.tab_name,
@@ -111,11 +110,11 @@ export function handleLine (line: string) {
entry.trade = {
item: {
amount: Number(iAmount),
name: ITEM_NAME_REF_BY_TRANSLATED.get(iName) || iName
name: iName
},
price: {
amount: Number(pAmount),
name: ITEM_NAME_REF_BY_TRANSLATED.get(pName) || pName
name: pName
}
}
+3 -13
View File
@@ -7,9 +7,8 @@
<script lang="ts">
import { defineComponent, PropType, computed, inject } from 'vue'
import { useI18n } from 'vue-i18n'
import { ItemRarity, ParsedItem } from '@/parser'
import { TRANSLATED_ITEM_NAME_BY_REF } from '@/assets/data'
import { WidgetManager } from '../overlay/interfaces'
import type { ParsedItem } from '@/parser'
import type { WidgetManager } from '../overlay/interfaces'
export default defineComponent({
props: {
@@ -22,19 +21,10 @@ export default defineComponent({
const wm = inject<WidgetManager>('wm')!
const { t } = useI18n()
const itemName = computed(() => {
const { item } = props
if (item.rarity === ItemRarity.Unique) {
return TRANSLATED_ITEM_NAME_BY_REF.get(item.name || item.baseType)
} else {
return TRANSLATED_ITEM_NAME_BY_REF.get(item.baseType || item.name)
}
})
return {
t,
wm,
itemName
itemName: computed(() => props.item.info.name)
}
}
})
+5 -16
View File
@@ -20,10 +20,10 @@
<script lang="ts">
import { defineComponent, PropType, computed, inject } from 'vue'
import { useI18n } from 'vue-i18n'
import { ItemRarity, ParsedItem } from '@/parser'
import { ParsedItem } from '@/parser'
import MapStatButton from './MapStatButton.vue'
import { prepareMapStats } from './prepare-map-stats'
import { TRANSLATED_ITEM_NAME_BY_REF, MAP_IMGS, STAT_BY_MATCH_STR } from '@/assets/data'
import { MAP_IMGS, STAT_BY_MATCH_STR } from '@/assets/data'
import { WidgetManager, ItemCheckWidget } from '../overlay/interfaces'
import { AppConfig } from '@/web/Config'
@@ -43,19 +43,8 @@ export default defineComponent({
const config = computed(() => AppConfig<ItemCheckWidget>('item-check')!)
const mapName = computed(() => {
const { item } = props
if (item.rarity === ItemRarity.Unique) {
return TRANSLATED_ITEM_NAME_BY_REF.get(item.name || item.baseType)
} else {
return TRANSLATED_ITEM_NAME_BY_REF.get(item.baseType || item.name)
}
})
const mapStats = computed(() => {
return prepareMapStats(props.item)
})
const image = computed(() => {
const entry = mapName.value && MAP_IMGS.get(mapName.value)
const entry = MAP_IMGS.get(props.item.info.refName)
return entry && entry.img
})
const hasOutdatedTranslation = computed<boolean>(() => {
@@ -68,9 +57,9 @@ export default defineComponent({
return {
t,
wm,
mapName,
mapName: computed(() => props.item.info.name),
image,
mapStats,
mapStats: computed(() => prepareMapStats(props.item)),
hasOutdatedTranslation
}
}
+2 -9
View File
@@ -1,7 +1,6 @@
import { MainProcess } from '@/ipc/main-process-bindings'
import { parseClipboard, ItemRarity } from '@/parser'
import { parseClipboard } from '@/parser'
import { AppConfig } from '@/web/Config'
import { TRANSLATED_ITEM_NAME_BY_REF } from '@/assets/data'
const ENDPOINT_BY_LANG = {
en: 'www.poewiki.net/wiki',
@@ -12,11 +11,5 @@ export function openWiki (clipboard: string) {
const item = parseClipboard(clipboard)
if (!item) return
let pageName = (item.rarity === ItemRarity.Unique)
? item.name
: item.baseType || item.name
pageName = TRANSLATED_ITEM_NAME_BY_REF.get(pageName) || pageName
MainProcess.openSystemBrowser(`https://${ENDPOINT_BY_LANG[AppConfig().language]}/${pageName}`)
MainProcess.openSystemBrowser(`https://${ENDPOINT_BY_LANG[AppConfig().language]}/${item.info.name}`)
}
+1 -1
View File
@@ -175,7 +175,7 @@ export default defineComponent({
const show = computed(() => {
return !(props.item.rarity === ItemRarity.Unique &&
props.item.isUnidentified &&
props.item.baseType == null)
props.item.info.unique == null)
})
async function applyItemBaseFilter () {
@@ -114,7 +114,7 @@ export default defineComponent({
const showTag = computed(() =>
props.filter.tag !== FilterTag.Property &&
props.filter.tradeId[0] !== 'item.has_empty_modifier' &&
props.item.name !== 'Chronicle of Atzoatl' &&
props.item.info.refName !== 'Chronicle of Atzoatl' &&
!(props.item.rarity === ItemRarity.Unique && props.filter.tag === FilterTag.Explicit)
)
+3 -6
View File
@@ -16,7 +16,6 @@ import { useI18n } from 'vue-i18n'
import { ItemRarity, ParsedItem } from '@/parser'
import { ItemFilters } from './interfaces'
import { CATEGORY_TO_TRADE_ID } from '../trade/pathofexile-trade'
import { TRANSLATED_ITEM_NAME_BY_REF } from '@/assets/data'
export default defineComponent({
name: 'FilterName',
@@ -35,12 +34,10 @@ export default defineComponent({
const label = computed(() => {
if (props.filters.name) {
return TRANSLATED_ITEM_NAME_BY_REF.get(props.filters.name.value) ||
props.filters.name.value
return props.filters.name.value
}
if (props.filters.baseType) {
return TRANSLATED_ITEM_NAME_BY_REF.get(props.filters.baseType.value) ||
props.filters.baseType.value
return props.filters.baseType.value
}
if (props.filters.category) {
return t(`Category: ${props.filters.category.value}`)
@@ -66,7 +63,7 @@ export default defineComponent({
if (props.filters.category) {
props.filters.category = undefined
props.filters.baseType = {
value: props.item.baseType || props.item.name
value: props.item.info.name
}
} else {
props.filters.baseType = undefined
@@ -2,6 +2,7 @@ import type { ItemFilters } from './interfaces'
import { ParsedItem, ItemCategory, ItemRarity } from '@/parser'
import { tradeTag } from '../trade/common'
import { ModifierType } from '@/parser/modifiers'
import { ITEM_BY_REF } from '@/assets/data'
export const SPECIAL_SUPPORT_GEM = ['Empower Support', 'Enlighten Support', 'Enhance Support']
@@ -29,7 +30,8 @@ export function createFilters (
}
if (item.category === ItemCategory.CapturedBeast) {
filters.baseType = {
value: item.baseType || item.name
value: item.info.name,
trade: item.info.refName
}
return filters
}
@@ -41,7 +43,7 @@ export function createFilters (
}
if (item.category === ItemCategory.MavenInvitation) {
filters.baseType = {
value: item.baseType || item.name
value: item.info.name
}
return filters
}
@@ -50,7 +52,7 @@ export function createFilters (
item.category === ItemCategory.Seed
) {
filters.baseType = {
value: item.name
value: item.info.name
}
filters.itemLevel = {
value: item.itemLevel!,
@@ -63,9 +65,9 @@ export function createFilters (
item.category === ItemCategory.Currency
) {
filters.baseType = {
value: item.name
value: item.info.name
}
if (item.name === 'Chronicle of Atzoatl') {
if (item.info.refName === 'Chronicle of Atzoatl') {
filters.areaLevel = {
value: floorToBracket(item.areaLevel!, [1, 68, 73, 75, 78, 80])
}
@@ -74,14 +76,15 @@ export function createFilters (
}
if (item.category === ItemCategory.Prophecy) {
filters.name = {
value: item.name
value: item.info.name
}
filters.baseType = {
value: 'Prophecy'
value: ITEM_BY_REF('ITEM', 'Prophecy')![0].name
}
if (item.extra.prophecyMaster) {
if (item.info.prophecy?.masterName) {
filters.discriminator = {
value: item.extra.prophecyMaster
value: item.info.prophecy.masterName,
trade: item.info.tradeDisc!
}
}
return filters
@@ -94,7 +97,9 @@ export function createFilters (
}
} else {
filters.baseType = {
value: item.baseType || item.name
value: (item.info.unique)
? ITEM_BY_REF('ITEM', item.info.unique.base)![0].name
: item.info.name
}
}
@@ -103,33 +108,29 @@ export function createFilters (
}
if (item.rarity === ItemRarity.Unique) {
filters.name = { value: item.name }
filters.name = { value: item.info.name }
}
filters.mapTier = {
value: item.mapTier!
}
} else if (
item.category === ItemCategory.HeistContract ||
item.category === ItemCategory.HeistBlueprint
item.rarity !== ItemRarity.Unique && (
item.category === ItemCategory.HeistContract ||
item.category === ItemCategory.HeistBlueprint)
) {
if (item.rarity === ItemRarity.Unique) {
filters.name = { value: item.name }
filters.baseType = { value: item.baseType! }
} else {
filters.category = {
value: item.category
}
filters.category = {
value: item.category
}
filters.areaLevel = {
value: item.areaLevel!
}
filters.areaLevel = {
value: item.areaLevel!
}
if (item.heistJob) {
filters.heistJob = {
name: item.heistJob.name,
level: item.heistJob.level
}
if (item.heistJob) {
filters.heistJob = {
name: item.heistJob.name,
level: item.heistJob.level
}
}
} else if (
@@ -137,15 +138,11 @@ export function createFilters (
item.rarity !== ItemRarity.Unique
) {
filters.baseType = {
value: item.baseType || item.name
}
} else if (item.rarity === ItemRarity.Unique) {
filters.name = {
value: item.name
}
filters.baseType = {
value: item.baseType!
value: item.info.name
}
} else if (item.rarity === ItemRarity.Unique && item.info.unique) {
filters.name = { value: item.info.name }
filters.baseType = { value: ITEM_BY_REF('ITEM', item.info.unique.base)![0].name }
} else if (item.rarity === ItemRarity.Rare) {
if (item.category) {
filters.category = {
@@ -156,7 +153,7 @@ export function createFilters (
} else {
// @TODO
filters.baseType = {
value: item.baseType || item.name
value: item.info.name
}
}
@@ -241,7 +238,7 @@ export function createFilters (
}
if (item.rarity === ItemRarity.Unique) {
if (item.isUnidentified && item.name === "Watcher's Eye") {
if (item.isUnidentified && item.info.refName === "Watcher's Eye") {
filters.itemLevel = {
value: item.itemLevel,
disabled: false
@@ -250,7 +247,7 @@ export function createFilters (
if (item.itemLevel >= 75 && [
'Agnerod', 'Agnerod East', 'Agnerod North', 'Agnerod South', 'Agnerod West'
].includes(item.name)) {
].includes(item.info.refName)) {
// https://pathofexile.gamepedia.com/The_Vinktar_Square
const normalizedLvl =
item.itemLevel >= 82 ? 82
@@ -281,7 +278,7 @@ export function createFilters (
}
filters.category = undefined
filters.baseType = {
value: item.baseType || item.name
value: item.info.name
}
}
}
@@ -306,7 +303,7 @@ export function createFilters (
function createGemFilters (item: ParsedItem, filters: ItemFilters) {
filters.baseType = {
value: item.name
value: item.info.name
}
filters.corrupted = {
@@ -320,7 +317,7 @@ function createGemFilters (item: ParsedItem, filters: ItemFilters) {
}
}
if (SPECIAL_SUPPORT_GEM.includes(item.name)) {
if (SPECIAL_SUPPORT_GEM.includes(item.info.refName)) {
filters.gemLevel = {
min: item.gemLevel!,
max: item.gemLevel!,
@@ -307,7 +307,7 @@ function finalFilterTweaks (ctx: FiltersCreationContext) {
}
}
if (item.name === 'Chronicle of Atzoatl') {
if (item.info.refName === 'Chronicle of Atzoatl') {
applyAtzoatlRules(ctx.filters)
}
}
@@ -9,9 +9,11 @@ export interface ItemFilters {
}
baseType?: {
value: string
trade?: string
}
discriminator?: {
value: string
trade: string
}
category?: {
value: ItemCategory
+1 -1
View File
@@ -11,7 +11,7 @@ export function uniqueModFilterPartial (
percent: number,
dp: boolean
): void {
// const uniqueInfo = UNIQUES.get(`${item.name} ${item.baseType!}`)
// const uniqueInfo = UNIQUES.get(`${item.info.refName} ${item.info.unique!.base}`)
// TODO set this info again and uncomment line
// filter.variant = modInfo.variant
@@ -15,7 +15,7 @@
:min="price.min"
:max="price.max"
approx
:item-img="item.icon"
:item-img="item.info.icon"
:currency="price.currency === 'exalt' ? 'exa' : 'chaos'"
/>
<div class="text-center">
@@ -33,7 +33,7 @@ export default defineComponent({
function getPriceFor (n: number) {
const one = findByDetailsId(getDetailsId(props.item)!)!
const price = (props.item.name === 'Exalted Orb')
const price = (props.item.info.refName === 'Exalted Orb')
? { val: n * one.receive.chaosValue, curr: 'c' }
: autoCurrency(n * one.receive.chaosValue, 'c')
+3 -4
View File
@@ -92,8 +92,7 @@ import { useI18n } from 'vue-i18n'
import { DateTime } from 'luxon'
import { MainProcess } from '@/ipc/main-process-bindings'
import { BulkSearch, execBulkSearch, PricingResult, requestResults } from './pathofexile-bulk'
import { tradeTag, getTradeEndpoint } from './common'
import { TRADE_TAG_BY_NAME } from '@/assets/data'
import { getTradeEndpoint } from './common'
import { selected as league } from '../../background/Leagues'
import { AppConfig } from '@/web/Config'
import { ItemFilters } from '../filters/interfaces'
@@ -197,9 +196,9 @@ export default defineComponent({
const { exa, chaos } = result.value
selectedCurr.value = (exa.total > chaos.total) ? 'exa' : 'chaos'
// override, because at league start many players set wrong price, and this breaks auto-detection
if (tradeTag(props.item) === TRADE_TAG_BY_NAME.get('Chaos Orb')) {
if (props.item.info.refName === 'Chaos Orb') {
selectedCurr.value = 'exa'
} else if (tradeTag(props.item) === TRADE_TAG_BY_NAME.get('Exalted Orb')) {
} else if (props.item.info.refName === 'Exalted Orb') {
selectedCurr.value = 'chaos'
}
}
+2 -20
View File
@@ -1,10 +1,9 @@
import { shallowReactive } from 'vue'
import type { ItemFilters, StatFilter } from '../filters/interfaces'
import { TRADE_TAG_BY_NAME } from '@/assets/data'
import { AppConfig } from '@/web/Config'
import type { PriceCheckWidget } from '@/web/overlay/interfaces'
import { RateLimiter } from './RateLimiter'
import { ParsedItem, ItemCategory, ItemRarity } from '@/parser'
import { ParsedItem, ItemCategory } from '@/parser'
export const PERMANENT_LEAGUES = ['Standard', 'Hardcore']
@@ -47,24 +46,7 @@ export function apiToSatisfySearch (item: ParsedItem, stats: StatFilter[], filte
}
export function tradeTag (item: ParsedItem): string | undefined {
let name = item.baseType || item.name
if (item.category === ItemCategory.Map && item.rarity === ItemRarity.Unique) {
name = item.name
}
if (name) {
if (item.mapBlighted === 'Blighted') {
name = `Blighted ${name} (Tier ${item.mapTier})`
} else if (item.mapBlighted === 'Blight-ravaged') {
// TODO
} else if (item.mapTier) {
name = `${name} (Tier ${item.mapTier})`
} else if (item.extra.prophecyMaster) {
name = `${name} (${item.extra.prophecyMaster})`
}
return TRADE_TAG_BY_NAME.get(name)
}
return item.info.tradeTag
}
const ENDPOINT_BY_LANG = {
+5 -13
View File
@@ -3,7 +3,7 @@ import { ItemFilters, StatFilter, INTERNAL_TRADE_IDS, InternalTradeId } from '..
import prop from 'dot-prop'
import { MainProcess } from '@/ipc/main-process-bindings'
import { SearchResult, Account, getTradeEndpoint, adjustRateLimits, RATE_LIMIT_RULES, preventQueueCreation, PERMANENT_LEAGUES } from './common'
import { STAT_BY_REF, TRANSLATED_ITEM_NAME_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'
@@ -253,15 +253,11 @@ export function createTradeRequest (filters: ItemFilters, stats: StatFilter[], i
}
if (filters.name) {
query.name = nameToQuery(filters.name.value, filters, true)
query.name = nameToQuery(filters.name.value, filters)
}
if (filters.baseType) {
if (item.category === ItemCategory.CapturedBeast) {
query.type = nameToQuery(filters.baseType.value, filters, false)
} else {
query.type = nameToQuery(filters.baseType.value, filters, true)
}
query.type = nameToQuery(filters.baseType.trade ?? filters.baseType.value, filters)
}
if (filters.rarity) {
@@ -619,16 +615,12 @@ function tradeIdToQuery (id: string, stat: StatFilter) {
}
}
function nameToQuery (name: string, filters: ItemFilters, translate: boolean) {
if (translate) {
name = TRANSLATED_ITEM_NAME_BY_REF.get(name) || name
}
function nameToQuery (name: string, filters: ItemFilters) {
if (!filters.discriminator) {
return name
} else {
return {
discriminator: filters.discriminator.value.toLowerCase(),
discriminator: filters.discriminator.trade,
option: name
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ export default defineComponent({
const trend = detailsId && findByDetailsId(detailsId)
if (!trend) return
const price = (props.item.name === 'Exalted Orb')
const price = (props.item.info.refName === 'Exalted Orb')
? { val: trend.receive.chaosValue, curr: 'c' }
: autoCurrency(trend.receive.chaosValue, 'c')
+31 -27
View File
@@ -24,14 +24,14 @@ export function getDetailsId (item: ParsedItem) {
}
if (item.category === ItemCategory.Map) {
if (item.rarity === ItemRarity.Unique) {
return nameToDetailsId(`${item.name} t${item.mapTier}`)
return nameToDetailsId(`${item.info.refName} t${item.mapTier}`)
} else {
return nameToDetailsId(`${item.mapBlighted ? `${item.mapBlighted} ` : ''}${item.baseType || item.name} t${item.mapTier} ${LATEST_MAP_VARIANT}`)
return nameToDetailsId(`${item.mapBlighted ? `${item.mapBlighted} ` : ''}${item.info.refName} t${item.mapTier} ${LATEST_MAP_VARIANT}`)
}
}
if (item.category === ItemCategory.CapturedBeast ||
item.category === ItemCategory.MavenInvitation) {
return nameToDetailsId(item.baseType || item.name)
return nameToDetailsId(item.info.refName)
}
if (item.rarity === ItemRarity.Unique) {
return getUniqueDetailsId(item)
@@ -39,14 +39,14 @@ export function getDetailsId (item: ParsedItem) {
if (isValuableBasetype(item)) {
return getBaseTypeDetailsId(item)
}
if (item.extra.prophecyMaster) {
return nameToDetailsId(`${item.name} ${item.extra.prophecyMaster}`)
if (item.info.prophecy?.masterName) {
return nameToDetailsId(`${item.info.refName} ${item.info.prophecy.masterName}`)
}
if (item.category === ItemCategory.Seed) {
return nameToDetailsId(`${item.name} ${item.itemLevel! >= 76 ? '76' : '1-75'}`)
return nameToDetailsId(`${item.info.refName} ${item.itemLevel! >= 76 ? '76' : '1-75'}`)
}
return nameToDetailsId(item.baseType ? `${item.name} ${item.baseType}` : item.name)
return nameToDetailsId(item.info.name)
}
const BRAND_RECALL_GEM = 'Brand Recall'
@@ -54,18 +54,18 @@ const BLOOD_AND_SAND_GEM = 'Blood and Sand'
const PORTAL_GEM = 'Portal'
function getGemDetailsId (item: ParsedItem) {
if (item.name === PORTAL_GEM) {
if (item.info.refName === PORTAL_GEM) {
return 'portal-1'
}
let id = item.gemAltQuality === 'Superior'
? nameToDetailsId(item.name)
: nameToDetailsId(`${item.gemAltQuality} ${item.name}`)
? nameToDetailsId(item.info.refName)
: nameToDetailsId(`${item.gemAltQuality} ${item.info.refName}`)
if (
SPECIAL_SUPPORT_GEM.includes(item.name) ||
item.name === BRAND_RECALL_GEM ||
item.name === BLOOD_AND_SAND_GEM ||
SPECIAL_SUPPORT_GEM.includes(item.info.refName) ||
item.info.refName === BRAND_RECALL_GEM ||
item.info.refName === BLOOD_AND_SAND_GEM ||
item.gemLevel! >= 20
) {
id += `-${item.gemLevel}`
@@ -74,9 +74,9 @@ function getGemDetailsId (item: ParsedItem) {
}
if (item.quality) {
if (
!SPECIAL_SUPPORT_GEM.includes(item.name) &&
!(item.name === BRAND_RECALL_GEM && item.isCorrupted)
// @TODO(poe.ninja blocking): !(item.name === BLOOD_AND_SAND_GEM && item.isCorrupted)
!SPECIAL_SUPPORT_GEM.includes(item.info.refName) &&
!(item.info.refName === BRAND_RECALL_GEM && item.isCorrupted)
// @TODO(poe.ninja blocking): !(item.info.refName === BLOOD_AND_SAND_GEM && item.isCorrupted)
) {
// Gem Q20 with up to 4xGCP (TODO: should this rule apply to corrupted gems?)
const q = (item.quality >= 16 && item.quality <= 20) ? 20 : item.quality
@@ -91,7 +91,7 @@ function getGemDetailsId (item: ParsedItem) {
}
function getBaseTypeDetailsId (item: ParsedItem) {
let id = nameToDetailsId(`${item.baseType || item.name}`)
let id = nameToDetailsId(item.info.refName)
id += `-${Math.min(item.itemLevel!, 86)}`
@@ -105,12 +105,14 @@ function getBaseTypeDetailsId (item: ParsedItem) {
}
function getUniqueDetailsId (item: ParsedItem) {
let id = nameToDetailsId(`${item.name}${getUniqueVariant(item) || ''} ${item.baseType}`)
if (!item.info.unique) return
let id = nameToDetailsId(`${item.info.refName}${getUniqueVariant(item) || ''} ${item.info.unique.base}`)
if (item.sockets?.linked) {
id += `-${item.sockets.linked}l`
}
if (item.baseType === 'Ivory Watchstone') {
if (item.info.unique.base === 'Ivory Watchstone') {
const uses = item.statsByType.find(m => m.type === 'explicit' && m.stat.ref === '# uses remaining')!
const roll = uses.sources[0].contributes!.value
id += `-${roll}`
@@ -124,7 +126,9 @@ function getUniqueVariant (item: ParsedItem) {
return item.statsByType.some(m => m.stat.ref === stat)
}
if (item.name === 'Vessel of Vinktar') {
const uniqueName = item.info.refName
if (uniqueName === 'Vessel of Vinktar') {
if (hasStat(item, 'Adds # to # Lightning Damage to Attacks during Flask effect')) {
return '-added-attacks'
} else if (hasStat(item, 'Adds # to # Lightning Damage to Spells during Flask effect')) {
@@ -134,7 +138,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, '#% of Physical Damage Converted to Lightning during Flask effect')) {
return '-conversion'
}
} else if (item.name === "Atziri's Splendour") {
} else if (uniqueName === "Atziri's Splendour") {
if (hasStat(item, '#% increased Armour, Evasion and Energy Shield')) {
return '-armour-evasion-es'
} else if (hasStat(item, '#% increased Evasion and Energy Shield') && hasStat(item, '+# to maximum Energy Shield')) {
@@ -154,7 +158,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, '#% increased Armour') && hasStat(item, '+# to maximum Life')) {
return '-armour'
}
} else if (item.name === 'Bubonic Trail' || item.name === 'Lightpoacher' || item.name === 'Shroud of the Lightless' || item.name === 'Tombfist') {
} else if (uniqueName === 'Bubonic Trail' || uniqueName === 'Lightpoacher' || uniqueName === 'Shroud of the Lightless' || uniqueName === 'Tombfist') {
const sockets = item.statsByType.find(m => m.type === 'explicit' && m.stat.ref === 'Has # Abyssal Sockets')!
const roll = sockets.sources[0].contributes!.value
if (roll === 2) {
@@ -162,7 +166,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (roll === 1) {
return '-1-jewel'
}
} else if (item.name === "Volkuur's Guidance") {
} else if (uniqueName === "Volkuur's Guidance") {
if (hasStat(item, 'Adds # to # Cold Damage to Spells and Attacks')) {
return '-cold'
} else if (hasStat(item, 'Adds # to # Fire Damage to Spells and Attacks')) {
@@ -170,7 +174,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, 'Adds # to # Lightning Damage to Spells and Attacks')) {
return '-lightning'
}
} else if (item.name === "Yriel's Fostering") {
} else if (uniqueName === "Yriel's Fostering") {
if (hasStat(item, 'Projectiles from Attacks have #% chance to Maim on Hit while\nyou have a Bestial Minion')) {
return '-maim'
} else if (hasStat(item, 'Projectiles from Attacks have #% chance to Poison on Hit while\nyou have a Bestial Minion')) {
@@ -178,7 +182,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, 'Projectiles from Attacks have #% chance to inflict Bleeding on Hit while\nyou have a Bestial Minion')) {
return '-bleeding'
}
} else if (item.name === "Doryani's Invitation") {
} else if (uniqueName === "Doryani's Invitation") {
if (hasStat(item, '#% increased Global Physical Damage')) {
return '-physical'
} else if (hasStat(item, '#% increased Fire Damage')) {
@@ -188,7 +192,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, '#% increased Lightning Damage')) {
return '-lightning'
}
} else if (item.name === 'Impresence') {
} else if (uniqueName === 'Impresence') {
if (hasStat(item, 'Adds # to # Cold Damage')) {
return '-cold'
} else if (hasStat(item, 'Adds # to # Chaos Damage')) {
@@ -200,7 +204,7 @@ function getUniqueVariant (item: ParsedItem) {
} else if (hasStat(item, 'Adds # to # Physical Damage')) {
return '-physical'
}
} else if (item.name === 'Voices') {
} else if (uniqueName === 'Voices') {
const passives = item.statsByType.find(m => m.stat.ref === 'Adds # Small Passive Skills which grant nothing')!
const roll = passives.sources[0].contributes!.value
if (roll === 7) {
@@ -6,7 +6,7 @@
<div class="overflow-auto pb-4 px-4">
<div class="flex flex-wrap -m-1">
<div v-for="item in identifiedVariants" :key="item.name" class="p-1 flex w-1/2">
<button @click="select(item.refName)" class="bg-gray-700 rounded flex items-center p-2 w-full">
<button @click="select(item)" class="bg-gray-700 rounded flex items-center p-2 w-full">
<img :src="item.icon" class="w-12" />
<div class="pl-3 leading-tight">{{ item.name }}</div>
</button>
@@ -19,7 +19,7 @@
<script lang="ts">
import { defineComponent, PropType, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { UNIQUES_LIST, TRANSLATED_ITEM_NAME_BY_REF } from '@/assets/data'
import { BaseType2, ITEMS_ITERATOR } from '@/assets/data'
import { ItemRarity, ParsedItem } from '@/parser'
export default defineComponent({
@@ -32,17 +32,18 @@ export default defineComponent({
},
setup (props, ctx) {
const identifiedVariants = computed(() => {
const name = props.item!.name
const possible = UNIQUES_LIST
.filter(unique => unique.basetype === name)
.map(unique => ({
refName: unique.name,
icon: unique.icon,
name: TRANSLATED_ITEM_NAME_BY_REF.get(unique.name) || unique.name
}))
const baseType = props.item!.info.refName
const possible: BaseType2[] = []
for (const match of ITEMS_ITERATOR(baseType)) {
if (match.namespace === 'UNIQUE' && match.unique!.base === baseType) {
// TODO currently ignoring variants
if (!possible.some(unique => unique.refName === match.refName)) {
possible.push(match)
}
}
}
if (possible.length === 1) {
select(possible[0].refName)
select(possible[0])
}
return possible
@@ -53,25 +54,13 @@ export default defineComponent({
return props.item.rarity === ItemRarity.Unique &&
props.item.isUnidentified &&
props.item.baseType == null
!props.item.info.unique
})
const baseType = computed(() => {
return TRANSLATED_ITEM_NAME_BY_REF.get(props.item!.name) ||
props.item!.name
})
function select (name: string) {
if ([
'Agnerod East', 'Agnerod North', 'Agnerod South', 'Agnerod West'
].includes(name)) {
name = 'Agnerod'
}
function select (info: BaseType2) {
const newItem: ParsedItem = {
...props.item!,
name: name,
baseType: props.item!.name
info: info
}
ctx.emit('identify', newItem)
}
@@ -82,7 +71,7 @@ export default defineComponent({
t,
identifiedVariants,
show,
baseType,
baseType: computed(() => props.item!.info.name),
select
}
}
+5
View File
@@ -551,6 +551,11 @@
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@sindresorhus/fnv1a@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/fnv1a/-/fnv1a-3.0.0.tgz#e8ce2e7c7738ec8c354867d38e3bfcde622b87ca"
integrity sha512-M6pmbdZqAryzjZ4ELAzrdCMoMZk5lH/fshKrapfSeXdf2W+GDqZvPmfXaNTZp43//FVbSwkTPwpEMnehSyskkQ==
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"