@juice789/tf2items 1.0.39 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fromListingV1.js CHANGED
@@ -1,74 +1,31 @@
1
- const {
2
- compose,
3
- complement,
4
- propEq,
5
- hasPath,
6
- F,
7
- prop,
8
- chain,
9
- assoc,
10
- map,
11
- __,
12
- applyTo,
13
- cond,
14
- identity,
15
- T,
16
- flatten,
17
- toPairs,
18
- pathOr,
19
- pickBy,
20
- indexBy,
21
- propOr,
22
- path,
23
- find,
24
- includes,
25
- values,
26
- nth,
27
- has,
28
- when,
29
- allPass,
30
- converge,
31
- or,
32
- take,
33
- uncurryN
34
- } = require('ramda')
35
-
36
- const { safeItems: items } = require('./schemaItems.js')
37
- const { textures } = require('./schema.json')
38
- const { skuFromItem } = require('./sku.js')
39
-
40
- const {
41
- kitRemap
42
- } = require('./fromEconItem.js')
43
-
44
- const findValue = uncurryN(2, (fns) => compose(
45
- find(Boolean),
46
- map(__, fns),
47
- applyTo
48
- ))
49
-
50
- const isWeaponEffect = compose(includes(__, ['701', '702', '703', '704']), String)
51
-
52
- const defindex = prop('defindex')
53
-
54
- const quality = prop('quality')
55
-
56
- const uncraftable = compose(Boolean, prop('flag_cannot_craft'))
1
+ import { safeItems as items } from './schemaItems.js'
2
+ import schema from './schema.json' with { type: 'json' }
3
+ const { textures } = schema
4
+ import { skuFromItem } from './sku.js'
5
+ import { kitRemap } from './fromEconItem.js'
6
+
7
+ function coalesce(fns, item) {
8
+ return fns.map(fn => fn(item)).find(Boolean)
9
+ }
10
+
11
+ const isWeaponEffect = x => ['701', '702', '703', '704'].includes(String(x))
12
+
13
+ const defindex = item => item.defindex
14
+
15
+ const quality = item => item.quality
16
+
17
+ const uncraftable = item => Boolean(item.flag_cannot_craft)
57
18
 
58
19
  const effectOptions = [
59
- path(['attributes', '134', 'float_value']),
60
- path(['attributes', '2041', 'value']),
20
+ item => item?.attributes?.['134']?.float_value,
21
+ item => item?.attributes?.['2041']?.value,
61
22
  ]
62
23
 
63
- const effect = findValue(effectOptions)
24
+ const effect = item => coalesce(effectOptions, item)
64
25
 
65
- const elevated = cond(
66
- [
67
- [complement(propEq)(11, 'quality'), hasPath(['attributes', '214'])],
68
- [propEq(11, 'quality'), compose(isWeaponEffect, effect)],
69
- [T, F]
70
- ]
71
- )
26
+ const elevated = item => item.quality === 11
27
+ ? isWeaponEffect(effect(item))
28
+ : '214' in (item.attributes ?? {})
72
29
 
73
30
  const ktRemap = {
74
31
  '6527': '1',
@@ -79,15 +36,15 @@ const ktRemap = {
79
36
  }
80
37
 
81
38
  const ktOptions = [
82
- path(['attributes', '2025', 'float_value']),
83
- compose(prop(__, ktRemap), prop('defindex'))
39
+ item => item?.attributes?.['2025']?.float_value,
40
+ item => ktRemap[item.defindex]
84
41
  ]
85
42
 
86
- const killstreakTier = findValue(ktOptions)
43
+ const killstreakTier = item => coalesce(ktOptions, item)
87
44
 
88
- const festivized = hasPath(['attributes', '2053'])
45
+ const festivized = item => '2053' in (item.attributes ?? {})
89
46
 
90
- const texture = path(['attributes', '834', 'value'])
47
+ const texture = item => item?.attributes?.['834']?.value
91
48
 
92
49
  const wears = {
93
50
  '0': null,
@@ -98,46 +55,31 @@ const wears = {
98
55
  '1': '5'
99
56
  }
100
57
 
101
- const wear = compose(
102
- prop(__, wears),
103
- take(3),
104
- String,
105
- pathOr('0', ['attributes', '725', 'float_value'])
106
- )
58
+ const wear = item => wears[String(item?.attributes?.['725']?.float_value ?? '0').slice(0, 3)]
107
59
 
108
- const australium = hasPath(['attributes', '2027'])
60
+ const australium = item => '2027' in (item.attributes ?? {})
109
61
 
110
- const series = path(['attributes', '187', 'float_value'])
62
+ const series = item => item?.attributes?.['187']?.float_value
111
63
 
112
- const findOutput = compose(
113
- find(compose(includes(__, [true, 'true']), prop('is_output'))),
114
- values,
115
- propOr({}, 'attributes')
116
- )
64
+ const findOutput = item => Object.values(item.attributes ?? {})
65
+ .find(attr => [true, 'true'].includes(attr.is_output))
117
66
 
118
- const findRecipeTarget = compose(
119
- prop('float_value'),
120
- find(compose(includes(__, ['2012', 2012]), prop('defindex'))),
121
- propOr([], 'attributes'),
122
- findOutput
123
- )
67
+ const findRecipeTarget = item => {
68
+ const out = findOutput(item)
69
+ const attr = (out?.attributes ?? []).find(a => ['2012', 2012].includes(a.defindex))
70
+ return attr?.float_value
71
+ }
124
72
 
125
73
  const targetOptions = [
126
- path(['attributes', '2012', 'float_value']),
74
+ item => item?.attributes?.['2012']?.float_value,
127
75
  findRecipeTarget
128
76
  ]
129
77
 
130
- const target = findValue(targetOptions)
78
+ const target = item => coalesce(targetOptions, item)
131
79
 
132
- const output = compose(
133
- prop('itemdef'),
134
- findOutput
135
- )
80
+ const output = item => findOutput(item)?.itemdef
136
81
 
137
- const oq = compose(
138
- prop('quality'),
139
- findOutput
140
- )
82
+ const oq = item => findOutput(item)?.quality
141
83
 
142
84
  const fns = {
143
85
  defindex,
@@ -156,94 +98,42 @@ const fns = {
156
98
  oq
157
99
  }
158
100
 
159
- const remap = (fn1, fn2) => when(
160
- fn1,
161
- chain(
162
- assoc('defindex'),
163
- converge(
164
- or,
165
- [
166
- fn2,
167
- prop('defindex')
168
- ]
169
- )
170
- )
171
- )
101
+ const remap = (fn1, fn2) => item => fn1(item)
102
+ ? { ...item, defindex: fn2(item) || item.defindex }
103
+ : item
172
104
 
173
105
  const remapStrangifier = remap(
174
- compose(
175
- propEq('Strangifier', 'item_name'),
176
- prop(__, items),
177
- prop('defindex')
178
- ),
179
- compose(
180
- prop('defindex'),
181
- nth(0),
182
- values,
183
- (listingTarget) => pickBy(
184
- compose(
185
- includes(listingTarget.toString()),
186
- propOr([], 'target')
187
- ),
188
- items
189
- ),
190
- prop('target')
191
- )
106
+ item => items[item.defindex]?.item_name === 'Strangifier',
107
+ item => {
108
+ const t = String(item.target)
109
+ return Object.values(items).find(v => (v.target ?? []).includes(t))?.defindex
110
+ }
192
111
  )
193
112
 
194
- const strangifierSets = pickBy(allPass([
195
- has('td'),
196
- propEq('Chemistry Set', 'item_name')
197
- ]), items)
113
+ const strangifierSets = Object.fromEntries(
114
+ Object.entries(items).filter(([, v]) => 'td' in v && v.item_name === 'Chemistry Set')
115
+ )
198
116
 
199
117
  const remapStrangifierSet = remap(
200
- allPass([
201
- propEq(20001, 'defindex'),
202
- prop('output'),
203
- prop('target')
204
- ]),
205
- compose(
206
- prop('defindex'),
207
- nth(0),
208
- values,
209
- (listingTarget) => pickBy(
210
- compose(
211
- includes(listingTarget.toString()),
212
- prop('td')
213
- ),
214
- strangifierSets
215
- ),
216
- prop('target'),
217
- )
118
+ item => item.defindex === 20001 && item.output && item.target,
119
+ item => {
120
+ const t = String(item.target)
121
+ return Object.values(strangifierSets).find(v => v.td?.includes(t))?.defindex
122
+ }
218
123
  )
219
124
 
220
- const collectorSets = pickBy(allPass([
221
- complement(prop)('td'),
222
- prop('od'),
223
- propEq('Chemistry Set', 'item_name'),
224
- ]), items)
125
+ const collectorSets = Object.fromEntries(
126
+ Object.entries(items).filter(([, v]) => !v.td && v.od && v.item_name === 'Chemistry Set')
127
+ )
225
128
 
226
129
  const remapCollectorSet = remap(
227
- allPass([
228
- propEq(20001, 'defindex'),
229
- complement(prop)('target')
230
- ]),
231
- compose(
232
- prop('defindex'),
233
- nth(0),
234
- values,
235
- (listingOutput) => pickBy(
236
- compose(
237
- includes(listingOutput.toString()),
238
- prop('od')
239
- ),
240
- collectorSets
241
- ),
242
- prop('output')
243
- )
130
+ item => item.defindex === 20001 && !item.target,
131
+ item => {
132
+ const o = String(item.output)
133
+ return Object.values(collectorSets).find(v => v.od?.includes(o))?.defindex
134
+ }
244
135
  )
245
136
 
246
-
247
137
  const weaponIndex = {
248
138
  "0": 190,
249
139
  "1": 191,
@@ -276,51 +166,37 @@ const weaponIndex = {
276
166
  "12": 199
277
167
  }
278
168
 
279
- const remapWeapon = when(
280
- compose(has(__, weaponIndex), prop('defindex')),
281
- chain(assoc('defindex'), compose(prop(__, weaponIndex), prop('defindex')))
282
- )
169
+ const remapWeapon = item => item.defindex in weaponIndex
170
+ ? { ...item, defindex: weaponIndex[item.defindex] }
171
+ : item
283
172
 
284
- const decodeSkinQuality = cond([
285
- [allPass([propEq(15, 'quality'), compose(isWeaponEffect, prop('effect'))]), assoc('quality', 5)], //decorated + effect = unusual
286
- [allPass([propEq(11, 'quality'), compose(isWeaponEffect, prop('effect'))]), assoc('quality', 5)], //strange + effect = unusual
287
- [allPass([propEq(15, 'quality'), complement(prop)('effect'), prop('elevated')]), assoc('quality', 11)], //decorated + elevated = strange
288
- [T, identity]
289
- ])
173
+ function decodeSkinQuality(item) {
174
+ if (item.quality === 15 && isWeaponEffect(item.effect)) return { ...item, quality: 5 } // decorated + effect = unusual
175
+ if (item.quality === 11 && isWeaponEffect(item.effect)) return { ...item, quality: 5 } // strange + effect = unusual
176
+ if (item.quality === 15 && !item.effect && item.elevated) return { ...item, quality: 11 } // decorated + elevated = strange
177
+ return item
178
+ }
290
179
 
291
- const unboxedSkins = map(
292
- (item) => assoc('item_name', textures[item.texture] + ' ' + item.item_name, item),
293
- pickBy(propEq(15, 'item_quality'), items)
180
+ const unboxedSkins = Object.fromEntries(
181
+ Object.entries(items)
182
+ .filter(([, v]) => v.item_quality === 15)
183
+ .map(([k, v]) => [k, { ...v, item_name: textures[v.texture] + ' ' + v.item_name }])
294
184
  )
295
185
 
296
186
  const unboxSkinsRemap = remap(
297
- prop('texture'),
298
- compose(
299
- nth(0),
300
- flatten,
301
- toPairs,
302
- ({ defindex, texture }) => pickBy(
303
- propEq(textures[texture] + ' ' + items[defindex].item_name, 'item_name'),
304
- unboxedSkins
305
- )
306
- )
187
+ item => item.texture,
188
+ item => {
189
+ const expectedName = textures[item.texture] + ' ' + items[item.defindex].item_name
190
+ return Object.entries(unboxedSkins).find(([, v]) => v.item_name === expectedName)?.[0]
191
+ }
307
192
  )
308
193
 
309
194
  const remapCrateSeries = remap(
310
- prop('series'),
311
- compose(
312
- prop('defindex'),
313
- find(
314
- __,
315
- values(items)
316
- ),
317
- (s) => compose(
318
- includes(s),
319
- propOr([], 'series')
320
- ),
321
- String,
322
- prop('series')
323
- )
195
+ item => item.series,
196
+ item => {
197
+ const s = String(item.series)
198
+ return Object.values(items).find(v => (v.series ?? []).includes(s))?.defindex
199
+ }
324
200
  )
325
201
 
326
202
  const promoIndex = {
@@ -337,38 +213,27 @@ const promoIndex = {
337
213
  "817": "838"
338
214
  }
339
215
 
340
- const promoRemap = when(
341
- allPass([
342
- compose(has(__, promoIndex), prop('defindex')),
343
- propEq(1, 'quality')
344
- ]),
345
- chain(assoc('defindex'), compose(prop(__, promoIndex), prop('defindex')))
346
- )
216
+ const promoRemap = item => item.defindex in promoIndex && item.quality === 1
217
+ ? { ...item, defindex: promoIndex[item.defindex] }
218
+ : item
347
219
 
348
- const remaps = compose(
349
- remapCrateSeries,
350
- unboxSkinsRemap,
351
- kitRemap,
352
- promoRemap,
353
- decodeSkinQuality,
354
- remapWeapon,
355
- remapCollectorSet,
220
+ export const remaps = item => [
221
+ remapStrangifier,
356
222
  remapStrangifierSet,
357
- remapStrangifier
358
- )
223
+ remapCollectorSet,
224
+ remapWeapon,
225
+ decodeSkinQuality,
226
+ promoRemap,
227
+ kitRemap,
228
+ unboxSkinsRemap,
229
+ remapCrateSeries,
230
+ ].reduce((acc, fn) => fn(acc), item)
359
231
 
360
- const fromListingV1 = compose(
361
- skuFromItem,
362
- remaps,
363
- map(__, fns),
364
- applyTo,
365
- chain(
366
- assoc('attributes'),
367
- compose(
368
- indexBy(prop('defindex')),
369
- propOr([], 'attributes')
370
- )
232
+ export function fromListingV1(item) {
233
+ const indexedAttrs = Object.fromEntries(
234
+ (item.attributes ?? []).map(a => [a.defindex, a])
371
235
  )
372
- )
373
-
374
- module.exports = { fromListingV1, remaps }
236
+ const normalized = { ...item, attributes: indexedAttrs }
237
+ const mapped = Object.fromEntries(Object.entries(fns).map(([k, fn]) => [k, fn(normalized)]))
238
+ return skuFromItem(remaps(mapped))
239
+ }
package/fromListingV2.js CHANGED
@@ -1,69 +1,41 @@
1
- const {
2
- compose,
3
- propEq,
4
- prop,
5
- map,
6
- __,
7
- applyTo,
8
- pathOr,
9
- includes,
10
- pathEq,
11
- propOr,
12
- ifElse,
13
- equals,
14
- length,
15
- split,
16
- allPass,
17
- nth,
18
- cond,
19
- T,
20
- F,
21
- complement
22
- } = require('ramda')
1
+ import { skuFromItem } from './sku.js'
2
+ import { remaps } from './fromListingV1.js'
23
3
 
24
- const { skuFromItem } = require('./sku.js')
25
- const { remaps } = require('./fromListingV1.js')
4
+ const defindex = item => item.defindex
26
5
 
27
- const defindex = prop('defindex')
6
+ const quality = item => item?.quality?.id ?? null
28
7
 
29
- const quality = pathOr(null, ['quality', 'id'])
8
+ const uncraftable = item => item.name?.includes('Non-Craftable') ?? false
30
9
 
31
- const uncraftable = compose(includes('Non-Craftable'), prop('name'))
10
+ const effect = item => item?.particle?.id ?? null
32
11
 
33
- const effect = pathOr(null, ['particle', 'id'])
12
+ const elevated = item => (item?.quality?.id ?? null) === 11
13
+ ? ['701', '702', '703', '704'].includes(String(item?.particle?.id ?? null))
14
+ : (item?.elevatedQuality?.id ?? null) === 11
34
15
 
35
- const elevated = cond(
36
- [
37
- [compose(complement(equals)(11), quality), compose(equals(11), pathOr(null, ['elevatedQuality', 'id']))],
38
- [compose(equals(11), quality), compose(includes(__, ['701', '702', '703', '704']), String, effect)],
39
- [T, F]
40
- ]
41
- )
16
+ const killstreakTier = item => item.killstreakTier ?? null
42
17
 
43
- const killstreakTier = propOr(null, 'killstreakTier')
18
+ const festivized = item => item.festivized === true
44
19
 
45
- const festivized = propEq(true, 'festivized')
20
+ const texture = item => item?.texture?.id ?? null
46
21
 
47
- const texture = pathOr(null, ['texture', 'id'])
22
+ const wear = item => item?.wearTier?.id ?? null
48
23
 
49
- const wear = pathOr(null, ['wearTier', 'id'])
24
+ const australium = item => item.australium === true
50
25
 
51
- const australium = propEq(true, 'australium')
26
+ const series = item => item.crateSeries ?? null
52
27
 
53
- const series = propOr(null, 'crateSeries')
54
-
55
- const target = ifElse(
56
- allPass([
57
- pathEq(null, ['recipe', 'targetItem']),
58
- compose(equals(3), length, split('-'), prop('priceindex'))
59
- ]),
60
- compose(nth(2), split('-'), prop('priceindex')),
61
- pathOr(null, ['recipe', 'targetItem', '_source', 'defindex'])
62
- )
28
+ const target = item => {
29
+ const parts = (item.priceindex ?? '').split('-')
30
+ if (item?.recipe?.targetItem === null && parts.length === 3) {
31
+ return parts[2]
32
+ }
33
+ return item?.recipe?.targetItem?._source?.defindex ?? null
34
+ }
63
35
 
64
- const output = pathOr(null, ['recipe', 'outputItem', 'defindex'])
36
+ const output = item => item?.recipe?.outputItem?.defindex ?? null
65
37
 
66
- const oq = pathOr(null, ['recipe', 'outputItem', 'quality', 'id'])
38
+ const oq = item => item?.recipe?.outputItem?.quality?.id ?? null
67
39
 
68
40
  const fns = {
69
41
  defindex,
@@ -82,11 +54,7 @@ const fns = {
82
54
  oq
83
55
  }
84
56
 
85
- const fromListingV2 = compose(
86
- skuFromItem,
87
- remaps,
88
- map(__, fns),
89
- applyTo
90
- )
91
-
92
- module.exports = { fromListingV2 }
57
+ export function fromListingV2(item) {
58
+ const mapped = Object.fromEntries(Object.entries(fns).map(([k, fn]) => [k, fn(item)]))
59
+ return skuFromItem(remaps(mapped))
60
+ }
package/getCollections.js CHANGED
@@ -1,33 +1,17 @@
1
- const { prop, map, compose, toLower, mapObjIndexed, toPairs, when, has, __, chain, assoc, reduce, mergeRight, values, path, uncurryN, replace, mapKeys } = require('ramda')
1
+ export function getCollections(english, itemsGame) {
2
+ const collections = {}
3
+ for (const collection of Object.values(itemsGame.item_collections)) {
4
+ collections[collection.name.replace('#', '')] = collection
5
+ }
2
6
 
3
- const simplifyCollections = compose(
4
- reduce((curr, obj) => mergeRight(curr, obj), {}),
5
- values,
6
- mapObjIndexed(
7
- (collection, key) => map(assoc('collection', key), collection)
8
- ),
9
- map(
10
- compose(
11
- reduce((curr, obj) => mergeRight(curr, obj), {}),
12
- map(([rarity, items]) => map(() => ({ rarity }), items)),
13
- toPairs,
14
- prop('items')
15
- )
16
- ),
17
- (collections) => mapKeys((key) => replace('#', '', path([key, 'name'], collections)), collections),
18
- prop('item_collections')
19
- )
20
-
21
- const localizeCollections = uncurryN(2, (english) => map(
22
- when(
23
- compose(has(__, english), compose(toLower, prop('collection'))),
24
- chain(assoc('collection'), compose(prop(__, english), toLower, prop('collection')))
25
- )
26
- ))
27
-
28
- const getCollections = uncurryN(2, (english) => compose(
29
- localizeCollections(english),
30
- simplifyCollections
31
- ))
32
-
33
- module.exports = { getCollections }
7
+ const result = {}
8
+ for (const [collectionName, collection] of Object.entries(collections)) {
9
+ const localizedName = english[collectionName.toLowerCase()] ?? collectionName
10
+ for (const [rarity, items] of Object.entries(collection.items)) {
11
+ for (const key of Object.keys(items)) {
12
+ result[key] = { rarity, collection: localizedName }
13
+ }
14
+ }
15
+ }
16
+ return result
17
+ }
package/getItems.js CHANGED
@@ -1,42 +1,35 @@
1
- const { prop, map, compose, toLower, when, has, __, chain, assoc, reduce, omit, props, split, propOr, replace, mergeDeepLeft, mergeDeepWith } = require('ramda')
1
+ import { mergeDeepWith, mergeDeepRight } from './utils.js'
2
2
 
3
- function getItems(english, items_game) {
3
+ export function getItems(english, items_game) {
4
4
 
5
- var mergePrefab = (item) => mergeDeepLeft(
6
- omit(['prefab'], item),
7
- reduce(
8
- mergeDeepWith((p, n) => p + ' ' + n),
9
- {},
10
- props(split(' ', item.prefab), items_game.prefabs)
5
+ function mergePrefab(item) {
6
+ const prefabKeys = item.prefab.split(' ')
7
+ const prefabs = prefabKeys.map(k => items_game.prefabs[k]).filter(Boolean)
8
+ const mergedPrefabs = prefabs.reduce(
9
+ (acc, prefab) => mergeDeepWith((p, n) => p + ' ' + n, acc, prefab),
10
+ {}
11
11
  )
12
- )
13
-
14
- var mergePrefabs = when(
15
- has('prefab'),
16
- (a) => mergePrefabs(mergePrefab(a))
17
- )
18
-
19
- var localize = (key) => chain(
20
- assoc(key),
21
- compose(
22
- prop(__, english),
23
- replace('#', ''),
24
- toLower,
25
- propOr('NaN', key)
26
- )
27
- )
28
-
29
- const items = map(
30
- compose(
31
- localize('item_type_name'),
32
- localize('item_name'),
33
- mergePrefabs
34
- ),
35
- items_game.items
36
- )
37
-
38
- return items
12
+ const { prefab: _, ...rest } = item
13
+ return mergeDeepRight(mergedPrefabs, rest)
14
+ }
15
+
16
+ function mergePrefabs(item) {
17
+ if (!('prefab' in item)) return item
18
+ return mergePrefabs(mergePrefab(item))
19
+ }
20
+
21
+ function localize(item, key) {
22
+ const raw = (item[key] ?? 'NaN').toLowerCase().replace('#', '')
23
+ return { ...item, [key]: english[raw] }
24
+ }
25
+
26
+ const result = {}
27
+ for (const [defindex, item] of Object.entries(items_game.items)) {
28
+ let processed = mergePrefabs(item)
29
+ processed = localize(processed, 'item_name')
30
+ processed = localize(processed, 'item_type_name')
31
+ result[defindex] = processed
32
+ }
33
+ return result
39
34
 
40
35
  }
41
-
42
- module.exports = { getItems }