feat(diva): implement Diva Defense point accumulation (#168)

RE'd putAdd_ud_point (FUN_114fd490) and putAdd_ud_tactics_point
(FUN_114fe9c0) from the ZZ client DLL via Ghidra decompilation.

MsgMhfAddUdPoint fields: QuestPoints (sum of 11 category accumulators
earned per quest) and BonusPoints (kiju prayer song multiplier extra).
MsgMhfAddUdTacticsPoint fields: QuestID and TacticsPoints.

Adds diva_points table (migration 0009) for per-character per-event
point tracking, with UPSERT-based atomic accumulation in the handler.
This commit is contained in:
Houmgaor
2026-03-18 12:09:44 +01:00
parent 61d85e749f
commit 792dcd5d91
10 changed files with 217 additions and 18 deletions

View File

@@ -38,3 +38,40 @@ func (r *DivaRepository) GetEvents() ([]DivaEvent, error) {
err := r.db.Select(&result, "SELECT id, (EXTRACT(epoch FROM start_time)::int) as start_time FROM events WHERE event_type='diva'")
return result, err
}
// AddPoints atomically adds quest and bonus points for a character in a diva event.
func (r *DivaRepository) AddPoints(charID, eventID, questPoints, bonusPoints uint32) error {
_, err := r.db.Exec(`
INSERT INTO diva_points (char_id, event_id, quest_points, bonus_points, updated_at)
VALUES ($1, $2, $3, $4, now())
ON CONFLICT (char_id, event_id) DO UPDATE
SET quest_points = diva_points.quest_points + EXCLUDED.quest_points,
bonus_points = diva_points.bonus_points + EXCLUDED.bonus_points,
updated_at = now()`,
charID, eventID, questPoints, bonusPoints)
return err
}
// GetPoints returns the accumulated quest and bonus points for a character in an event.
func (r *DivaRepository) GetPoints(charID, eventID uint32) (int64, int64, error) {
var qp, bp int64
err := r.db.QueryRow(
"SELECT quest_points, bonus_points FROM diva_points WHERE char_id=$1 AND event_id=$2",
charID, eventID).Scan(&qp, &bp)
if err != nil {
return 0, 0, err
}
return qp, bp, nil
}
// GetTotalPoints returns the sum of all players' quest and bonus points for an event.
func (r *DivaRepository) GetTotalPoints(eventID uint32) (int64, int64, error) {
var qp, bp int64
err := r.db.QueryRow(
"SELECT COALESCE(SUM(quest_points),0), COALESCE(SUM(bonus_points),0) FROM diva_points WHERE event_id=$1",
eventID).Scan(&qp, &bp)
if err != nil {
return 0, 0, err
}
return qp, bp, nil
}