From d95409026fde2c659189c4ff5d7db5bee6cfa889 Mon Sep 17 00:00:00 2001 From: GaboGG Date: Mon, 27 Jul 2026 15:51:22 -0400 Subject: [PATCH] v0.14.15 - Retry gear scrape until dynjs_equip store loads - equip-UID.js loads asynchonously after document-end, so dynjs_equip might not exist when init() first runs - Now retries up to 10 times (500ms apart, 5 seconds total) waiting for the store to populate before scraping - Added HV.gearStore() to check whether the store is loaded - If store never loads, falls back to name/ID scrape without stats --- scripts/hv-unified.user.js | 22 +++++++++++++++++++--- scripts/latest.user.js | 22 +++++++++++++++++++--- src/config.js | 2 +- src/header.user.js | 2 +- src/init.js | 17 ++++++++++++++++- src/public-api.js | 1 + 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/scripts/hv-unified.user.js b/scripts/hv-unified.user.js index 3a488c2..4d16e6a 100644 --- a/scripts/hv-unified.user.js +++ b/scripts/hv-unified.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.14.14 +// @version 0.14.15 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -17,7 +17,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.14.14'; +const VERSION = '0.14.15'; const CFG = { // — Battle automation @@ -3805,6 +3805,7 @@ window.HV = { gearSummary: () => logGearSummary(), scrapeGear: () => autoScrapeGear(), gearDebug: () => debugScrapeGear(), + gearStore: () => { const s = getHVEquipStore(); return s ? `Loaded: ${Object.keys(s).length} items` : 'Not loaded yet'; }, }; // ═══════════════════════════════════════════════════════════════════════ @@ -3912,9 +3913,24 @@ function initializeBattle() { } // Auto-scrape gear data on character/armory pages (reads from HV's in-memory store) + // Wait for dynjs_equip to load (external script, may load after document-end) const url = window.location.href || ''; if (url.includes('ss=eq') || url.includes('ss=ch') || url.includes('ss=am')) { - setTimeout(autoScrapeGear, 300); + let attempts = 0; + const tryScrape = () => { + const store = getHVEquipStore(); + if (store && Object.keys(store).length > 0) { + autoScrapeGear(); + return; + } + if (++attempts < 10) { + setTimeout(tryScrape, 500); // retry every 500ms up to 5 seconds + } else { + // Fallback: scrape names/IDs without stats + autoScrapeGear(); + } + }; + setTimeout(tryScrape, 300); } STATE.battleInitialized = true; diff --git a/scripts/latest.user.js b/scripts/latest.user.js index 3a488c2..4d16e6a 100644 --- a/scripts/latest.user.js +++ b/scripts/latest.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.14.14 +// @version 0.14.15 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -17,7 +17,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.14.14'; +const VERSION = '0.14.15'; const CFG = { // — Battle automation @@ -3805,6 +3805,7 @@ window.HV = { gearSummary: () => logGearSummary(), scrapeGear: () => autoScrapeGear(), gearDebug: () => debugScrapeGear(), + gearStore: () => { const s = getHVEquipStore(); return s ? `Loaded: ${Object.keys(s).length} items` : 'Not loaded yet'; }, }; // ═══════════════════════════════════════════════════════════════════════ @@ -3912,9 +3913,24 @@ function initializeBattle() { } // Auto-scrape gear data on character/armory pages (reads from HV's in-memory store) + // Wait for dynjs_equip to load (external script, may load after document-end) const url = window.location.href || ''; if (url.includes('ss=eq') || url.includes('ss=ch') || url.includes('ss=am')) { - setTimeout(autoScrapeGear, 300); + let attempts = 0; + const tryScrape = () => { + const store = getHVEquipStore(); + if (store && Object.keys(store).length > 0) { + autoScrapeGear(); + return; + } + if (++attempts < 10) { + setTimeout(tryScrape, 500); // retry every 500ms up to 5 seconds + } else { + // Fallback: scrape names/IDs without stats + autoScrapeGear(); + } + }; + setTimeout(tryScrape, 300); } STATE.battleInitialized = true; diff --git a/src/config.js b/src/config.js index f88d8b1..ae36b79 100644 --- a/src/config.js +++ b/src/config.js @@ -2,7 +2,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.14.14'; +const VERSION = '0.14.15'; const CFG = { // — Battle automation diff --git a/src/header.user.js b/src/header.user.js index ab74ed5..3cafdae 100644 --- a/src/header.user.js +++ b/src/header.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.14.14 +// @version 0.14.15 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* diff --git a/src/init.js b/src/init.js index 1d8a2d5..9747870 100644 --- a/src/init.js +++ b/src/init.js @@ -103,9 +103,24 @@ function initializeBattle() { } // Auto-scrape gear data on character/armory pages (reads from HV's in-memory store) + // Wait for dynjs_equip to load (external script, may load after document-end) const url = window.location.href || ''; if (url.includes('ss=eq') || url.includes('ss=ch') || url.includes('ss=am')) { - setTimeout(autoScrapeGear, 300); + let attempts = 0; + const tryScrape = () => { + const store = getHVEquipStore(); + if (store && Object.keys(store).length > 0) { + autoScrapeGear(); + return; + } + if (++attempts < 10) { + setTimeout(tryScrape, 500); // retry every 500ms up to 5 seconds + } else { + // Fallback: scrape names/IDs without stats + autoScrapeGear(); + } + }; + setTimeout(tryScrape, 300); } STATE.battleInitialized = true; diff --git a/src/public-api.js b/src/public-api.js index fd99792..8202fb8 100644 --- a/src/public-api.js +++ b/src/public-api.js @@ -25,4 +25,5 @@ window.HV = { gearSummary: () => logGearSummary(), scrapeGear: () => autoScrapeGear(), gearDebug: () => debugScrapeGear(), + gearStore: () => { const s = getHVEquipStore(); return s ? `Loaded: ${Object.keys(s).length} items` : 'Not loaded yet'; }, };