feat(diva): implement Diva Defense (UD) system

Add full Diva Defense / United Defense system: schema, repo layer,
i18n bead names, and RE-verified packet handler implementations.

Schema (0011_diva.sql): diva_beads, diva_beads_assignment,
diva_beads_points, diva_prizes tables; interception_maps/points
columns on guilds and guild_characters.

Seed (DivaDefaults.sql): 26 prize milestones for personal and
guild reward tracks (item_type=26 diva coins).

Repo (DivaRepo): 11 new methods covering bead assignment, point
accumulation, interception point tracking, prize queries, and
cleanup. Mocks wired in test_helpers_test.go.

i18n: Bead struct with EN/JP names for all 18 bead types (IDs
1–25). Session tracks currentBeadIndex (-1 = none assigned).

Packet handlers corrected against mhfo-hd.dll RE findings:
- GetKijuInfo: u8 count, 512-byte desc, color_id+bead_type per entry
- SetKiju: 1-byte ACK; persists bead assignment to DB
- GetUdMyPoint: 8×18-byte entries, no count prefix
- GetUdTotalPointInfo: u8 error + u64[64] + u8[64] + u64 (~585 B)
- GetUdSelectedColorInfo: u8 error + u8[8] = 9 bytes
- GetUdDailyPresentList: correct u16 count format (was wrong hex)
- GetUdNormaPresentList: correct u16 count format (was wrong hex)
- GetUdRankingRewardList: correct u16 count with u32 item_id/qty
- GetRewardSong: 22-byte layout with 0xFFFFFFFF prayer_end sentinel
- AddRewardSongCount: parse implemented (was NOT IMPLEMENTED stub)
This commit is contained in:
Houmgaor
2026-03-20 17:52:01 +01:00
parent 7ff033e36e
commit 2bd92c9ae7
13 changed files with 708 additions and 69 deletions

View File

@@ -0,0 +1,32 @@
-- Diva Defense default prize rewards.
-- Personal track: type='personal', quantity=1 per milestone.
-- Guild track: type='guild', quantity=5 per milestone.
-- item_type=26 is Diva Coins; item_id=0 for all.
INSERT INTO diva_prizes (type, points_req, item_type, item_id, quantity, gr, repeatable) VALUES
('personal', 500000, 26, 0, 1, false, false),
('personal', 1000000, 26, 0, 1, false, false),
('personal', 2000000, 26, 0, 1, false, false),
('personal', 3000000, 26, 0, 1, false, false),
('personal', 5000000, 26, 0, 1, false, false),
('personal', 7000000, 26, 0, 1, false, false),
('personal', 10000000, 26, 0, 1, false, false),
('personal', 15000000, 26, 0, 1, false, false),
('personal', 20000000, 26, 0, 1, false, false),
('personal', 30000000, 26, 0, 1, false, false),
('personal', 50000000, 26, 0, 1, false, false),
('personal', 70000000, 26, 0, 1, false, false),
('personal', 100000000, 26, 0, 1, false, false),
('guild', 500000, 26, 0, 5, false, false),
('guild', 1000000, 26, 0, 5, false, false),
('guild', 2000000, 26, 0, 5, false, false),
('guild', 3000000, 26, 0, 5, false, false),
('guild', 5000000, 26, 0, 5, false, false),
('guild', 7000000, 26, 0, 5, false, false),
('guild', 10000000, 26, 0, 5, false, false),
('guild', 15000000, 26, 0, 5, false, false),
('guild', 20000000, 26, 0, 5, false, false),
('guild', 30000000, 26, 0, 5, false, false),
('guild', 50000000, 26, 0, 5, false, false),
('guild', 70000000, 26, 0, 5, false, false),
('guild', 100000000, 26, 0, 5, false, false)
ON CONFLICT DO NOTHING;

View File

@@ -0,0 +1,44 @@
-- Diva Defense (United Defense) extended schema.
-- Adds bead selection, per-bead point accumulation, interception points,
-- and prize reward tables for personal and guild tracks.
-- Interception map data per guild (binary blob, existing column pattern).
ALTER TABLE guilds ADD COLUMN IF NOT EXISTS interception_maps bytea;
-- Per-character interception points keyed by quest file ID.
ALTER TABLE guild_characters ADD COLUMN IF NOT EXISTS interception_points jsonb NOT NULL DEFAULT '{}';
-- Prize reward table for personal and guild tracks.
CREATE TABLE IF NOT EXISTS diva_prizes (
id SERIAL PRIMARY KEY,
type VARCHAR(10) NOT NULL CHECK (type IN ('personal', 'guild')),
points_req INTEGER NOT NULL,
item_type INTEGER NOT NULL,
item_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
gr BOOLEAN NOT NULL DEFAULT false,
repeatable BOOLEAN NOT NULL DEFAULT false
);
-- Active bead types for the current Diva Defense event.
CREATE TABLE IF NOT EXISTS diva_beads (
id SERIAL PRIMARY KEY,
type INTEGER NOT NULL
);
-- Per-character bead slot assignments with expiry.
CREATE TABLE IF NOT EXISTS diva_beads_assignment (
id SERIAL PRIMARY KEY,
character_id INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
bead_index INTEGER NOT NULL,
expiry TIMESTAMPTZ NOT NULL
);
-- Per-character bead point accumulation log.
CREATE TABLE IF NOT EXISTS diva_beads_points (
id SERIAL PRIMARY KEY,
character_id INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
bead_index INTEGER NOT NULL,
points INTEGER NOT NULL,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW()
);