From 24c47edece210db0976b37a25903b0b22fbca7d7 Mon Sep 17 00:00:00 2001 From: GaboGG Date: Tue, 4 Aug 2026 14:52:13 -0400 Subject: [PATCH] v0.16.1 - Add HV.diag() integration diagnostics + error trap --- scripts/hv-unified.user.js | 49 +++++++++++++++++++++++++++++++++++--- scripts/latest.user.js | 49 +++++++++++++++++++++++++++++++++++--- src/config.js | 2 +- src/header.user.js | 2 +- src/init.js | 11 ++++++++- src/public-api.js | 34 ++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 9 deletions(-) diff --git a/scripts/hv-unified.user.js b/scripts/hv-unified.user.js index 39fc5f2..8989692 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.16.0 +// @version 0.16.1 // @description HV Unified — Bridge & Strategy/Gear Advisor for HentaiVerse (complements Monsterbation & HVUtils) // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -18,7 +18,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.16.0'; +const VERSION = '0.16.1'; const CFG = { // — Battle strategy advisory @@ -3637,6 +3637,40 @@ window.HV = { analyzeGear: () => analyzeGear(), gearPanel: () => buildGearPanel(), clearBuy: () => { const db = getGearDB(); saveGearDB(db.filter(e => e.source !== 'buy')); return 'Buy data cleared'; }, + // ── Integration diagnostics (run in battle or on any HV page) ── + diag: () => { + const out = { + version: VERSION, + page: STATE.page, + url: location.href, + difficulty: (document.getElementById('level_readout') || {}).textContent ? + document.getElementById('level_readout').textContent.replace(/\\s+/g, ' ').trim().slice(0, 40) : 'n/a', + tier: STATE.tier, + // Community script detection + scripts: { + monsterbation: typeof window.unsafeWindow !== 'undefined' || !!(document.querySelector('script[src*="hvmonsterbate"], [class*="monsterbation"], #homosex, #gay_sex')), + hvutils: !!(document.querySelector('[id*="hvut"], [class*="hvut"], #hvut')), + unified: true, + }, + // State availability + state_ready: !!STATE && !!STATE.page, + monsters: STATE.monsters ? STATE.monsters.length : null, + oc: STATE.oc !== undefined ? STATE.oc : null, + sp: STATE.sp !== undefined ? STATE.sp : null, + hp: STATE.hp !== undefined ? STATE.hp : null, + mp: STATE.mp !== undefined ? STATE.mp : null, + skillsKnown: STATE.skillsKnown ? STATE.skillsKnown.slice(0, 10) : null, + // Advisory engine + advice: (typeof getRecommendedAction === 'function') ? (() => { + try { return getRecommendedAction(); } catch (e) { return { error: e.message }; } + })() : 'NOT DEFINED', + // Gear DB size + gearCount: (() => { try { const db = getGearDB(); return db ? db.length : null; } catch (e) { return null; } })(), + // Errors to watch + lastErrors: (window.__hvErrors || []).slice(-5), + }; + return out; + }, }; function init() { @@ -3732,6 +3766,15 @@ function initializeBattle() { // ── Bootstrap ── +// Global error trap — HV.diag().lastErrors surfaces runtime exceptions +window.__hvErrors = []; +window.addEventListener('error', function (e) { + try { + window.__hvErrors.push(String(e.message || e.type).slice(0, 200)); + if (window.__hvErrors.length > 20) window.__hvErrors.shift(); + } catch (err) {} +}); + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { @@ -3740,7 +3783,7 @@ if (document.readyState === 'loading') { console.log('%c🛡️ HV Unified v' + VERSION + ' Bridge & Advisory Mode%c | ,=settings', 'color:#fdcb00;font-weight:bold', ''); -console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check', +console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check | HV.diag() for integration diagnostics', 'color:#888;font-size:10px'); })(); diff --git a/scripts/latest.user.js b/scripts/latest.user.js index 39fc5f2..8989692 100644 --- a/scripts/latest.user.js +++ b/scripts/latest.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.16.0 +// @version 0.16.1 // @description HV Unified — Bridge & Strategy/Gear Advisor for HentaiVerse (complements Monsterbation & HVUtils) // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -18,7 +18,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.16.0'; +const VERSION = '0.16.1'; const CFG = { // — Battle strategy advisory @@ -3637,6 +3637,40 @@ window.HV = { analyzeGear: () => analyzeGear(), gearPanel: () => buildGearPanel(), clearBuy: () => { const db = getGearDB(); saveGearDB(db.filter(e => e.source !== 'buy')); return 'Buy data cleared'; }, + // ── Integration diagnostics (run in battle or on any HV page) ── + diag: () => { + const out = { + version: VERSION, + page: STATE.page, + url: location.href, + difficulty: (document.getElementById('level_readout') || {}).textContent ? + document.getElementById('level_readout').textContent.replace(/\\s+/g, ' ').trim().slice(0, 40) : 'n/a', + tier: STATE.tier, + // Community script detection + scripts: { + monsterbation: typeof window.unsafeWindow !== 'undefined' || !!(document.querySelector('script[src*="hvmonsterbate"], [class*="monsterbation"], #homosex, #gay_sex')), + hvutils: !!(document.querySelector('[id*="hvut"], [class*="hvut"], #hvut')), + unified: true, + }, + // State availability + state_ready: !!STATE && !!STATE.page, + monsters: STATE.monsters ? STATE.monsters.length : null, + oc: STATE.oc !== undefined ? STATE.oc : null, + sp: STATE.sp !== undefined ? STATE.sp : null, + hp: STATE.hp !== undefined ? STATE.hp : null, + mp: STATE.mp !== undefined ? STATE.mp : null, + skillsKnown: STATE.skillsKnown ? STATE.skillsKnown.slice(0, 10) : null, + // Advisory engine + advice: (typeof getRecommendedAction === 'function') ? (() => { + try { return getRecommendedAction(); } catch (e) { return { error: e.message }; } + })() : 'NOT DEFINED', + // Gear DB size + gearCount: (() => { try { const db = getGearDB(); return db ? db.length : null; } catch (e) { return null; } })(), + // Errors to watch + lastErrors: (window.__hvErrors || []).slice(-5), + }; + return out; + }, }; function init() { @@ -3732,6 +3766,15 @@ function initializeBattle() { // ── Bootstrap ── +// Global error trap — HV.diag().lastErrors surfaces runtime exceptions +window.__hvErrors = []; +window.addEventListener('error', function (e) { + try { + window.__hvErrors.push(String(e.message || e.type).slice(0, 200)); + if (window.__hvErrors.length > 20) window.__hvErrors.shift(); + } catch (err) {} +}); + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { @@ -3740,7 +3783,7 @@ if (document.readyState === 'loading') { console.log('%c🛡️ HV Unified v' + VERSION + ' Bridge & Advisory Mode%c | ,=settings', 'color:#fdcb00;font-weight:bold', ''); -console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check', +console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check | HV.diag() for integration diagnostics', 'color:#888;font-size:10px'); })(); diff --git a/src/config.js b/src/config.js index 1544526..9fcd21d 100644 --- a/src/config.js +++ b/src/config.js @@ -2,7 +2,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.16.0'; +const VERSION = '0.16.1'; const CFG = { // — Battle strategy advisory diff --git a/src/header.user.js b/src/header.user.js index cee5f02..debb486 100644 --- a/src/header.user.js +++ b/src/header.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.16.0 +// @version 0.16.1 // @description HV Unified — Bridge & Strategy/Gear Advisor for HentaiVerse (complements Monsterbation & HVUtils) // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* diff --git a/src/init.js b/src/init.js index b6fac67..3227701 100644 --- a/src/init.js +++ b/src/init.js @@ -91,6 +91,15 @@ function initializeBattle() { // ── Bootstrap ── +// Global error trap — HV.diag().lastErrors surfaces runtime exceptions +window.__hvErrors = []; +window.addEventListener('error', function (e) { + try { + window.__hvErrors.push(String(e.message || e.type).slice(0, 200)); + if (window.__hvErrors.length > 20) window.__hvErrors.shift(); + } catch (err) {} +}); + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { @@ -99,7 +108,7 @@ if (document.readyState === 'loading') { console.log('%c🛡️ HV Unified v' + VERSION + ' Bridge & Advisory Mode%c | ,=settings', 'color:#fdcb00;font-weight:bold', ''); -console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check', +console.log('%c HV.analyzeGear() for gear scoring | HV.advice() for build guidance | HV.difficulty() for difficulty check | HV.diag() for integration diagnostics', 'color:#888;font-size:10px'); })(); diff --git a/src/public-api.js b/src/public-api.js index fdaa4b8..4f98e54 100644 --- a/src/public-api.js +++ b/src/public-api.js @@ -30,4 +30,38 @@ window.HV = { analyzeGear: () => analyzeGear(), gearPanel: () => buildGearPanel(), clearBuy: () => { const db = getGearDB(); saveGearDB(db.filter(e => e.source !== 'buy')); return 'Buy data cleared'; }, + // ── Integration diagnostics (run in battle or on any HV page) ── + diag: () => { + const out = { + version: VERSION, + page: STATE.page, + url: location.href, + difficulty: (document.getElementById('level_readout') || {}).textContent ? + document.getElementById('level_readout').textContent.replace(/\\s+/g, ' ').trim().slice(0, 40) : 'n/a', + tier: STATE.tier, + // Community script detection + scripts: { + monsterbation: typeof window.unsafeWindow !== 'undefined' || !!(document.querySelector('script[src*="hvmonsterbate"], [class*="monsterbation"], #homosex, #gay_sex')), + hvutils: !!(document.querySelector('[id*="hvut"], [class*="hvut"], #hvut')), + unified: true, + }, + // State availability + state_ready: !!STATE && !!STATE.page, + monsters: STATE.monsters ? STATE.monsters.length : null, + oc: STATE.oc !== undefined ? STATE.oc : null, + sp: STATE.sp !== undefined ? STATE.sp : null, + hp: STATE.hp !== undefined ? STATE.hp : null, + mp: STATE.mp !== undefined ? STATE.mp : null, + skillsKnown: STATE.skillsKnown ? STATE.skillsKnown.slice(0, 10) : null, + // Advisory engine + advice: (typeof getRecommendedAction === 'function') ? (() => { + try { return getRecommendedAction(); } catch (e) { return { error: e.message }; } + })() : 'NOT DEFINED', + // Gear DB size + gearCount: (() => { try { const db = getGearDB(); return db ? db.length : null; } catch (e) { return null; } })(), + // Errors to watch + lastErrors: (window.__hvErrors || []).slice(-5), + }; + return out; + }, };