v0.14.20 - Fix Purchase page scraper: const dynjs_eqstore + screen=purchase
- Bug 1: Purchase tab URL is 'screen=purchase', not 'screen=buy'
- Bug 2: dynjs_eqstore is declared with 'const', not 'var', so it doesn't
create a window property. getHVEquipStore() now also checks bare names
which works with @grant none and the IIFE scope chain
- Fixed price parsing: purchase table has 2 td cells (label + price),
previously required >3 cells so prices were always empty
- Names with 🔺 prefix are cleaned before storage
This commit is contained in:
parent
f2e8ce536a
commit
5286f66b3e
5 changed files with 51 additions and 21 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.14.19
|
||||
// @version 0.14.20
|
||||
// @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.19';
|
||||
const VERSION = '0.14.20';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -3281,8 +3281,18 @@ const GEAR_DB_KEY = SP + 'geardb';
|
|||
// ── Access HV's in-memory equipment store ──
|
||||
function getHVEquipStore() {
|
||||
const w = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
|
||||
// Check window properties (works for var-declared globals like dynjs_equip)
|
||||
if (w.dynjs_eqstore && Object.keys(w.dynjs_eqstore).length) return w.dynjs_eqstore;
|
||||
if (w.dynjs_equip && Object.keys(w.dynjs_equip).length) return w.dynjs_equip;
|
||||
// Check bare names (works for const/let globals that don't create window props)
|
||||
try {
|
||||
if (typeof dynjs_eqstore !== 'undefined' && dynjs_eqstore && Object.keys(dynjs_eqstore).length)
|
||||
return dynjs_eqstore;
|
||||
} catch(e) {}
|
||||
try {
|
||||
if (typeof dynjs_equip !== 'undefined' && dynjs_equip && Object.keys(dynjs_equip).length)
|
||||
return dynjs_equip;
|
||||
} catch(e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -3523,13 +3533,13 @@ function scrapeBuyPage() {
|
|||
let name = label ? (label.textContent || '').trim() : '';
|
||||
if (cb && label) name = (label.textContent || '').replace(cb.outerHTML, '').trim();
|
||||
|
||||
// Try to read price from buy pages (often in additional columns or cell text)
|
||||
// Try to read price from buy pages (second td with credit cost)
|
||||
let price = '';
|
||||
if (!idM && !name && !itemId) return;
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length > 3) {
|
||||
const lastCell = cells[cells.length - 1];
|
||||
if (lastCell) price = (lastCell.textContent || '').trim();
|
||||
if (cells.length >= 2) {
|
||||
const priceCell = cells[cells.length - 1]; // last td = price column
|
||||
if (priceCell) price = (priceCell.textContent || '').trim();
|
||||
}
|
||||
|
||||
const obj = { id: itemId, name: name || 'Unknown', category: cat, price, source: 'buy', scrapedAt: Date.now() };
|
||||
|
|
@ -3559,7 +3569,7 @@ function autoScrapeGear() {
|
|||
const url = window.location.href || '';
|
||||
if (url.includes('ss=eq') || url.includes('ss=ch')) return scrapeCharacterEquip();
|
||||
if (url.includes('ss=am') && (url.includes('screen=organize') || !url.includes('screen='))) return scrapeArmory();
|
||||
if (url.includes('ss=am') && url.includes('screen=buy')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=purchase')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=modify')) return scrapeModifyDetail();
|
||||
if (url.includes('ss=bi')) return scrapeBuyPage();
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.14.19
|
||||
// @version 0.14.20
|
||||
// @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.19';
|
||||
const VERSION = '0.14.20';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -3281,8 +3281,18 @@ const GEAR_DB_KEY = SP + 'geardb';
|
|||
// ── Access HV's in-memory equipment store ──
|
||||
function getHVEquipStore() {
|
||||
const w = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
|
||||
// Check window properties (works for var-declared globals like dynjs_equip)
|
||||
if (w.dynjs_eqstore && Object.keys(w.dynjs_eqstore).length) return w.dynjs_eqstore;
|
||||
if (w.dynjs_equip && Object.keys(w.dynjs_equip).length) return w.dynjs_equip;
|
||||
// Check bare names (works for const/let globals that don't create window props)
|
||||
try {
|
||||
if (typeof dynjs_eqstore !== 'undefined' && dynjs_eqstore && Object.keys(dynjs_eqstore).length)
|
||||
return dynjs_eqstore;
|
||||
} catch(e) {}
|
||||
try {
|
||||
if (typeof dynjs_equip !== 'undefined' && dynjs_equip && Object.keys(dynjs_equip).length)
|
||||
return dynjs_equip;
|
||||
} catch(e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -3523,13 +3533,13 @@ function scrapeBuyPage() {
|
|||
let name = label ? (label.textContent || '').trim() : '';
|
||||
if (cb && label) name = (label.textContent || '').replace(cb.outerHTML, '').trim();
|
||||
|
||||
// Try to read price from buy pages (often in additional columns or cell text)
|
||||
// Try to read price from buy pages (second td with credit cost)
|
||||
let price = '';
|
||||
if (!idM && !name && !itemId) return;
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length > 3) {
|
||||
const lastCell = cells[cells.length - 1];
|
||||
if (lastCell) price = (lastCell.textContent || '').trim();
|
||||
if (cells.length >= 2) {
|
||||
const priceCell = cells[cells.length - 1]; // last td = price column
|
||||
if (priceCell) price = (priceCell.textContent || '').trim();
|
||||
}
|
||||
|
||||
const obj = { id: itemId, name: name || 'Unknown', category: cat, price, source: 'buy', scrapedAt: Date.now() };
|
||||
|
|
@ -3559,7 +3569,7 @@ function autoScrapeGear() {
|
|||
const url = window.location.href || '';
|
||||
if (url.includes('ss=eq') || url.includes('ss=ch')) return scrapeCharacterEquip();
|
||||
if (url.includes('ss=am') && (url.includes('screen=organize') || !url.includes('screen='))) return scrapeArmory();
|
||||
if (url.includes('ss=am') && url.includes('screen=buy')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=purchase')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=modify')) return scrapeModifyDetail();
|
||||
if (url.includes('ss=bi')) return scrapeBuyPage();
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// CONFIG — default settings
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
|
||||
const VERSION = '0.14.19';
|
||||
const VERSION = '0.14.20';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
|
|||
|
|
@ -10,8 +10,18 @@ const GEAR_DB_KEY = SP + 'geardb';
|
|||
// ── Access HV's in-memory equipment store ──
|
||||
function getHVEquipStore() {
|
||||
const w = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
|
||||
// Check window properties (works for var-declared globals like dynjs_equip)
|
||||
if (w.dynjs_eqstore && Object.keys(w.dynjs_eqstore).length) return w.dynjs_eqstore;
|
||||
if (w.dynjs_equip && Object.keys(w.dynjs_equip).length) return w.dynjs_equip;
|
||||
// Check bare names (works for const/let globals that don't create window props)
|
||||
try {
|
||||
if (typeof dynjs_eqstore !== 'undefined' && dynjs_eqstore && Object.keys(dynjs_eqstore).length)
|
||||
return dynjs_eqstore;
|
||||
} catch(e) {}
|
||||
try {
|
||||
if (typeof dynjs_equip !== 'undefined' && dynjs_equip && Object.keys(dynjs_equip).length)
|
||||
return dynjs_equip;
|
||||
} catch(e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -252,13 +262,13 @@ function scrapeBuyPage() {
|
|||
let name = label ? (label.textContent || '').trim() : '';
|
||||
if (cb && label) name = (label.textContent || '').replace(cb.outerHTML, '').trim();
|
||||
|
||||
// Try to read price from buy pages (often in additional columns or cell text)
|
||||
// Try to read price from buy pages (second td with credit cost)
|
||||
let price = '';
|
||||
if (!idM && !name && !itemId) return;
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length > 3) {
|
||||
const lastCell = cells[cells.length - 1];
|
||||
if (lastCell) price = (lastCell.textContent || '').trim();
|
||||
if (cells.length >= 2) {
|
||||
const priceCell = cells[cells.length - 1]; // last td = price column
|
||||
if (priceCell) price = (priceCell.textContent || '').trim();
|
||||
}
|
||||
|
||||
const obj = { id: itemId, name: name || 'Unknown', category: cat, price, source: 'buy', scrapedAt: Date.now() };
|
||||
|
|
@ -288,7 +298,7 @@ function autoScrapeGear() {
|
|||
const url = window.location.href || '';
|
||||
if (url.includes('ss=eq') || url.includes('ss=ch')) return scrapeCharacterEquip();
|
||||
if (url.includes('ss=am') && (url.includes('screen=organize') || !url.includes('screen='))) return scrapeArmory();
|
||||
if (url.includes('ss=am') && url.includes('screen=buy')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=purchase')) return scrapeBuyPage();
|
||||
if (url.includes('ss=am') && url.includes('screen=modify')) return scrapeModifyDetail();
|
||||
if (url.includes('ss=bi')) return scrapeBuyPage();
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.14.19
|
||||
// @version 0.14.20
|
||||
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
|
||||
// @author GaboGG + Hermes
|
||||
// @match *://*.hentaiverse.org/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue