* Changes wordig for one vs two hand items (#120)

* [PoE2] - Rune type mod showing as "filters.tag_rune" instead of "RUNE" #108

* [PoE2] Missing Total / Elemental DPS on weapon #109

* [PoE2] no option to change from divine currency to exalt in price check #119

* Adds + to all ele res

* version bump

* also version bump
This commit is contained in:
Kvan7
2024-12-19 15:44:09 -06:00
committed by GitHub
parent 06be6dc2e0
commit c25192e6fe
19 changed files with 158 additions and 8340 deletions

View File

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

View File

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

View File

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

View File

@@ -131,7 +131,8 @@
"accessory_trinket": "Trinket",
"sanctum_relic": "Sanctum Relic",
"tincture": "Tincture",
"azmeri_charm": "Charm"
"azmeri_charm": "Charm",
"weapon_crossbow": "Crossbow"
},
"filters": {
"selected_some": "{0} of {1}, stats",
@@ -170,7 +171,8 @@
"tag_explicit_warlord": "Warlord",
"tag_explicit_delve": "Delve",
"tag_explicit_veiled": "Veiled",
"tag_explicit_incursion": "Incursion"
"tag_explicit_incursion": "Incursion",
"tag_rune": "Rune"
},
"online_filter": {
"offline_toggle": "Offline & Online",
@@ -185,7 +187,9 @@
"currency_any": "Any Currency",
"currency_only_chaos": "Chaos Orb",
"currency_only_div": "Divine Orb",
"currency_chaos_div": "Both Orbs"
"currency_chaos_div": "Both Orbs",
"currency_exalted_div": "Both Orbs",
"currency_only_exalted": "Exalted Orbs"
},
"widget": {
"title": "widget title",

View File

@@ -21,6 +21,9 @@ export default {
QUALITY: 'Quality: ',
PHYSICAL_DAMAGE: 'Physical Damage: ',
ELEMENTAL_DAMAGE: 'Elemental Damage: ',
LIGHTNING_DAMAGE: 'Lightning Damage: ',
COLD_DAMAGE: 'Cold Damage: ',
FIRE_DAMAGE: 'Fire Damage: ',
CRIT_CHANCE: 'Critical Strike Chance: ',
ATTACK_SPEED: 'Attacks per Second: ',
ARMOUR: 'Armour: ',

View File

@@ -1,6 +1,20 @@
{
"pseudo.pseudo_total_elemental_resistance": {
"filters": [
{
"id": "explicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "implicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "explicit.stat_3372524247",
"value": {
@@ -51,6 +65,20 @@
},
"pseudo.pseudo_total_resistance": {
"filters": [
{
"id": "explicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "implicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "explicit.stat_3372524247",
"value": {
@@ -115,6 +143,20 @@
},
"pseudo.pseudo_total_fire_resistance": {
"filters": [
{
"id": "explicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "implicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "explicit.stat_3372524247",
"value": {
@@ -137,6 +179,20 @@
},
"pseudo.pseudo_total_cold_resistance": {
"filters": [
{
"id": "explicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "implicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "explicit.stat_4220027924",
"value": {
@@ -159,6 +215,20 @@
},
"pseudo.pseudo_total_lightning_resistance": {
"filters": [
{
"id": "explicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "implicit.stat_2901986750",
"value": {
"weight": 1
},
"disabled": false
},
{
"id": "explicit.stat_1671376347",
"value": {

View File

@@ -190,6 +190,10 @@ export interface TranslationDict {
CHAT_WHISPER_TO: RegExp;
CHAT_WHISPER_FROM: RegExp;
CHAT_WEBTRADE_GEM: RegExp;
// ---
FIRE_DAMAGE: string;
LIGHTNING_DAMAGE: string;
COLD_DAMAGE: string;
}
export interface Filter {

View File

@@ -635,6 +635,60 @@ function parseWeapon(section: string[], item: ParsedItem) {
isParsed = "SECTION_PARSED";
continue;
}
if (line.startsWith(_$.FIRE_DAMAGE)) {
const fireDamage = line
.slice(_$.FIRE_DAMAGE.length)
.split(", ")
.map((element) =>
getRollOrMinmaxAvg(
element.split("-").map((str) => parseInt(str, 10)),
),
)
.reduce((sum, x) => sum + x, 0);
if (item.weaponELEMENTAL) {
item.weaponELEMENTAL = fireDamage + item.weaponELEMENTAL;
} else {
item.weaponELEMENTAL = fireDamage;
}
isParsed = "SECTION_PARSED";
continue;
}
if (line.startsWith(_$.COLD_DAMAGE)) {
const coldDamage = line
.slice(_$.COLD_DAMAGE.length)
.split(", ")
.map((element) =>
getRollOrMinmaxAvg(
element.split("-").map((str) => parseInt(str, 10)),
),
)
.reduce((sum, x) => sum + x, 0);
if (item.weaponELEMENTAL) {
item.weaponELEMENTAL = coldDamage + item.weaponELEMENTAL;
} else {
item.weaponELEMENTAL = coldDamage;
}
isParsed = "SECTION_PARSED";
continue;
}
if (line.startsWith(_$.LIGHTNING_DAMAGE)) {
const lightningDamage = line
.slice(_$.LIGHTNING_DAMAGE.length)
.split(", ")
.map((element) =>
getRollOrMinmaxAvg(
element.split("-").map((str) => parseInt(str, 10)),
),
)
.reduce((sum, x) => sum + x, 0);
if (item.weaponELEMENTAL) {
item.weaponELEMENTAL = lightningDamage + item.weaponELEMENTAL;
} else {
item.weaponELEMENTAL = lightningDamage;
}
isParsed = "SECTION_PARSED";
continue;
}
}
if (isParsed === "SECTION_PARSED") {

View File

@@ -1,323 +0,0 @@
{
"please_wait": "Please wait\u2026",
"choose_file": "Choose File",
"app_is_ready": "Is ready and running in background",
"reopen_settings": "Press {0} to continue editing.",
"seconds": "seconds",
"league": "League",
"realm": "Realm",
"realm_intl": "International",
"app": {
"leagues_loading": "Loading leagues\u2026",
"leagues_failed": "Failed to load leagues",
"leagues_failed_help": "Make sure the realm is not under maintenance. Also try clicking on the \"Browser\" button, you may need to complete a CAPTCHA there.",
"leagues_failed_help_alt": "Price check an Item, and follow the instructions in the error description there.",
"thanks_3rd_party": "This tool relies on {0} and {1}, consider supporting them as well",
"toggle_browser_hint": "Press {0} to switch between browser and game.",
"contact_me": "Contact me on one of the PoE Discords,",
"version": "Version {0}",
"release_notes": "Release notes",
"report_bug": "Report a bug on GitHub",
"quit": "Quit"
},
"map.mods.heist": "heist",
"map.mods.uber": "T17",
"map.mods.outdated": "outdated",
"Support development on": "Support development\u00A0on",
"Blighted": "Blighted",
"Blight-ravaged": "Blight-ravaged",
"Magic": "Magic",
"Shaper": "Shaper",
"Elder": "Elder",
"Crusader": "Crusader",
"Hunter": "Hunter",
"Redeemer": "Redeemer",
"Warlord": "Warlord",
"Superior": "Superior",
"Anomalous": "Anomalous",
"Divergent": "Divergent",
"Phantasmal": "Phantasmal",
"item": {
"prop_quality": "Q {0}%",
"base_percentile": "Base Percentile: {0}%",
"armour": "Armour: {0}",
"evasion_rating": "Evasion Rating: {0}",
"energy_shield": "Energy Shield: {0}",
"block": "Block: {0}%",
"total_dps": "Total DPS: {0}",
"physical_dps": "Physical DPS: {0}",
"elemental_dps": "Elemental DPS: {0}",
"crit": "Critical Strike Chance: {0}%",
"aps": "Attacks per Second: {0}",
"spirit": "Spirit: {0}",
"has_empty_modifier": "1 Empty or Crafted Modifier",
"has_empty_affix": "Any",
"has_empty_prefix": "Prefix",
"has_empty_suffix": "Suffix",
"item_level": "Item Level: {0}",
"stock": "Stock: {0}",
"map_tier": "Map Tier: {0}",
"area_level": "Area Level: {0}",
"heist_wings_revealed": "Wings Revealed: {0}",
"linked_sockets": "Links: {0}",
"white_sockets": "White: {0}",
"quality": "Quality: {0}",
"gem_level": "Level: {0}",
"gem_sockets": "Sockets: {0}",
"rune_sockets": "Sockets: {0}",
"sentinel_charge": "Charge: {0}",
"find_in_stash": "Find in Stash",
"parse_error": "An error occurred while parsing the item",
"parse_error_help": "This is probably a bug and you can report it on GitHub.",
"unknown": "Unknown Item",
"unknown_help": "If this Item was introduced in this League, it will likely be supported in the next app update.",
"identification": "You are trying to price check unidentified Unique item with base type \"{0}\". Which one?",
"open_on_wiki": "Open item on wiki",
"open_on_poedb": "Open item on PoEDB",
"info": "Item info",
"corrupted": "Corrupted",
"not_corrupted": "Not Corrupted",
"mod_tier": "Tier: {0}",
"mod_rank": "Rank: {0}",
"mod_pseudo": "Pseudo",
"mod_implicit": "Implicit",
"mod_fractured": "Fractured",
"mod_explicit": "Explicit",
"mod_crafted": "Crafted",
"mod_scourge": "Scourge",
"unidentified": "Unidentified",
"veiled": "Veiled",
"foil_unique": "Foil Unique",
"mirrored": "Mirrored",
"not_mirrored": "Not Mirrored"
},
"item_category": {
"prop": "Category: {0}",
"map": "Map",
"jewel_abyss": "Abyss Jewel",
"accessory_amulet": "Amulet",
"accessory_belt": "Belt",
"armour_chest": "Body Armour",
"armour_boots": "Boots",
"weapon_bow": "Bow",
"weapon_claw": "Claw",
"weapon_dagger": "Dagger",
"weapon_rod": "Fishing Rod",
"flask": "Flask",
"armour_gloves": "Gloves",
"armour_helmet": "Helmet",
"jewel": "Jewel",
"weapon_oneaxe": "One-Handed Axe",
"weapon_onemace": "One-Handed Mace",
"weapon_onesword": "One-Handed Sword",
"armour_quiver": "Quiver",
"accessory_ring": "Ring",
"weapon_runedagger": "Rune Dagger",
"weapon_sceptre": "Sceptre",
"armour_shield": "Shield",
"weapon_staff": "Staff",
"weapon_twoaxe": "Two-Handed Axe",
"weapon_twomace": "Two-Handed Mace",
"weapon_twosword": "Two-Handed Sword",
"weapon_wand": "Wand",
"weapon_warstaff": "Warstaff",
"jewel_cluster": "Cluster Jewel",
"heistmission_blueprint": "Heist Blueprint",
"heistmission_contract": "Heist Contract",
"heistequipment_heisttool": "Heist Tool",
"heistequipment_heistreward": "Heist Brooch",
"heistequipment_heistweapon": "Heist Gear",
"heistequipment_heistutility": "Heist Cloak",
"accessory_trinket": "Trinket",
"sanctum_relic": "Sanctum Relic",
"tincture": "Tincture",
"azmeri_charm": "Charm"
},
"filters": {
"selected_some": "{0} of {1}, stats",
"selected_none": "Stats ignored",
"hidden_toggle": "Hidden",
"collapse": "Collapse",
"mods_toggle": "Mods",
"empty": "No relevant stats were found",
"tier": "Tier {0}",
"preset_pseudo": "Pseudo",
"preset_base_item": "Base item",
"hide_const_roll": "Roll is not variable",
"hide_ele_dps": "Elemental damage is not the main source of DPS",
"hide_phys_dps": "Physical damage is not the main source of DPS",
"hide_ele_res": "Filtering by exact Elemental Resistance unreasonably increases the price",
"hide_crafted_chaos": "Crafted Chaos Resistance without Explicit mod has no value",
"hide_anointment": "Buyer will likely change anointment",
"hide_for_crafting": "Select only if price-checking as base item for crafting",
"hide_empty_mod": "Select only if item has 6 modifiers (1 of which is crafted) or if it has 5 modifiers",
"tag_implicit": "implicit",
"tag_fractured": "fractured",
"tag_crafted": "crafted",
"tag_scourge": "scourge",
"tag_enchant": "enchant",
"tag_variant": "variant",
"tag_corrupted": "corrupted",
"tag_synthesised": "synthesised",
"tag_eldritch": "eldritch",
"tag_pseudo": "pseudo",
"tag_explicit": "explicit",
"tag_explicit_shaper": "Shaper",
"tag_explicit_elder": "Elder",
"tag_explicit_crusader": "Crusader",
"tag_explicit_hunter": "Hunter",
"tag_explicit_redeemer": "Redeemer",
"tag_explicit_warlord": "Warlord",
"tag_explicit_delve": "Delve",
"tag_explicit_veiled": "Veiled",
"tag_explicit_incursion": "Incursion"
},
"online_filter": {
"offline_toggle": "Offline & Online",
"in_league_toggle": "In League",
"listed_any_time": "Listed: Any Time",
"listed_1day": "1 Day Ago",
"listed_3days": "3 Days Ago",
"listed_1week": "1 Week Ago",
"listed_2weeks": "2 Weeks Ago",
"listed_1month": "1 Month Ago",
"listed_2months": "2 Months Ago",
"currency_any": "Any Currency",
"currency_only_chaos": "Chaos Orb",
"currency_only_div": "Divine Orb",
"currency_chaos_div": "Both Orbs"
},
"widget": {
"title": "widget title",
"hide": "hide",
"edit": "edit",
"move": "move",
"delete": "delete"
},
"updates": {
"maybe_outdated": "You may have an outdated version",
"latest": "You have the latest version",
"error": "Error while checking for updates",
"checking": "Checking for updates",
"downloading": "Downloading\u2026",
"available": "Update available: {0}",
"never_checked": "Last checked: never",
"last_checked": "Last checked: {0}",
"check_now": "Check now",
"install_now": "Install now",
"downloads_page": "Open the Downloads page",
"installed_on_exit": "It will be installed automatically on exit",
"download_manually": "You can download it from GitHub",
"download_disabled": "You have disabled automatic updates download"
},
"widget_menu": {
"add": "add widget\u2026",
"always_show": "Show button for active widgets",
"price_check": "Price check (Ctrl + V)"
},
"stopwatch": {
"name": "Stopwatch",
"paused": "paused",
"toggle_key": "Start and Pause",
"reset_key": "Reset"
},
"stash_search": {
"enable_keys": "Keys",
"name": "Stash search",
"search_text": "search text or regex",
"friendly_name": "friendly name"
},
"image_strip": {
"name": "Image strip"
},
"item_search": {
"name": "Item search",
"input": "Search by name\u2026",
"reset": "Reset items",
"heist_target": "Heist target:",
"target_gem": "Skill Gem",
"target_replica": "Replicas",
"too_many": "Too many items found, enter the name more precisely.",
"not_found": "No items found.",
"ocr_gems_key": "Perform an OCR for a Skill Gem"
},
"map_check": {
"name": "Map check",
"has_outdated": "Wording of some stats has been changed. Check and update dangerous map mods in the settings. (This message will be hidden as soon as you remove all outdated stats)",
"no_mods": "Item has no modifiers.",
"profile": "Profile",
"search_selected": "Only selected",
"search_stat_col": "Stat (found: {0})",
"new_mods_icon": "Show icon for new mods"
},
"trade_result": {
"error": "Trade site request failed",
"matched": "Matched: {0}",
"trade": "Trade",
"price": "Price",
"bulk": "bulk",
"stock": "Stock",
"fulfill": "Fulfill",
"listed": "Listed",
"seller": "Seller",
"item_level": "iLvl",
"gem_level": "Level",
"quality": "Quality",
"base_item": "Base item",
"graph_7d": "Last 7 days",
"getting_price": "Getting price {0}",
"getting_price_from": "from poe.ninja \u2026",
"you_have": "You have",
"stack": "Stack"
},
"settings": {
"title": "Settings - Exiled Exchange 2",
"language": "Language",
"private_league": "or Private League",
"account_name": "Account name",
"last_char_name": "Last character name",
"chat_cmd_add": "Add command",
"chat_cmd_send": "press Enter",
"no_key": "Not Set",
"clear_hotkey": "You can clear hotkey by pressing Backspace",
"overlay": "Overlay",
"stash_scroll": "Stash tab scrolling",
"delve_grid": "Grid for Delve Chart",
"window_title": "PoE window title",
"thank_you": "App development continues thanks to:",
"hotkeys": "Hotkeys",
"chat": "Chat",
"general": "General",
"debug": "Debug",
"about": "About",
"font_size": "Font size",
"overlay_bg": "Background when the Overlay is clickable",
"overlay_bg_none": "Transparent",
"overlay_bg_focus_game": "Clicking on the background focuses the game",
"overlay_always_close": "Always fully close the overlay instead of hiding it",
"poe_log_file": "PoE log file",
"poe_cfg_file": "PoE config file",
"restore_clipboard": "Restore clipboard",
"show_overlay_ready": "Show a notification when the Overlay detects a PoE window",
"debug_hotkeys": "Record all key presses"
},
"price_check": {
"name": "Price check",
"hotkey": "Auto-hide Mode",
"hotkey_locked": "Open without auto-hide",
"enable_browser": "Enable builtin browser",
"builtin_browser_warning": "I am aware that future releases can potentially contain malicious code that can steal my POESESSID.",
"highlight_hint": "Your items will be highlighted even if this setting is off",
"show_seller": "Show seller",
"fill_rolls": "Fill stat values",
"fill_roll_exact": "Exact value",
"cursor_pos": "Show memorized cursor position",
"extra_delay": "Extra time to prevent spurious Rate limiting",
"warn_expensive": "Settings below are a compromise between increasing load on PoE website and convenient price checking / more accurate search.",
"accurate_collapsed": "Show indication on collapsed listings",
"auto_search": "Perform an auto search, when pressing",
"select_stock": "Always select \"Stock\" filter",
"show_prediction": "Show price prediction",
"remember_currency": "Remember the Buyout Currency filter"
}
}

View File

@@ -1,112 +0,0 @@
// @ts-check
/** @type{import('../../../src/assets/data/interfaces').TranslationDict} */
export default {
RARITY_NORMAL: 'Normal',
RARITY_MAGIC: 'Magic',
RARITY_RARE: 'Rare',
RARITY_UNIQUE: 'Unique',
RARITY_GEM: 'Gem',
RARITY_CURRENCY: 'Currency',
RARITY_DIVCARD: 'Divination Card',
RARITY_QUEST: 'Quest',
MAP_TIER: 'Map Tier: ',
RARITY: 'Rarity: ',
ITEM_CLASS: 'Item Class: ',
ITEM_LEVEL: 'Item Level: ',
CORPSE_LEVEL: 'Corpse Level: ',
TALISMAN_TIER: 'Talisman Tier: ',
GEM_LEVEL: 'Level: ',
STACK_SIZE: 'Stack Size: ',
SOCKETS: 'Sockets: ',
QUALITY: 'Quality: ',
PHYSICAL_DAMAGE: 'Physical Damage: ',
ELEMENTAL_DAMAGE: 'Elemental Damage: ',
CRIT_CHANCE: 'Critical Strike Chance: ',
ATTACK_SPEED: 'Attacks per Second: ',
ARMOUR: 'Armour: ',
EVASION: 'Evasion Rating: ',
ENERGY_SHIELD: 'Energy Shield: ',
BLOCK_CHANCE: 'Chance to Block: ',
CORRUPTED: 'Corrupted',
UNIDENTIFIED: 'Unidentified',
ITEM_SUPERIOR: /^Superior (.*)$/,
MAP_BLIGHTED: /^Blighted (.*)$/,
MAP_BLIGHT_RAVAGED: /^Blight-ravaged (.*)$/,
INFLUENCE_SHAPER: 'Shaper Item',
INFLUENCE_ELDER: 'Elder Item',
INFLUENCE_CRUSADER: 'Crusader Item',
INFLUENCE_HUNTER: 'Hunter Item',
INFLUENCE_REDEEMER: 'Redeemer Item',
INFLUENCE_WARLORD: 'Warlord Item',
SECTION_SYNTHESISED: 'Synthesised Item',
ITEM_SYNTHESISED: /^Synthesised (.*)$/,
VEILED_PREFIX: 'Veiled Prefix',
VEILED_SUFFIX: 'Veiled Suffix',
FLASK_CHARGES: /^Currently has \d+ Charges$/,
METAMORPH_HELP: "Combine this with four other different samples in Tane's Laboratory.",
BEAST_HELP: 'Right-click to add this to your bestiary.',
VOIDSTONE_HELP: 'Socket this into your Atlas to increase the Tier of all Maps.',
METAMORPH_BRAIN: /^.* Brain$/,
METAMORPH_EYE: /^.* Eye$/,
METAMORPH_LUNG: /^.* Lung$/,
METAMORPH_HEART: /^.* Heart$/,
METAMORPH_LIVER: /^.* Liver$/,
CANNOT_USE_ITEM: 'You cannot use this item. Its stats will be ignored',
QUALITY_ANOMALOUS: /^Anomalous (.*)$/,
QUALITY_DIVERGENT: /^Divergent (.*)$/,
QUALITY_PHANTASMAL: /^Phantasmal (.*)$/,
AREA_LEVEL: 'Area Level: ',
HEIST_WINGS_REVEALED: 'Wings Revealed: ',
HEIST_TARGET: 'Heist Target: ',
HEIST_BLUEPRINT_ENCHANTS: 'Enchanted Armaments',
HEIST_BLUEPRINT_TRINKETS: 'Thieves\' Trinkets or Currency',
HEIST_BLUEPRINT_GEMS: 'Unusual Gems',
HEIST_BLUEPRINT_REPLICAS: 'Replicas or Experimented Items',
MIRRORED: 'Mirrored',
MODIFIER_LINE: /^(?<type>[^"]+)(?:\s+"(?<name>[^"]+)")?(?:\s+\(Tier: (?<tier>\d+)\))?(?:\s+\(Rank: (?<rank>\d+)\))?$/,
PREFIX_MODIFIER: 'Prefix Modifier',
SUFFIX_MODIFIER: 'Suffix Modifier',
CRAFTED_PREFIX: 'Master Crafted Prefix Modifier',
CRAFTED_SUFFIX: 'Master Crafted Suffix Modifier',
UNSCALABLE_VALUE: ' — Unscalable Value',
CORRUPTED_IMPLICIT: 'Corruption Implicit Modifier',
MODIFIER_INCREASED: /^(.+?)% Increased$/,
INCURSION_OPEN: 'Open Rooms:',
INCURSION_OBSTRUCTED: 'Obstructed Rooms:',
EATER_IMPLICIT: /^Eater of Worlds Implicit Modifier \((?<rank>.+)\)$/,
EXARCH_IMPLICIT: /^Searing Exarch Implicit Modifier \((?<rank>.+)\)$/,
ELDRITCH_MOD_R1: 'Lesser',
ELDRITCH_MOD_R2: 'Greater',
ELDRITCH_MOD_R3: 'Grand',
ELDRITCH_MOD_R4: 'Exceptional',
ELDRITCH_MOD_R5: 'Exquisite',
ELDRITCH_MOD_R6: 'Perfect',
SENTINEL_CHARGE: 'Charge: ',
SHAPER_MODS: ['of Shaping', "The Shaper's"],
ELDER_MODS: ['of the Elder', "The Elder's"],
CRUSADER_MODS: ["Crusader's", 'of the Crusade'],
HUNTER_MODS: ["Hunter's", 'of the Hunt'],
REDEEMER_MODS: ['of Redemption', "Redeemer's"],
WARLORD_MODS: ["Warlord's", 'of the Conquest'],
DELVE_MODS: ['Subterranean', 'of the Underground'],
VEILED_MODS: ['Chosen', 'of the Order'],
INCURSION_MODS: ["Guatelitzi's", "Xopec's", "Topotante's", "Tacati's", "Matatl's", 'of Matatl', "Citaqualotl's", 'of Citaqualotl', 'of Tacati', 'of Guatelitzi', 'of Puhuarte'],
FOIL_UNIQUE: 'Foil Unique',
UNMODIFIABLE: 'Unmodifiable',
// ---
CHAT_SYSTEM: /^: (?<body>.+)$/,
CHAT_TRADE: /^\$(?:<(?<guild_tag>.+?)> )?(?<char_name>.+?): (?<body>.+)$/,
CHAT_GLOBAL: /^#(?:<(?<guild_tag>.+?)> )?(?<char_name>.+?): (?<body>.+)$/,
CHAT_PARTY: /^%(?:<(?<guild_tag>.+?)> )?(?<char_name>.+?): (?<body>.+)$/,
CHAT_GUILD: /^&(?:<(?<guild_tag>.+?)> )?(?<char_name>.+?): (?<body>.+)$/,
CHAT_WHISPER_TO: /^@To (?<char_name>.+?): (?<body>.+)$/,
CHAT_WHISPER_FROM: /^@From (?:<(?<guild_tag>.+?)> )?(?<char_name>.+?): (?<body>.+)$/,
CHAT_WEBTRADE_GEM: /^level (?<gem_lvl>\d+) (?<gem_qual>\d+)% (?<gem_name>.+)$/,
REQUIREMENTS: 'Requirements',
CHARM_SLOTS: 'Charm Slots:',
BASE_SPIRIT: 'Spirit:',
QUIVER_HELP_TEXT: 'Can only be equipped',
FLASK_HELP_TEXT: 'Right click to drink.',
CHARM_HELP_TEXT: 'Used automatically when condition'
}

View File

@@ -1,187 +0,0 @@
import type { ItemCategory } from "@/parser";
export interface StatMatcher {
string: string;
advanced?: string;
negate?: true;
value?: number;
oils?: string; // Amulet anointment
}
export enum StatBetter {
NegativeRoll = -1,
PositiveRoll = 1,
NotComparable = 0,
}
export interface Stat {
ref: string;
dp?: true;
matchers: StatMatcher[];
better: StatBetter;
fromAreaMods?: true;
fromUberAreaMods?: true;
fromHeistAreaMods?: true;
anointments?: Array<{ roll: number; oils: string }>; // Ring anointments
trade: {
inverted?: true;
option?: true;
ids: {
[type: string]: string[];
};
};
}
export interface DropEntry {
query: string[];
items: string[];
}
export interface BaseType {
name: string;
refName: string;
namespace: "DIVINATION_CARD" | "CAPTURED_BEAST" | "UNIQUE" | "ITEM" | "GEM";
icon: string;
w?: number;
h?: number;
tradeTag?: string;
tradeDisc?: string;
disc?: {
propAR?: true;
propEV?: true;
propES?: true;
hasImplicit?: { ref: Stat["ref"] };
hasExplicit?: { ref: Stat["ref"] };
sectionText?: string;
mapTier?: "W" | "Y" | "R";
};
// extra info
craftable?: {
category: ItemCategory;
corrupted?: true;
uniqueOnly?: true;
};
unique?: {
base: BaseType["refName"];
fixedStats?: Array<Stat["ref"]>;
};
map?: {
screenshot?: string;
};
gem?: {
vaal?: true;
awakened?: true;
transfigured?: true;
normalVariant?: BaseType["refName"];
};
armour?: {
ar?: [min: number, max: number];
ev?: [min: number, max: number];
es?: [min: number, max: number];
};
}
export interface TranslationDict {
RARITY_NORMAL: string;
RARITY_MAGIC: string;
RARITY_RARE: string;
RARITY_UNIQUE: string;
RARITY_GEM: string;
RARITY_CURRENCY: string;
RARITY_DIVCARD: string;
RARITY_QUEST: string;
MAP_TIER: string;
RARITY: string;
ITEM_CLASS: string;
ITEM_LEVEL: string;
CORPSE_LEVEL: string;
TALISMAN_TIER: string;
GEM_LEVEL: string;
STACK_SIZE: string;
SOCKETS: string;
QUALITY: string;
PHYSICAL_DAMAGE: string;
ELEMENTAL_DAMAGE: string;
CRIT_CHANCE: string;
ATTACK_SPEED: string;
ARMOUR: string;
EVASION: string;
ENERGY_SHIELD: string;
BLOCK_CHANCE: string;
CORRUPTED: string;
UNIDENTIFIED: string;
ITEM_SUPERIOR: RegExp;
MAP_BLIGHTED: RegExp;
MAP_BLIGHT_RAVAGED: RegExp;
INFLUENCE_SHAPER: string;
INFLUENCE_ELDER: string;
INFLUENCE_CRUSADER: string;
INFLUENCE_HUNTER: string;
INFLUENCE_REDEEMER: string;
INFLUENCE_WARLORD: string;
SECTION_SYNTHESISED: string;
ITEM_SYNTHESISED: RegExp;
VEILED_PREFIX: string;
VEILED_SUFFIX: string;
FLASK_CHARGES: RegExp;
METAMORPH_HELP: string;
BEAST_HELP: string;
VOIDSTONE_HELP: string;
METAMORPH_BRAIN: RegExp;
METAMORPH_EYE: RegExp;
METAMORPH_LUNG: RegExp;
METAMORPH_HEART: RegExp;
METAMORPH_LIVER: RegExp;
CANNOT_USE_ITEM: string;
QUALITY_ANOMALOUS: RegExp;
QUALITY_DIVERGENT: RegExp;
QUALITY_PHANTASMAL: RegExp;
AREA_LEVEL: string;
HEIST_WINGS_REVEALED: string;
HEIST_TARGET: string;
HEIST_BLUEPRINT_ENCHANTS: string;
HEIST_BLUEPRINT_TRINKETS: string;
HEIST_BLUEPRINT_GEMS: string;
HEIST_BLUEPRINT_REPLICAS: string;
MIRRORED: string;
MODIFIER_LINE: RegExp;
PREFIX_MODIFIER: string;
SUFFIX_MODIFIER: string;
CRAFTED_PREFIX: string;
CRAFTED_SUFFIX: string;
UNSCALABLE_VALUE: string;
CORRUPTED_IMPLICIT: string;
MODIFIER_INCREASED: RegExp;
INCURSION_OPEN: string;
INCURSION_OBSTRUCTED: string;
EATER_IMPLICIT: RegExp;
EXARCH_IMPLICIT: RegExp;
ELDRITCH_MOD_R1: string;
ELDRITCH_MOD_R2: string;
ELDRITCH_MOD_R3: string;
ELDRITCH_MOD_R4: string;
ELDRITCH_MOD_R5: string;
ELDRITCH_MOD_R6: string;
SENTINEL_CHARGE: string;
SHAPER_MODS: string[];
ELDER_MODS: string[];
CRUSADER_MODS: string[];
HUNTER_MODS: string[];
REDEEMER_MODS: string[];
WARLORD_MODS: string[];
DELVE_MODS: string[];
VEILED_MODS: string[];
INCURSION_MODS: string[];
FOIL_UNIQUE: string;
UNMODIFIABLE: string;
REQUIREMENTS: string;
// ---
CHAT_SYSTEM: RegExp;
CHAT_TRADE: RegExp;
CHAT_GLOBAL: RegExp;
CHAT_PARTY: RegExp;
CHAT_GUILD: RegExp;
CHAT_WHISPER_TO: RegExp;
CHAT_WHISPER_FROM: RegExp;
CHAT_WEBTRADE_GEM: RegExp;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,191 +0,0 @@
[
{"from": "A. Førde", "months": 3, "style": 1},
{"from": "A. Koenig", "months": 1, "style": 1},
{"from": "A. Logos", "months": 20, "style": 2},
{"from": "A. Miller", "months": 11, "style": 1},
{"from": "A. Nakarada", "months": 7, "style": 2},
{"from": "A. Robinson", "months": 7, "style": 3},
{"from": "A. West", "months": 27, "style": 3},
{"from": "A. Zastre", "months": 5, "style": 1},
{"from": "AbedNego", "months": 6, "style": 1},
{"from": "aikodz", "months": 3, "style": 1},
{"from": "Andrew S", "months": 1, "style": 1},
{"from": "angrymouse", "months": 6, "style": 1},
{"from": "aNitMotD", "months": 2, "style": 3},
{"from": "applejacked", "months": 20, "style": 2},
{"from": "Arte Lope", "months": 17, "style": 2},
{"from": "Askanor", "months": 1, "style": 1},
{"from": "Athena", "months": 10, "style": 3},
{"from": "AZ", "months": 3, "style": 1},
{"from": "B. Maszlag", "months": 16, "style": 2},
{"from": "B. Stone", "months": 1, "style": 1},
{"from": "B3ginner", "months": 1, "style": 1},
{"from": "Baang", "months": 35, "style": 5},
{"from": "bashcoder", "months": 4, "style": 1},
{"from": "BearsInTheSky", "months": 1, "style": 1},
{"from": "Bjoern B.", "months": 4, "style": 1},
{"from": "Brotango", "months": 3, "style": 1},
{"from": "Budget Boudica", "months": 23, "style": 3},
{"from": "C. Niemeier", "months": 10, "style": 2},
{"from": "C. Szilagy", "months": 15, "style": 2},
{"from": "C.M. Tolman", "months": 4, "style": 2},
{"from": "Calyx", "months": 36, "style": 5},
{"from": "camenre", "months": 2, "style": 1},
{"from": "Chee", "months": 2, "style": 1},
{"from": "clopnaz", "months": 3, "style": 1},
{"from": "Cod Smack", "months": 28, "style": 3},
{"from": "Coolulder", "months": 42, "style": 5},
{"from": "Cry0nicS", "months": 1, "style": 1},
{"from": "cuinhellcat", "months": 2, "style": 1},
{"from": "CysDg", "months": 1, "style": 1},
{"from": "D. Bryan", "months": 2, "style": 1},
{"from": "D. Ivanov", "months": 16, "style": 4},
{"from": "D. Paulino", "months": 30, "style": 5},
{"from": "D. Ward", "months": 8, "style": 2},
{"from": "d0mEsPLiTa", "months": 12, "style": 3},
{"from": "Dadaless", "months": 4, "style": 1},
{"from": "Dante M.", "months": 27, "style": 4},
{"from": "Darkscion", "months": 1, "style": 1},
{"from": "deeray", "months": 38, "style": 3},
{"from": "delasteve", "months": 1, "style": 2},
{"from": "digininja", "months": 39, "style": 3},
{"from": "dreamweaverkara", "months": 4, "style": 2},
{"from": "DTauro", "months": 6, "style": 1},
{"from": "Dvoth", "months": 3, "style": 1},
{"from": "E. Giegerich", "months": 2, "style": 1},
{"from": "E. Manhattan", "months": 12, "style": 2},
{"from": "E. Troyak", "months": 4, "style": 3},
{"from": "Ellendar", "months": 45, "style": 5},
{"from": "EllieJelly", "months": 38, "style": 4},
{"from": "facemask12", "months": 4, "style": 2},
{"from": "FARIS2", "months": 4, "style": 2},
{"from": "frsm", "months": 37, "style": 3},
{"from": "gamingrobot", "months": 9, "style": 2},
{"from": "Gdubz", "months": 4, "style": 3},
{"from": "GRIMGeek", "months": 37, "style": 3},
{"from": "Grotok", "months": 19, "style": 3},
{"from": "gurthymyco", "months": 1, "style": 1},
{"from": "haliun", "months": 7, "style": 3},
{"from": "Harometras", "months": 3, "style": 1},
{"from": "Heikki", "months": 34, "style": 3},
{"from": "Holonaut", "months": 7, "style": 2},
{"from": "HOOSIER", "months": 21, "style": 2},
{"from": "Horstusius", "months": 8, "style": 2},
{"from": "hyronimus84", "months": 1, "style": 1},
{"from": "imaapty", "months": 4, "style": 2},
{"from": "iqdrive", "months": 2, "style": 1},
{"from": "J. Harmer", "months": 10, "style": 2},
{"from": "J. Krzeminski", "months": 14, "style": 2},
{"from": "J. Madill", "months": 19, "style": 2},
{"from": "J. Müller", "months": 26, "style": 3},
{"from": "J. Pollard", "months": 4, "style": 1},
{"from": "J. Porter", "months": 35, "style": 3},
{"from": "J. Rapp", "months": 23, "style": 3},
{"from": "J. Reed", "months": 6, "style": 2},
{"from": "J. Stratmann", "months": 43, "style": 3},
{"from": "J. Wiegand", "months": 10, "style": 3},
{"from": "jerbear_pnw", "months": 14, "style": 4},
{"from": "Jordan", "months": 1, "style": 1},
{"from": "JoyFired", "months": 7, "style": 1},
{"from": "JP Bagdonas", "months": 8, "style": 3},
{"from": "Jr Honorio", "months": 5, "style": 2},
{"from": "K_fudge", "months": 1, "style": 2},
{"from": "K. Hafenscher", "months": 26, "style": 4},
{"from": "K. Hardy", "months": 4, "style": 4},
{"from": "K. Kaptur", "months": 8, "style": 1},
{"from": "K. Mohin", "months": 1, "style": 1},
{"from": "KhaozNZ", "months": 5, "style": 1},
{"from": "khay", "months": 20, "style": 2},
{"from": "Kloozy", "months": 6, "style": 1},
{"from": "kmalex4", "months": 33, "style": 3},
{"from": "kruderf", "months": 1, "style": 1},
{"from": "L. Chien", "months": 12, "style": 3},
{"from": "L. Kelly", "months": 8, "style": 2},
{"from": "L. MacNeil", "months": 32, "style": 5},
{"from": "L. Sampaio Dias", "months": 2, "style": 1},
{"from": "lecruz01", "months": 2, "style": 1},
{"from": "Lendoria", "months": 22, "style": 4},
{"from": "livejamie", "months": 26, "style": 2},
{"from": "lord_lengl", "months": 2, "style": 1},
{"from": "Lordius", "months": 1, "style": 1},
{"from": "louislo", "months": 6, "style": 1},
{"from": "Ludion R", "months": 3, "style": 1},
{"from": "M. Aldous", "months": 30, "style": 3},
{"from": "M. Kimble", "months": 34, "style": 4},
{"from": "M. Lopez", "months": 10, "style": 3},
{"from": "martin1*5", "months": 12, "style": 3},
{"from": "Max10969", "months": 16, "style": 3},
{"from": "Melu", "months": 1, "style": 1},
{"from": "Mike", "months": 6, "style": 2},
{"from": "MiksLynx", "months": 14, "style": 2},
{"from": "Mindfire", "months": 2, "style": 1},
{"from": "mmastrocinque", "months": 11, "style": 2},
{"from": "Mr. Ozarka", "months": 10, "style": 2},
{"from": "N. Baldwin", "months": 23, "style": 4},
{"from": "N. Juretic", "months": 15, "style": 4},
{"from": "N. Pawlawski", "months": 3, "style": 1},
{"from": "N. Sabin", "months": 1, "style": 1},
{"from": "Nakoma", "months": 2, "style": 1},
{"from": "ninni", "months": 12, "style": 2},
{"from": "nipser", "months": 3, "style": 1},
{"from": "P. Pandian", "months": 8, "style": 3},
{"from": "P. Roeper", "months": 26, "style": 3},
{"from": "Pieman807", "months": 12, "style": 3},
{"from": "Praestrom", "months": 2, "style": 1},
{"from": "Quezion", "months": 29, "style": 4},
{"from": "R. Chow", "months": 40, "style": 3},
{"from": "R. Fidel", "months": 14, "style": 4},
{"from": "R. Klippert", "months": 26, "style": 3},
{"from": "R. Meliksetyan", "months": 1, "style": 1},
{"from": "R. Myers", "months": 1, "style": 1},
{"from": "Rafnak", "months": 3, "style": 1},
{"from": "roxzin", "months": 4, "style": 1},
{"from": "Rutschi", "months": 4, "style": 2},
{"from": "rw", "months": 31, "style": 4},
{"from": "Ryndaar", "months": 2, "style": 1},
{"from": "S. Barton", "months": 20, "style": 3},
{"from": "S. Bejan", "months": 16, "style": 2},
{"from": "S. Goozey", "months": 25, "style": 2},
{"from": "S. Jones", "months": 8, "style": 2},
{"from": "Sanii", "months": 35, "style": 5},
{"from": "SasQ", "months": 1, "style": 1},
{"from": "Secret Wizard", "months": 6, "style": 2},
{"from": "Seppi", "months": 1, "style": 1},
{"from": "sergeantglasc", "months": 1, "style": 1},
{"from": "smartmusic", "months": 2, "style": 1},
{"from": "smifli", "months": 3, "style": 2},
{"from": "sn0cr4sh", "months": 31, "style": 4},
{"from": "snape3619", "months": 3, "style": 1},
{"from": "Solaarian", "months": 15, "style": 2},
{"from": "Splat", "months": 7, "style": 1},
{"from": "stark4machines", "months": 13, "style": 2},
{"from": "Steve O.", "months": 6, "style": 1},
{"from": "StrangerKill", "months": 29, "style": 3},
{"from": "Sy", "months": 23, "style": 2},
{"from": "sycofly", "months": 14, "style": 2},
{"from": "symphony", "months": 20, "style": 2},
{"from": "T. Boone", "months": 3, "style": 1},
{"from": "T. Pluta", "months": 16, "style": 3},
{"from": "T. Rayne", "months": 3, "style": 1},
{"from": "T. Trav", "months": 15, "style": 4},
{"from": "Tactical96", "months": 2, "style": 1},
{"from": "TH", "months": 11, "style": 1},
{"from": "ThatGuyWasTaken", "months": 38, "style": 5},
{"from": "TheDriveHome", "months": 31, "style": 4},
{"from": "tony", "months": 1, "style": 1},
{"from": "Traceur", "months": 11, "style": 3},
{"from": "turmalin", "months": 4, "style": 2},
{"from": "V. Chernenko", "months": 2, "style": 1},
{"from": "Vandi", "months": 30, "style": 3},
{"from": "vervalsen", "months": 1, "style": 1},
{"from": "vii", "months": 13, "style": 4},
{"from": "Vindexus", "months": 6, "style": 2},
{"from": "vivi", "months": 3, "style": 1},
{"from": "Vulinux", "months": 4, "style": 1},
{"from": "W. Milas", "months": 42, "style": 4},
{"from": "Washclof", "months": 4, "style": 1},
{"from": "Wiggles", "months": 21, "style": 4},
{"from": "Zach H", "months": 11, "style": 5},
{"from": "Zigra", "months": 4, "style": 2},
{"from": "zlajo", "months": 8, "style": 1}
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,253 +0,0 @@
import fnv1a from "@sindresorhus/fnv1a";
import type {
BaseType,
DropEntry,
Stat,
StatMatcher,
TranslationDict,
} from "./interfaces";
import path from "path";
import fs from "fs";
export * from "./interfaces";
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 ITEM_BY_TRANSLATED = (
ns: BaseType["namespace"],
name: string,
): BaseType[] | undefined => undefined;
export let ITEM_BY_REF = (
ns: BaseType["namespace"],
name: string,
): BaseType[] | undefined => undefined;
export let ITEMS_ITERATOR = function* (
includes: string,
andIncludes?: string[],
): Generator<BaseType> {};
export let ALTQ_GEM_NAMES = function* (): Generator<string> {};
export let REPLICA_UNIQUE_NAMES = function* (): Generator<string> {};
export let STAT_BY_MATCH_STR = (
name: string,
): { matcher: StatMatcher; stat: Stat } | undefined => undefined;
export let STAT_BY_REF = (name: string): Stat | undefined => undefined;
export let STATS_ITERATOR = function* (
includes: string,
andIncludes?: string[],
): Generator<Stat> {};
function dataBinarySearch(
data: Uint32Array,
value: number,
rowOffset: number,
rowSize: number,
) {
let left = 0;
let right = data.length / rowSize - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const midValue = data[mid * rowSize + rowOffset];
if (midValue < value) {
left = mid + 1;
} else if (midValue > value) {
right = mid - 1;
} else {
return mid;
}
}
return -1;
}
function ndjsonFindLines<T>(ndjson: string) {
// it's preferable that passed `searchString` has good entropy
return function* (
searchString: string,
andIncludes: string[] = [],
): Generator<T> {
let start = 0;
while (start !== ndjson.length) {
const matchPos = ndjson.indexOf(searchString, start);
if (matchPos === -1) break;
// works for first line too (-1 + 1 = 0)
start = ndjson.lastIndexOf("\n", matchPos) + 1;
const end = ndjson.indexOf("\n", matchPos);
const jsonLine = ndjson.slice(start, end);
if (andIncludes.every((str) => jsonLine.includes(str))) {
yield JSON.parse(jsonLine) as T;
}
start = end + 1;
}
};
}
function itemNamesFromLines(items: Generator<BaseType>) {
let cached = "";
return function* (): Generator<string> {
if (!cached.length) {
for (const item of items) {
cached += item.name + "\n";
}
}
let start = 0;
while (start !== cached.length) {
const end = cached.indexOf("\n", start);
yield cached.slice(start, end);
start = end + 1;
}
};
}
async function loadItems(language: string) {
const ndjson = fs.readFileSync(
path.resolve(__dirname, `./items.ndjson`),
"utf-8",
);
const INDEX_WIDTH = 2;
const indexNames = new Uint32Array(
fs.readFileSync(path.resolve(__dirname, `./items-name.index.bin`)).buffer,
);
const indexRefNames = new Uint32Array(
fs.readFileSync(path.resolve(__dirname, `./items-ref.index.bin`)).buffer,
);
function commonFind(index: Uint32Array, prop: "name" | "refName") {
return function (
ns: BaseType["namespace"],
name: string,
): BaseType[] | undefined {
let start = dataBinarySearch(
index,
Number(fnv1a(`${ns}::${name}`, { size: 32 })),
0,
INDEX_WIDTH,
);
if (start === -1) return undefined;
start = index[start * INDEX_WIDTH + 1];
const out: BaseType[] = [];
while (start !== ndjson.length) {
const end = ndjson.indexOf("\n", start);
const record = JSON.parse(ndjson.slice(start, end)) as BaseType;
if (record.namespace === ns && record[prop] === name) {
out.push(record);
if (!record.disc && !record.unique) break;
} else {
break;
}
start = end + 1;
}
return out;
};
}
ITEM_BY_TRANSLATED = commonFind(indexNames, "name");
ITEM_BY_REF = commonFind(indexRefNames, "refName");
ITEMS_ITERATOR = ndjsonFindLines<BaseType>(ndjson);
ALTQ_GEM_NAMES = itemNamesFromLines(
ITEMS_ITERATOR('altQuality":["Anomalous'),
);
REPLICA_UNIQUE_NAMES = itemNamesFromLines(
ITEMS_ITERATOR('refName":"Replica'),
);
}
async function loadStats(language: string) {
const ndjson = fs.readFileSync(
path.resolve(__dirname, `./stats.ndjson`),
"utf-8",
);
const INDEX_WIDTH = 2;
const indexRef = new Uint32Array(
fs.readFileSync(path.resolve(__dirname, `./stats-ref.index.bin`)).buffer,
);
const indexMatcher = new Uint32Array(
fs.readFileSync(
path.resolve(__dirname, `./stats-matcher.index.bin`),
).buffer,
);
STAT_BY_REF = function (ref: string) {
let start = dataBinarySearch(
indexRef,
Number(fnv1a(ref, { size: 32 })),
0,
INDEX_WIDTH,
);
if (start === -1) return undefined;
start = indexRef[start * INDEX_WIDTH + 1];
const end = ndjson.indexOf("\n", start);
return JSON.parse(ndjson.slice(start, end));
};
STAT_BY_MATCH_STR = function (matchStr: string) {
let start = dataBinarySearch(
indexMatcher,
Number(fnv1a(matchStr, { size: 32 })),
0,
INDEX_WIDTH,
);
if (start === -1) return undefined;
start = indexMatcher[start * INDEX_WIDTH + 1];
const end = ndjson.indexOf("\n", start);
const stat = JSON.parse(ndjson.slice(start, end)) as Stat;
const matcher = stat.matchers.find(
(m) => m.string === matchStr || m.advanced === matchStr,
);
if (!matcher) {
// console.log('fnv1a32 collision')
return undefined;
}
return { stat, matcher };
};
STATS_ITERATOR = ndjsonFindLines<Stat>(ndjson);
}
// assertion, to avoid regressions in stats.ndjson
const DELAYED_STAT_VALIDATION = new Set<string>();
export function stat(text: string) {
DELAYED_STAT_VALIDATION.add(text);
return text;
}
export async function init(lang: string) {
CLIENT_STRINGS_REF = (await import("./client_strings.js")).default;
ITEM_DROP = JSON.parse(
fs.readFileSync(path.resolve(__dirname, `./item-drop.json`), "utf-8"),
) as DropEntry[];
APP_PATRONS = JSON.parse(
fs.readFileSync(path.resolve(__dirname, `./patrons.json`), "utf-8"),
) as Array<{ from: string; months: number; style: number }>;
await loadForLang(lang);
let failed = false;
const missing = [];
for (const text of DELAYED_STAT_VALIDATION) {
if (STAT_BY_REF(text) == null) {
// throw new Error(`Cannot find stat: ${text}`);
missing.push(text);
failed = true;
}
}
if (failed) {
throw new Error(
`Cannot find stat${missing.length > 1 ? "s" : ""}: ${missing.join("\n")}`,
);
}
DELAYED_STAT_VALIDATION.clear();
}
export async function loadForLang(lang: string) {
CLIENT_STRINGS = (await import("./client_strings.js")).default;
await loadItems(lang);
await loadStats(lang);
}

View File

@@ -23,12 +23,12 @@ export enum ItemCategory {
Warstaff = "Warstaff",
Dagger = "Dagger",
RuneDagger = "Rune Dagger",
OneHandedAxe = "One-Handed Axe",
TwoHandedAxe = "Two-Handed Axe",
OneHandedMace = "One-Handed Mace",
TwoHandedMace = "Two-Handed Mace",
OneHandedSword = "One-Handed Sword",
TwoHandedSword = "Two-Handed Sword",
OneHandedAxe = "One Hand Axe",
TwoHandedAxe = "Two Hand Axe",
OneHandedMace = "One Hand Mace",
TwoHandedMace = "Two Hand Mace",
OneHandedSword = "One Hand Sword",
TwoHandedSword = "Two Hand Sword",
ClusterJewel = "Cluster Jewel",
HeistBlueprint = "Heist Blueprint",
HeistContract = "Heist Contract",

View File

@@ -4,7 +4,8 @@ import { AppConfig } from "@/web/Config";
// pc-ggg, pc-garena
// const PERMANENT_SC = ['Standard', '標準模式']
const PERMANENT_HC = ["Hardcore", "專家模式"];
// const PERMANENT_HC = ["Hardcore", "專家模式"];
const PERMANENT_HC: string[] = [];
interface ApiLeague {
id: string;

View File

@@ -72,15 +72,18 @@
:value="undefined"
>{{ t(":currency_any") }}</ui-radio
>
<ui-radio v-model="filters.trade.currency" value="chaos">{{
t(":currency_only_chaos")
<ui-radio v-model="filters.trade.currency" value="exalted">{{
t(":currency_only_exalted")
}}</ui-radio>
<!-- <ui-radio v-model="filters.trade.currency" value="chaos">{{
t(":currency_only_chaos")
}}</ui-radio> -->
<ui-radio v-model="filters.trade.currency" value="divine">{{
t(":currency_only_div")
}}</ui-radio>
<ui-radio v-model="filters.trade.currency" value="chaos_divine">{{
t(":currency_chaos_div")
}}</ui-radio>
<!-- <ui-radio v-model="filters.trade.currency" value="exalted_divine">{{
t(":currency_exalted_div")
}}</ui-radio> -->
</template>
</div>
</div>