- 23 source files in src/ (build via scripts/build.sh) - Forum-sourced player knowledge in references/ - DESIGN.md with architecture and corrections - References to existing scripts (Monsterbation, jpx, HV Utils)
768 lines
31 KiB
Markdown
768 lines
31 KiB
Markdown
# HV Utils 4.2.3 — Deep Structural Analysis
|
||
|
||
**Source:** `/home/gabogg/Downloads/HVUT_4.2.3.txt`
|
||
**Lines:** 9,710 (416 KB)
|
||
**Author:** sssss2
|
||
**Date:** 2026-06-21
|
||
**Sections:** 19 page-specific modules + 10 core shared modules
|
||
|
||
---
|
||
|
||
## 1. PAGE DETECTION
|
||
|
||
HV Utils uses a multi-layered detection system:
|
||
|
||
### Primary: URL Query Parsing (Line 212)
|
||
```js
|
||
const _query = Object.fromEntries(location.search.slice(1).split('&')
|
||
.map((q) => { const [k, v = ''] = q.split('=', 2);
|
||
return [decodeURIComponent(k), decodeURIComponent(v)];
|
||
}));
|
||
```
|
||
This parses Hentaiverse's `?s=X&ss=Y&screen=Z&filter=W` format into `_query.s`, `_query.ss`, `_query.screen`, `_query.filter`.
|
||
|
||
### Server Detection (Line 213-217)
|
||
```js
|
||
const _server = {
|
||
name: location.pathname.includes('/isekai/') ? 'isekai' : 'persistent',
|
||
season: $id('world_text')?.textContent.match(/\d+ Season \d+/)?.[0] || '1',
|
||
};
|
||
```
|
||
Also sets `_server.persistent` / `_server.isekai` for boolean checks.
|
||
|
||
### Page Dispatch Architecture (Lines 3819–9710)
|
||
The script uses a chain of `if/else if` blocks testing `_query.s`, `_query.ss`, and DOM elements:
|
||
|
||
| Section | Condition | Module | Line |
|
||
|---------|-----------|--------|------|
|
||
| Character | `s=Character, ss=ch` | `_ch` | 3819 |
|
||
| Equipment | `s=Character, ss=eq` | `_eq` | 3922 |
|
||
| Abilities | `s=Character, ss=ab` | `_ab` | 4096 |
|
||
| Training | `s=Character, ss=tr` | `_tr` | 4467 |
|
||
| Item Inventory | `s=Character, ss=it` | `_it` | 4675 |
|
||
| Settings | `s=Character, ss=se` | `_se` | 4703 |
|
||
| Item Shop | `s=Bazaar, ss=is` | `_is` | 4806 |
|
||
| The Shrine | `s=Bazaar, ss=ss` | `_ss` | 4832 |
|
||
| The Market | `s=Bazaar, ss=mk` | `_mk` | 5373 |
|
||
| Monster Lab | `s=Bazaar, ss=ml` | `_ml` | 5485 |
|
||
| MoogleMail | `s=Bazaar, ss=mm` | `_mm` | 6869 |
|
||
| Lottery | `s=Bazaar, ss=lt/la` | `_lt` | 8499 |
|
||
| Battle → Arena | `s=Battle, ss=ar` | `_ar` | 8560 |
|
||
| Battle → RoB | `s=Battle, ss=rb` | `_ar` | 8570 |
|
||
| Battle → Tower | `s=Battle, ss=tw` | — | 8580 |
|
||
| Battle → GrindFest | `s=Battle, ss=gr` | — | 8587 |
|
||
| Battle → Item World | `s=Battle, ss=iw` | — | 8594 |
|
||
| Armory (Equip Shop) | `s=Bazaar, ss=am` | `$armory` | 8609 |
|
||
| Modify (single equip) | `s=Bazaar, ss=am, screen=modify` | `_mo` | 9669 |
|
||
|
||
### No-Navbar Early Exit (Lines 1144–1164)
|
||
Before any page dispatch, the script checks `$id('navbar')`. If absent, it handles:
|
||
- **Battle pages:** Activates RE timer in battle mode
|
||
- **e-hentai.org gallery:** Activates RE timer in gallery mode
|
||
- **Riddle Master:** Commented out
|
||
Then `return` — none of the page modules execute.
|
||
|
||
---
|
||
|
||
## 2. INVENTORY/SHOP AUTOMATION
|
||
|
||
### Equipment Shop (`$armory`, Lines 8609–9667)
|
||
|
||
**Architecture:** A self-contained module on `?s=Bazaar&ss=am` pages with sub-modules:
|
||
|
||
#### Sidebar Buttons (Line 8752-8801)
|
||
- **Select All** — toggles all non-protected, non-filtered checkboxes
|
||
- **Tradeables / Pinned** — bulk selection by status
|
||
- **Equip Code** — generate forum BBcode for selected equipment
|
||
- **Sell / Salvage / Purchase & Salvage** — with smart selection:
|
||
- `sell`: selects items where sell_price ≥ salvage_value, excluding protected/locked/stored
|
||
- `salvage`: selects items where salvage_value > sell_price
|
||
- `purchase_salvage`: selects items profitable to buy+salvage
|
||
- **Bazaar Filters / Protect Filters** — toggle between show-all and hide-based-on-filters
|
||
|
||
#### Protection System (Line 9073-9089)
|
||
- The `protect()` method checks: `eq.info.protected || eq.info.pinned || $equip.filter.equip($config.settings.equipmentShopProtectFilters, eq)`
|
||
- Protected equipment is moved to a special `<tbody>` at the top labeled "Protected Equipment"
|
||
- Their checkboxes are disabled from "Select All"
|
||
- If `equipmentShopAutoProtect` is enabled, auto-submits a protect action
|
||
|
||
#### Bazaar Filter System (Line 9090-9104)
|
||
- Applies `equipmentShopBazaarFilters` to hide non-valuable equipment
|
||
- Also shows items where `salvage_value > purchase_price` (profitable to buy and salvage)
|
||
- Hidden items get `hvut-eqp-hidden` class; category headers auto-hide when all children hidden
|
||
|
||
#### Salvage Value Calculation (`$armory.calc`, Line 8852-8938)
|
||
- **`calc.materials(eq)`**: Estimates salvage materials based on quality, material type, core type, and rare status:
|
||
- Quality 1-3 (Crude–Average): `Scrap [type]` = `min(10, ceil(sell_price / 100))`
|
||
- Quality 4 (Superior): `Low-Grade [type]` × (1 on persistent, 3 on isekai)
|
||
- Quality 5 (Exquisite): `Mid-Grade [type]`
|
||
- Quality 6 (Magnificent): `High-Grade [type]`
|
||
- Quality 7+ (Legendary/Peerless): adds `[Quality] [Weapon/Staff/Armor] Core` (×5 if rare)
|
||
- Rare items: adds `Energy Cell`
|
||
- **`calc.value(materials)`**: Multiplies by item prices (with optional 1% market fee deduction)
|
||
- Shows "C" (sell price) and "V" (salvage value) columns, highlighting profitable salvage in green
|
||
|
||
#### Submit Confirm (Line 9184-9194)
|
||
Three modes based on `equipmentShopConfirm`:
|
||
- `0`: default browser confirm dialog
|
||
- `1`: auto-check confirm checkbox
|
||
- `2`: skip confirmation entirely
|
||
|
||
#### Screen-Specific Modifications (`$armory.modify`, Line 8978-9042)
|
||
- **organize**: Adds note input fields (for `@price, $note` forum code annotations)
|
||
- **modify**: Shows upgrade/IW levels
|
||
- **purchase**: Shows purchase price and salvage value side-by-side; applies bazaar filter
|
||
- **sell**: Loads salvage page to get salvage values; protects valuable items
|
||
- **salvage**: Loads sell page to get sell prices; protects valuable items
|
||
|
||
#### All-In-One Integration (Line 8940-8975)
|
||
- `$armory.integrate` loads ALL equipment categories (1H, 2H, Staff, Shield, Cloth, Light, Heavy) into a single unified table
|
||
- Adds an "All" tab to the filter bar
|
||
- Each category loads asynchronously via AJAX
|
||
|
||
### Item Shop (`_is`, Lines 4806–4828)
|
||
- Minimal: just adds `hvut-item-{type}` CSS class to each row for color coding
|
||
- Types: Consumable, Artifact, Trophy, Token, Crystal, MonsterFood, Material, Collectable
|
||
|
||
---
|
||
|
||
## 3. SHRINE (`_ss`, Lines 4832–5371)
|
||
|
||
### Bulk Offering Queue
|
||
|
||
**Per-Item Controls (Line 5029-5081):**
|
||
- Each item row gets:
|
||
- A number input for offer count
|
||
- An "Offer" button
|
||
- For trophies: "All" button (offers max = `floor(stock / bulk)`)
|
||
- Displays bulk grouping info (e.g., " / 1000")
|
||
|
||
**Trophy Value System (Line 5050-5068):**
|
||
- Trophies have tier-based values (1000c for T2, 2000c for T3, 4000c for T4, 5000c for T5)
|
||
- Auto-calculates upgrade paths: combining lower-tier trophies into higher tiers increases value
|
||
- Shows upgraded trophy tier and value
|
||
|
||
**Item Hiding (Line 5070-5072):**
|
||
- Items matching `shrineHideItems` (default: `['Figurine', 'Peerless Voucher']`) get `hvut-none-item` class
|
||
- Toggle button to show/hide these filtered items
|
||
|
||
**Reward Selection (Line 4911-4948):**
|
||
- Intercepts reward selection buttons, adds visual highlight on selected reward
|
||
- Tracks `reward_type` and `reward_slot` for each offering request
|
||
|
||
### Result Tracking
|
||
|
||
**Offering Requests (Line 5083-5371):**
|
||
- Each offering creates an AJAX request with: `iid`, `count`, optional `reward_type`/`reward_slot`
|
||
- Results parsed from server response messages
|
||
- Equipment rewards filtered through `shrineFilters` (default: Peerless, Legendary, Magnificent, Exquisite)
|
||
- Results displayed in a toggleable table showing per-item breakdowns:
|
||
- Percentage and count for each reward type
|
||
- Equipment names shown for quality-filtered items
|
||
- Grouped categories (Pouches, Charms, High-Grade Materials, Bindings, Crystals, PABs)
|
||
|
||
**Shrine Log (Line 4889-4889):**
|
||
- Persistent log of all offering results
|
||
- Reset button to clear log
|
||
|
||
---
|
||
|
||
## 4. MONSTER LAB (`_ml`, Lines 5485–6867)
|
||
|
||
### Monster List Display
|
||
|
||
**Sort System (Line 5660-5685):**
|
||
- Sorts by: index, name, class, PL, wins, kills, gains, gifts, morale, hunger
|
||
- Configurable default via `monsterLabDefaultSort`
|
||
- Click column headers to sort; clicking again reverses order
|
||
|
||
**Per-Monster Tracking (Line 5741-5836):**
|
||
- `_ml.mobs[]` array stores: name, class, PL, wins, kills, PA values, ER values, CT values, morale, hunger, gifts log
|
||
- `_ml.log[]` persisted to storage with: date, PL, wins, kills, PA/ER/CT arrays, 49-element gift array
|
||
|
||
**Morale/Hunger Display (Line 5791-5803):**
|
||
- Parses the pixel-width of bar images: `hunger = width * 200`, `morale = width * 200`
|
||
- Shows numeric value overlay on each bar
|
||
|
||
### Feed System
|
||
|
||
**Feed Actions (Line 5877-5909):**
|
||
- **Click morale bar:** Feeds drugs (increases morale)
|
||
- **Click hunger bar:** Feeds food (increases hunger)
|
||
- **Click wins/kills:** Updates monster stats (fetches the monster page)
|
||
- After feeding, auto-updates: PL, wins, kills, PAs, ERs, CTs, morale, hunger bars
|
||
|
||
**Bulk Feed (Line 5889-5891):**
|
||
- "Update Wins/Kills" button feeds ALL monsters
|
||
- `feedall(stat, value, food)` — conditional bulk feeding
|
||
|
||
### Gift Tracking
|
||
|
||
**Gift Summary (Line 5921-5976):**
|
||
- Parses message box for gift notifications: "X brought you a gift!" + "Received N× Item"
|
||
- Computes total gifts and estimated credit value using `$price.value()`
|
||
- Shows per-material breakdown in a summary panel
|
||
|
||
**Monster Log (Line 5996-6023):**
|
||
- Per-monster log showing all 49 tracked material types
|
||
- Shows: days since first log, total gifts, total value, daily average
|
||
- Formatted in two-column layout
|
||
- Materials tracked: 12 grade materials + Phazon + Shade Fragment + Repurposed Actuator + Defense Matrix + 33 Bindings + World Seed
|
||
|
||
### Crystal/Pill Feeder (Monster Upgrader, Lines 6037-6867)
|
||
|
||
**Upgrade Table (Line 6096-6135):**
|
||
- Spreadsheet-style grid: rows = monsters, columns = stats
|
||
- **Primary Attributes (PA):** STR, DEX, AGI, END, INT, WIS → use Vigor/Finesse/Swiftness/Fortitude/Cunning/Knowledge crystals
|
||
- **Elemental Resistances (ER):** FIRE, COLD, ELEC, WIND, HOLY, DARK → use Flames/Frost/Lightning/Tempest/Devotion/Corruption crystals
|
||
- **Chaos Tokens (CT):** 12 stats → use Chaos Tokens
|
||
|
||
**Bulk Operations:**
|
||
- Increase/Decrease all monsters' stats at once
|
||
- Equalize (set all to highest value)
|
||
- Per-stat buttons for each crystal type
|
||
- Right-click to decrease, left-click to increase
|
||
|
||
**Crystal Stock Tracking:**
|
||
- Loads item inventory to show available crystals
|
||
- Shows per-crystal usage and remaining stock
|
||
|
||
### Power Level Calculator (Lines ~6700-6867)
|
||
- Complex PL simulation with PA/ER/CT values
|
||
- Input fields for custom values with slider-like controls
|
||
- Shows PL changes per stat
|
||
|
||
---
|
||
|
||
## 5. MOOGLEMAIL (`$mail` + `_mm`, Lines 2174–2413, 6869–8498)
|
||
|
||
### Send Engine (`$mail`)
|
||
|
||
**Queue System (Line 2179-2305):**
|
||
- `$mail.queue[]`: Array of mail chunks
|
||
- `$mail.current`: Index of current mail being processed
|
||
- `$mail.ready`: Semaphore preventing concurrent sends
|
||
- Auto-chains: when one mail completes, the next automatically starts
|
||
|
||
**Chunking (Line 2306-2386):**
|
||
- Splits large attachments into chunks of 10 items each
|
||
- Auto-generates subject from first item name
|
||
- Calculates CoD totals with optional deduction
|
||
- Adds attachment text to body
|
||
|
||
**Send Process (Line 2186-2305):**
|
||
1. Fetches MoogleMail token if not cached
|
||
2. Removes any existing attachments
|
||
3. Attaches items via `attach_add` API (Promise.all for concurrency)
|
||
4. Sets CoD if applicable
|
||
5. For persistent CoD (Isekai → Persistent): opens persistent MoogleMail, attaches credits, sets CoD there
|
||
6. Sends message
|
||
7. On completion: advances to next queue item, or redirects to Sent folder
|
||
|
||
**Error Handling (Line 2387-2398):**
|
||
- Checks server response for error messages
|
||
- On error: logs and discards the draft
|
||
|
||
### Write UI (`_mm.write`, Lines 6889-7089)
|
||
|
||
**Compose Interface:**
|
||
- To: with datalist autocomplete from user list
|
||
- Subject: auto-filled from first attachment
|
||
- Body: textarea
|
||
- CoD Deduction field
|
||
- Persistent CoD checkbox (Isekai only)
|
||
|
||
**Attachment Panels (three tabs):**
|
||
1. **Credits** (`_mm.credits`): Amount input with pre-set buttons (10k, 100k, 500k, 1m, etc.)
|
||
2. **Equipment** (`_mm.equip`): List of all equipment with checkboxes, search by name/EID, protected-item warning
|
||
3. **Items** (`_mm.item`): Filter by group (Consumables, Materials, Trophies, Crystals, Figures), search by name, bulk count/check
|
||
|
||
**Item Attachment (Lines 7092-7169):**
|
||
- Search: type partial item names, separated by commas
|
||
- Each item row: checkbox, count input, price input, auto-calculated CoD
|
||
- "CALC" button: previews attachment text
|
||
- "ATTACH from TEXT": parses free-form text like `100 x Health Potion @ 10`
|
||
- "SEND" button on each row for single-item quick send
|
||
- "SEND ALL" to send everything checked
|
||
|
||
**User List (Line 7020-7049):**
|
||
- Persisted list of recipients
|
||
- Auto-adds on send
|
||
- Deduplication on save
|
||
- Editable via popup
|
||
|
||
---
|
||
|
||
## 6. TRAINING (`_tr`, Lines 4467–4671)
|
||
|
||
### Queue Management
|
||
|
||
**Data Model (Line 4470-4488):**
|
||
- `_tr.json` (stored as `hvut_tr_notif`): `{ current_name, current_level, current_end, next_name, next_level, next_id, error }`
|
||
- Training data: id, base cost, linear cost increment, exponential factor for all 15 trainable skills
|
||
|
||
**Progress Tracking (Line 4548-4559):**
|
||
- Reads `end_time` from server-rendered JavaScript
|
||
- Shows current training name + level in bottom bar
|
||
- Countdown timer with `HH:MM:SS` format
|
||
|
||
**Queue System (Lines 4491-4659):**
|
||
- **Plan Training:** Select skill + target level, shows calculated credit cost
|
||
- **Set:** Saves `next_name`/`next_level`/`next_id` to storage
|
||
- When current training completes (or on page load if idle):
|
||
1. Fetches training page
|
||
2. Checks if `next_name`'s current level < `next_level`
|
||
3. If yes: auto-submits `start_train=<id>` form
|
||
4. If no: shows "Training completed!"
|
||
- **Cancel:** Clears the notification JSON
|
||
- **Reset Planning:** Clears both current and next
|
||
|
||
**Cost Calculation (Line 4611-4628):**
|
||
- Formula: `Σ pow(base + linear × level, 1 + exp × level)` for each level from current to target
|
||
- Uses the real game formulas for each training type
|
||
- Shows spent credits per training and total spent
|
||
|
||
**Bottom Bar Integration (Line 3647-3721):**
|
||
- `_bottom.tr` shows current training status in compact format
|
||
- Links to training page
|
||
- Auto-loads when timer expires
|
||
|
||
---
|
||
|
||
## 7. EQUIPMENT MANAGEMENT
|
||
|
||
### Upgrade Queue (`_mo.upgrade`, Lines 9669–9704)
|
||
|
||
On the single-equipment Modify page:
|
||
- Parses the upgrade materials table
|
||
- Calculates total cost using `$price.value(mats) + credits`
|
||
- Shows clickable total cost button → opens price editor
|
||
|
||
### Salvage/Repair/Rebuild (via `$armory`, Lines 8609-9667)
|
||
|
||
**Salvage vs Sell Comparison:**
|
||
- Calculates `salvage_value` from estimated materials × market prices
|
||
- Compares with `sell_price` or `purchase_price`
|
||
- Highlights profitable salvage in green (`hvut-eqp-profit`)
|
||
- "Purchase & Salvage" action filters for profitable arbitrage
|
||
|
||
**Batch Operations:**
|
||
- `$armory.submit.confirm('sell', ...)` / `$armory.submit.confirm('salvage', ...)`
|
||
- Gets the real submit button from the page, submits multi-equip form
|
||
|
||
### Reforge/Soulfuse
|
||
- Not directly implemented as separate features
|
||
- The Armory page covers all screens (organize, modify, repair, soulbind, purchase, sell, salvage)
|
||
|
||
### Equipment Data (`$armory.equipdata`, Line 8621)
|
||
- Stored as `hvut_equipdata` (persistent) / `hvuti_equipdata` (isekai)
|
||
- Contains per-EID: price (for forum code), note (for forum code `$featured` flag)
|
||
|
||
---
|
||
|
||
## 8. ITEM WORLD (Line 8594–8600)
|
||
|
||
The IW implementation is relatively minimal:
|
||
- Renders equipment list table with `$equip.list.table()`
|
||
- Moves the equipment blurb to the action area
|
||
- Initializes the battle panel (`$battle.init()`) for the equip select outer div
|
||
- **No PXP simulator is present** in this version (4.2.3). The script relies on the game's built-in IW interface.
|
||
|
||
Note: There *is* an EXP Simulator on the Character page (`_ch.exp`, Line 3823-3901) which uses the same exponential formula as the game.
|
||
|
||
---
|
||
|
||
## 9. ARENA/BATTLE MODES (Lines 8517–8604)
|
||
|
||
### Compact View
|
||
|
||
All battle modes (Arena, Ring of Blood, Tower, GrindFest, Item World) use `$battle.init()`:
|
||
|
||
**Layout System:**
|
||
- Wraps main pane in `hvut-bt-outer` class
|
||
- Adds a 600px side panel (`#hvut-bt-div`) on the left or right (configurable)
|
||
- Compact mode (`hvut-bt-on`): reduces main pane to 620px, side panel slides in
|
||
- Toggle button: "Details" / "Collapse"
|
||
|
||
**Equipment Panel (`.hvut-bt-equip`):**
|
||
- Shows equipped gear from current equip set
|
||
- Per-equip row: name (link), condition% / energy%, repair button
|
||
- Condition ≤ threshold (default 20%) shown in warning color
|
||
- Hover on repair shows per-material breakdown for that equip
|
||
|
||
**Item Inventory Panel (`.hvut-bt-items`):**
|
||
- Shows configured items from `equipPanelItemInventory`
|
||
- Format: `name (stock / threshold)`
|
||
- Warning if stock < threshold
|
||
- Click item name to buy from Item Shop
|
||
|
||
**Repair All Panel:**
|
||
- Calculates total materials needed
|
||
- Checks item inventory; if insufficient, offers to buy from Item Shop (Scraps, Energy Cell)
|
||
- Non-purchasable items (Infusions, Shards) trigger alert to buy from Market
|
||
|
||
### Arena-Specific
|
||
- Splits colspan=2 rows for proper compact layout
|
||
- Re-parents arena_list into arena_outer div
|
||
|
||
### Ring of Blood
|
||
- Same split_colspan treatment
|
||
- Includes arena_tokens in the outer
|
||
|
||
---
|
||
|
||
## 10. RE TIMER (`$re`, Lines 947–1142)
|
||
|
||
### Detection Mechanisms
|
||
|
||
**Mode Detection (Line 953):**
|
||
```js
|
||
$re.type = (!location.hostname.includes('hentaiverse.org') || _server.isekai) ? 'eh'
|
||
: $id('navbar') ? 'hv'
|
||
: $id('battle_top') ? 'ba'
|
||
: false;
|
||
```
|
||
- **`eh`**: e-hentai.org gallery or Isekai server
|
||
- **`hv`**: Normal Hentaiverse pages (has navbar)
|
||
- **`ba`**: Battle pages (has battle_top)
|
||
- **`false`**: Unknown/unsupported
|
||
|
||
### Key Management
|
||
|
||
- Stored as `hvut_re` (cross-profile, not namespaced): `{ date, key, count, clear }`
|
||
- **30-minute timer:** Random Encounter refreshes every 30 minutes
|
||
- **Auto-detection:**
|
||
- On HV pages: checks `location.search` for `encounter=<key>`
|
||
- On e-hentai: scrapes the event pane for the encounter link
|
||
- **Daily reset:** If the stored date is from a different UTC day, auto-resets
|
||
|
||
### Notification
|
||
|
||
- **Countdown display:** Shows `MM:SS [count]` while timer active
|
||
- **"Ready"**: When timer expires, button shows "Ready [count]"
|
||
- **"Expired"**: If an encounter was generated but not cleared
|
||
- **Beep:** Audio notification at `[0.2, 500, 0.5]` (volume, Hz, seconds) when timer expires — configurable, with test button
|
||
- **Warning highlight:** `hvut-warn` class when an uncleared encounter exists
|
||
|
||
### Engagement
|
||
|
||
- **Click RE button:** Engages if ready/uncleared (or Ctrl+Click to force engage)
|
||
- **Battle mode:** Shows RE status, click loads new key
|
||
- **Gallery mode:** Opens in new tab (configurable alt.hentaiverse.org)
|
||
- **Gallery detection:** Scrapes e-hentai.org news.php for the encounter key
|
||
|
||
---
|
||
|
||
## 11. DIFFICULTY/PERSONA/SET SELECTOR
|
||
|
||
### Difficulty Changer (`$dfct`, Lines 3280–3337)
|
||
|
||
**Location:** Top bar, shows current difficulty (Normal/Hard/Nightmare/Hell/Nintendo/IWBTH/PFUDOR)
|
||
|
||
**Mechanism:**
|
||
- Hover reveals dropdown with all 7 difficulties
|
||
- Selecting triggers:
|
||
1. Fetch settings page
|
||
2. Extract form data
|
||
3. Modify `difflevel`
|
||
4. POST updated form
|
||
5. Update local `_player.difficulty`
|
||
6. Persist to `hvut_ch_style`
|
||
|
||
**State:** Persists chosen difficulty in `ch_style.difficulty` storage
|
||
|
||
### Persona & Equipment Set Selector (`$persona`, Lines 3340–3594)
|
||
|
||
**Location:** Top bar, shows "Persona" by default, then current set name
|
||
|
||
**Data Model:**
|
||
```js
|
||
$persona.json = {
|
||
pset: current_persona_number,
|
||
plen: total_personas,
|
||
pname: current_persona_name,
|
||
eset: current_equip_set_number,
|
||
elen: total_equip_sets,
|
||
ename: current_set_name,
|
||
[pset]: { name: "...", [eset]: { name: "..." }, ... }
|
||
}
|
||
```
|
||
|
||
**Persona Switching:**
|
||
1. Fetch `?s=Character&ss=ch` with `persona_set=<N>`
|
||
2. Parse persona form for all persona names/IDs
|
||
3. Check if current matches stored
|
||
|
||
**Equip Set Switching:**
|
||
1. Fetch `?s=Character&ss=eq` with `equip_set=<N>`
|
||
2. Detect active set by finding `_on.png` image
|
||
3. Save equip config to `$config.set('equipset', ...)` — array of `{ slot, category, name, customname, eid, key }`
|
||
|
||
**Auto-reload:** After persona/set change, reloads current page if on Equipment, Abilities, Items, or Settings tabs
|
||
|
||
**Stats Parsing:**
|
||
- Parses the stats pane to determine:
|
||
- Fighting Style (Staff/Dualwield/Niten/Two-Handed/One-Handed/Unarmed)
|
||
- Best spell type (highest affinity)
|
||
- Proficiency factor
|
||
- Magic score
|
||
- Saves to `ch_style` for external use (e.g., monsterbation)
|
||
|
||
**Warnings:**
|
||
- Shows red warning bar for: repair needed, attribute check, exhausted stamina
|
||
- Stamina warning for: Exhausted, accuracy penalty, or below `warnLowStamina`
|
||
|
||
---
|
||
|
||
## 12. UI SYSTEM
|
||
|
||
### Top Navigation Bar (Lines 3030–3277)
|
||
|
||
**Complete replacement** of the game's `#navbar`:
|
||
- Hidden via `#navbar { display: none; }`
|
||
- Custom `#hvut-top` flexbox bar with:
|
||
- **MENU dropdown** (or individual section dropdowns if integration disabled): Character, Bazaar, Battle, Armory categories in organized columns
|
||
- **Quick links:** Configurable 2-letter link buttons (CH, EQ, AB, TR, IT, SE, IS, SS, MK, ML, MM, etc.)
|
||
- **Stamina display** with dropdown for restorative items
|
||
- **Level display** with EXP progress bar
|
||
- **Difficulty** dropdown
|
||
- **Persona/Equip Set** dropdown
|
||
- **RE Timer** display
|
||
- **Server** indicator with switch link
|
||
- **Settings** gear icon
|
||
|
||
### Bottom Bar (Lines 3597–3816)
|
||
|
||
`#hvut-bottom` below the main pane:
|
||
- **Credits** display (C:)
|
||
- **Equipment Inventory** capacity (E: usage/capacity) with warnings near limit
|
||
- **Training** status with countdown
|
||
- **Lottery** displays for Weapon and Armor lotteries:
|
||
- Shows current equipment + time until next drawing
|
||
- Red highlight when drawing is imminent
|
||
- Pops up alert when qualifying equipment appears (checked against `lotteryFilters`)
|
||
|
||
### Color Coding System (Lines 2772–2820)
|
||
|
||
**CSS Custom Properties** on `:root`:
|
||
|
||
**Font Colors:**
|
||
- `--color-font-default`: #5C0D11 (dark red-brown)
|
||
- `--color-font-light`: #9B4E03 (orange-brown)
|
||
- `--color-font-highlight`: #c00 (red)
|
||
- `--color-font-warn`: #e00 (bright red)
|
||
- `--color-font-bonus`: #03c (blue)
|
||
- `--color-font-invalid`: #666 (gray)
|
||
- `--color-font-invert`: #fff (white)
|
||
|
||
**Background Colors:**
|
||
- `--color-bg-default`: #EDEBDF (parchment) — main background
|
||
- `--color-bg-back`: #E3E0D1 — secondary background
|
||
- `--color-bg-light`: #fff — light highlight
|
||
- `--color-bg-alpha`: #fff9 — translucent overlay
|
||
- `--color-bg-invert`: #5C0D11 — inverted (dark)
|
||
- `--color-bg-h1`: #edb — header background
|
||
|
||
**Equipment Quality Colors:**
|
||
- Peerless: #fbb (pink), Legendary: #fd8 (gold), Magnificent: #bdf (light blue), Exquisite: #ce9 (green), Superior: #ccc (gray)
|
||
- Applied as `hvut-equip-{Quality}` class + `background-color` on rows
|
||
|
||
**Item Type Colors:**
|
||
- Consumable: #00B000 (green), Artifact: #0000FF (blue), Trophy: #461B7E (purple), Token: #254117 (dark green), Crystal: #BA05B4 (magenta), MonsterFood: #489EFF (light blue), Material: #FF0000 (red), Collectable: #0000FF (blue)
|
||
- Applied as `hvut-item-{Type}` class on rows
|
||
|
||
**Warning System:**
|
||
- `.hvut-warn`: Red text (#e00)
|
||
- `.hvut-warn2`: Inverted (dark bg, white text)
|
||
- `.hvut-bonus`: Blue text (#03c)
|
||
|
||
### Side Panel System
|
||
- `.hvut-side`: Absolute-positioned 100px wide flex column
|
||
- Used on: Shrine (`.hvut-ss-side`), Monster Lab (`.hvut-ml-side`), Market (`.hvut-mk-side`), Armory (`.hvut-am-side`)
|
||
- Contains action buttons grouped with optional margins
|
||
|
||
---
|
||
|
||
## 13. STORAGE STRUCTURES
|
||
|
||
### Primary Storage: `GM_getValue` / `GM_setValue` (TGM/Greasemonkey)
|
||
|
||
All keys prefixed with `hvut_` (persistent) or `hvuti_` (isekai):
|
||
|
||
| Key | Type | Description |
|
||
|-----|------|-------------|
|
||
| `hvut_settings` | Object | All user settings |
|
||
| `hvut_prices` | Object | Item price mappings (name → credits) |
|
||
| `hvut_persona` | Object | Persona/equip set state |
|
||
| `hvut_ch_style` | Object | Character style (difficulty, FS, spell type, prof factor) |
|
||
| `hvut_equipset` | Array | Current equip set slots |
|
||
| `hvut_equipdata` | Object | Equipment notes/prices (per EID) |
|
||
| `hvut_ml_log` | Array | Monster Lab log |
|
||
| `hvut_ss_log` | Object | Shrine log |
|
||
| `hvut_mm_userlist` | Array | MoogleMail recipient list |
|
||
| `hvut_ab_level` | Object | Ability levels |
|
||
| `hvut_se_settings` | Object | Saved settings presets |
|
||
| `hvut_tr_level` | Object | Training levels |
|
||
|
||
### Secondary Storage: `localStorage` (backup for critical data)
|
||
|
||
The `$config.ls_savelist` (line 222) defines which keys also get localStorage backup:
|
||
- `ch_style`, `persona`, `prices`, `equipset`
|
||
|
||
### Cross-Profile Storage (no prefix)
|
||
|
||
| Key | Type | Description |
|
||
|-----|------|-------------|
|
||
| `hvut_re` | Object | Random Encounter state (`{ date, key, count, clear }`) |
|
||
| `hvut_tr_notif` | Object | Training notification state |
|
||
| `hvut_lt_notif` | Object | Lottery notification state |
|
||
|
||
### Migration System (`$config.migration`, Lines 402-511)
|
||
- Detects old localStorage-based data (pre-4.x)
|
||
- Upgrades: equipdata, prices, protection filters, bazaar filters, monster lab log, equip sets, shrine log
|
||
- Cleans up old localStorage keys after migration
|
||
- Version-specific migrations for 4.2 and 4.22
|
||
|
||
---
|
||
|
||
## 14. KEY FUNCTION NAMES AND PURPOSES
|
||
|
||
### Core Shared Modules
|
||
|
||
| Module | Line | Purpose |
|
||
|--------|------|---------|
|
||
| `$config` | 220 | Configuration system: get/set/del/validate/migrate |
|
||
| `$ajax` | 837 | Rate-limited AJAX queue (300ms interval, max 4 concurrent) |
|
||
| `$re` | 947 | Random Encounter timer and notification |
|
||
| `$equip` | 1227 | Equipment parsing, sorting, filtering, namecode generation |
|
||
| `$item` | 1810 | Item inventory loading, counting, shop buying |
|
||
| `$price` | 1950 | Item price management, market integration |
|
||
| `$mail` | 2174 | MoogleMail send queue engine |
|
||
| `$battle` | 2416 | Battle side panel (equipment, items, repair) |
|
||
| `$dfct` | 3280 | Difficulty changer |
|
||
| `$persona` | 3340 | Persona/equip set changer |
|
||
|
||
### Page-Specific Modules
|
||
|
||
| Module | Line | Page |
|
||
|--------|------|------|
|
||
| `_ch` | 3820 | Character: EXP simulator, stats parsing |
|
||
| `_eq` | 3923 | Equipment: popups, charms, mage stats, equip code |
|
||
| `_ab` | 4097 | Abilities: slotbar parsing, tree parsing, ability simulator |
|
||
| `_tr` | 4468 | Training: queue planning, cost calculation, auto-start |
|
||
| `_it` | 4676 | Item Inventory: type coloring |
|
||
| `_se` | 4704 | Settings: preset save/load |
|
||
| `_is` | 4807 | Item Shop: type coloring |
|
||
| `_ss` | 4833 | Shrine: bulk offering, reward tracking, trophy system |
|
||
| `_mk` | 5374 | Market: price display, order checking, crystal pack |
|
||
| `_ml` | 5486 | Monster Lab: list, feeding, upgrades, PLC |
|
||
| `_mm` | 6870 | MoogleMail: compose UI, item/equip/credits attach |
|
||
| `_lt` | 8500 | Lottery: notification toggle, golden ticket confirm |
|
||
| `_ar` | 8560 | Arena/RoB: layout adjustment |
|
||
| `$armory` | 8611 | Equipment Shop: unified list, protect/bazaar filters, salvage calc |
|
||
| `_mo` | 9670 | Modify (single equip): upgrade cost display |
|
||
|
||
### Key Utility Functions
|
||
|
||
| Function | Line | Purpose |
|
||
|----------|------|---------|
|
||
| `$id` / `$qs` / `$qsa` / `$xpath` | 191-194 | DOM selectors |
|
||
| `$doc` | 195 | HTML string → Document |
|
||
| `$element` | 196 | Element builder with attributes, events, children |
|
||
| `$input` | 197 | Form input builder (text/checkbox/select/number) |
|
||
| `time_format` | 198 | ms → HH:MM:SS / HH:MM / MM:SS |
|
||
| `date_format` | 199 | Unix timestamp → YY-MM-DD HH:MM |
|
||
| `parse_count` | 200 | "1,234" → 1234 |
|
||
| `parse_price` | 201 | "10m"/"500k" → number |
|
||
| `split2` | 202 | "key:value" → ["key", "value"] |
|
||
| `scrollIntoView` | 203 | Scroll parent to show child |
|
||
| `confirm_event` | 204 | Add confirmation to onclick handlers |
|
||
| `toggle_button` | 205 | Toggle button text based on CSS class |
|
||
| `play_beep` | 206 | Web Audio API beep |
|
||
| `popup` | 207 | Modal overlay |
|
||
| `popup_text` | 208 | Modal with textarea |
|
||
| `get_message` | 209 | Parse server message box |
|
||
| `$equip.filter.test` | 1609 | Filter expression evaluator (&&, \|\|, !, $Quality+, $pab=, $prefix, $level) |
|
||
| `$equip.namecode` | 1696 | Forum BBcode name decorator |
|
||
| `$equip.parse.name` | 1300 | Name regex parser (quality, prefix, type, slot, suffix) |
|
||
| `$equip.parse.elem` | 1397 | DOM element → equipment object |
|
||
| `$equip.parse.dynjs` | 1361 | dynjs_equip data → equipment object |
|
||
|
||
---
|
||
|
||
## 15. MARKET INTEGRATION
|
||
|
||
### Price System (`$price`, Lines 1950–2171)
|
||
|
||
**Storage:** `hvut_prices` — object mapping item names to credit values
|
||
|
||
**Item Groups (Lines 1953-1971):**
|
||
- **Consumables:** Health/Mana/Spirit Draughts/Potions/Elixirs, Energy Drinks, Caffeinated Candy, Infusions, Scrolls, Flower Vases, Bubble-Gum
|
||
- **Materials:** Grade materials, Scraps, Energy Cells, Phazon, Shade Fragment, Repurposed Actuator, Defense Matrix Modulator, Bindings (33 types), Weapon/Staff/Armor Cores, Shards
|
||
- **Trophies:** All 12 trophies
|
||
- **Crystals:** All 12 crystal types
|
||
- **Figures:** All 27 figurine types
|
||
|
||
**Isekai Filtering (Line 1982-1989):**
|
||
- Removes: Last Elixir, Energy Drink, Caffeinated Candy, Bindings, Crystals, Figures
|
||
- These items don't exist on Isekai server
|
||
|
||
**Market Data Fetching (Line 2101-2149):**
|
||
```js
|
||
$price.parse_market(filter, doc)
|
||
```
|
||
- Parses the market item list table (`#market_itemlist table`)
|
||
- Extracts: item name, item ID, your stock, market bid, market ask, market stock
|
||
- Caches in `$price.market[name]` = `{ itemid, stock, bid, ask, market_stock }`
|
||
- Filter names: `co` (consumables), `ma` (materials), `tr` (trophies), `ar` (artifacts), `fi` (figures), `mo` (monster food)
|
||
|
||
**Market Price Update (Line 2125-2149):**
|
||
- `$price.update_market(filter, key, save)`: Fetches current market data, extracts prices for specified key (bid/ask)
|
||
- Fetches all filters at once if `filter` is empty
|
||
|
||
**Market Integration Points:**
|
||
|
||
1. **Market Page (`_mk`):** Shows HVUT prices in extra column, highlighting mismatched orders
|
||
2. **Item Price Editor:** `$price.edit()` opens popup with "Bid"/"Ask" buttons to fetch market prices
|
||
3. **Equipment Salvage Calc:** Uses material prices from `$price.get('Materials')` to value salvage
|
||
4. **Monster Lab Gift Summary:** Uses `$price.value()` to estimate gift credit value
|
||
5. **Monster Lab Upgrade Cost:** Uses crystal prices to show upgrade costs
|
||
6. **Modify Page:** Shows total upgrade cost using material prices
|
||
7. **Crystal Pack:** On Monster Food market page, calculates aggregate crystal pack bid/ask
|
||
|
||
**Price Editor Popup (Line 2045-2088):**
|
||
- Textarea with `name @ price` format
|
||
- **Save:** Validates and saves
|
||
- **Bid/Ask:** Fetches market prices for specified key, replaces values
|
||
- **Edit All Items:** Switches to full price list
|
||
|
||
**Default Prices (Line 1972-1976):**
|
||
- Peerless Weapon/Staff/Armor Cores: 500,000 credits
|
||
|
||
---
|
||
|
||
## ARCHITECTURE SUMMARY
|
||
|
||
### Module Dependencies
|
||
```
|
||
$config (storage, settings)
|
||
↓
|
||
$ajax (network, 300ms/4conn rate limit)
|
||
↓
|
||
$equip (equipment parsing/filtering) ← $item (inventory) → $price (market)
|
||
↓ ↓
|
||
$re (RE timer) $battle (side panel) $mail (MM send)
|
||
↓
|
||
Page modules (_ch, _eq, _ab, _tr, _it, _se, _is, _ss, _mk, _ml, _mm, _lt, _ar, $armory, _mo)
|
||
↓
|
||
_top (top bar) + _bottom (bottom bar) — always active, uses _player and specific modules
|
||
```
|
||
|
||
### Design Patterns
|
||
- **Singleton modules:** All `$xxx` and `_xxx` objects are const-declared singletons
|
||
- **Lazy initialization:** Most modules have `init()` called only when their page matches
|
||
- **AJAX queue:** Central `$ajax` manages concurrency (max 4) and rate limiting (300ms interval)
|
||
- **Filter DSL:** The `$equip.filter` system implements a custom boolean expression evaluator for equipment matching
|
||
- **CSS variables:** All theming uses CSS custom properties, making re-skinning trivial
|
||
- **Storage namespacing:** Persistent (`hvut_`) and Isekai (`hvuti_`) have separate storage namespaces
|
||
- **Migration system:** Automatic data migration when version numbers don't match
|