docs(earnings): define emulator rewards center

This commit is contained in:
simoleo89
2026-06-15 20:25:48 +02:00
parent c48e01cb8e
commit dac83e8a62
2 changed files with 182 additions and 0 deletions
@@ -0,0 +1,85 @@
# Earnings Center Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build an emulator-owned earnings/rewards hub for the new "Guadagni" UI, with server-side reward definitions and claim protection.
**Architecture:** Add a focused earnings package under `com.eu.habbo.habbohotel.earnings`, wire three incoming handlers and two outgoing composers, and persist claims in a dedicated table with a unique period key. Keep reward definitions config-driven so UI/renderer work can progress independently.
**Tech Stack:** Java 21, Maven, MariaDB SQL updates, existing Arcturus packet manager/composer patterns, JUnit tests.
---
### Task 1: Map Existing Patterns
**Files:**
- Read: `Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java`
- Read: `Emulator/src/main/java/com/eu/habbo/messages/PacketNames.java`
- Read: `Emulator/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java`
- Read: `Emulator/src/main/java/com/eu/habbo/messages/outgoing/MessageComposer.java`
- [ ] Inspect packet registration and composer header lookup.
- [ ] Inspect currency grant methods on `Habbo`.
- [ ] Inspect emulator setting access APIs.
- [ ] Choose the smallest implementation that matches existing style.
### Task 2: Add Earnings Domain
**Files:**
- Create: `Emulator/src/main/java/com/eu/habbo/habbohotel/earnings/EarningsCategory.java`
- Create: `Emulator/src/main/java/com/eu/habbo/habbohotel/earnings/EarningsReward.java`
- Create: `Emulator/src/main/java/com/eu/habbo/habbohotel/earnings/EarningsEntry.java`
- Create: `Emulator/src/main/java/com/eu/habbo/habbohotel/earnings/EarningsClaimResult.java`
- Create: `Emulator/src/main/java/com/eu/habbo/habbohotel/earnings/EarningsCenterManager.java`
- [ ] Define allowlisted categories and client keys.
- [ ] Load enabled flags, cooldowns, and reward values from configuration.
- [ ] Build row state for a user.
- [ ] Implement single claim and claim-all.
- [ ] Grant credits/pixels/points through existing `Habbo` APIs.
### Task 3: Add Persistence
**Files:**
- Create: `Database Updates/012_earnings_center.sql`
- [ ] Create `users_earnings_claims`.
- [ ] Add unique key on `user_id`, `category`, `period_key`.
- [ ] Keep the migration additive and safe for existing databases.
### Task 4: Add Packet Bridge
**Files:**
- Create: `Emulator/src/main/java/com/eu/habbo/messages/incoming/earnings/RequestEarningsCenterEvent.java`
- Create: `Emulator/src/main/java/com/eu/habbo/messages/incoming/earnings/ClaimEarningsRewardEvent.java`
- Create: `Emulator/src/main/java/com/eu/habbo/messages/incoming/earnings/ClaimAllEarningsRewardsEvent.java`
- Create: `Emulator/src/main/java/com/eu/habbo/messages/outgoing/earnings/EarningsCenterComposer.java`
- Create: `Emulator/src/main/java/com/eu/habbo/messages/outgoing/earnings/EarningsClaimResultComposer.java`
- Modify: packet registration/mapping files discovered in Task 1.
- [ ] Incoming handlers parse only category keys.
- [ ] Outgoing composers serialize rows and claim results.
- [ ] Packet names are documented for renderer alignment.
### Task 5: Test and Build
**Files:**
- Create: `Emulator/src/test/java/com/eu/habbo/habbohotel/earnings/EarningsCenterManagerTest.java`
- [ ] Test disabled feature behavior.
- [ ] Test unknown category rejection.
- [ ] Test single claim success.
- [ ] Test duplicate claim rejection.
- [ ] Test claim-all partial success.
- [ ] Run focused tests.
- [ ] Run `mvn clean package`.
### Task 6: Commit and PR
**Files:**
- Commit all source, test, SQL, spec, and plan files.
- [ ] Commit spec and plan.
- [ ] Commit implementation.
- [ ] Push `feat/earnings-center` to `simoleo89/Arcturus-Morningstar-Extended`.
- [ ] Open ready-for-review PR to `duckietm/Arcturus-Morningstar-Extended:dev`.
@@ -0,0 +1,97 @@
# Earnings Center Design
## Goal
Add an emulator-owned rewards hub for the "Guadagni" UI. The client and renderer may decide how it looks, but the emulator must own reward amounts, claim eligibility, cooldowns, and anti-abuse checks.
## Scope
The first emulator version exposes ten earnings categories:
- `daily_gift`
- `games`
- `achievements`
- `marketplace`
- `hc_payday`
- `level_progress`
- `donations`
- `bonus_bag`
- `mystery_boxes`
- `club_job`
Every category can be enabled, disabled, configured with one or more reward currencies, and claimed through a single-row claim or a claim-all request. Categories that are not yet backed by a native hotel subsystem still work through static configuration, so the UI contract is stable while deeper integrations are added later.
## Architecture
Add a focused `com.eu.habbo.habbohotel.earnings` package:
- `EarningsCenterManager` loads category definitions from emulator settings, builds per-user state, and performs claims.
- `EarningsCategory` is the allowlisted category enum and carries the client key.
- `EarningsReward` represents one configured reward.
- `EarningsEntry` is the serializable row state sent to the client.
- `EarningsClaimResult` reports single/all claim outcomes.
The packet layer only parses category keys and delegates to the manager. The client never sends amounts, cooldowns, or reward definitions.
## Persistence
Add a database update that creates `users_earnings_claims`:
- `id`
- `user_id`
- `category`
- `period_key`
- `claimed_at`
- unique key on `user_id`, `category`, `period_key`
The unique key is the main double-claim guard. `period_key` is calculated by the emulator from the category cooldown. Daily-style rewards use the UTC date key by default. One-time or long cooldown rows can use the cooldown bucket derived from `claimed_at`.
## Configuration
Add emulator settings with safe defaults:
- `earnings.enabled=0`
- `earnings.<category>.enabled=1`
- `earnings.<category>.cooldown.seconds=86400`
- `earnings.<category>.credits=0`
- `earnings.<category>.pixels=0`
- `earnings.<category>.points=0`
- `earnings.<category>.points.type=5`
The feature defaults off so existing hotels do not receive surprise economy changes after deploying the jar.
## Packet Contract
Add three incoming handlers:
- `RequestEarningsCenterEvent`
- `ClaimEarningsRewardEvent`
- `ClaimAllEarningsRewardsEvent`
Add two outgoing composers:
- `EarningsCenterComposer`
- `EarningsClaimResultComposer`
Composer format is intentionally simple and renderer-friendly: category key, enabled state, claimable state, next claim timestamp, rewards, and result code. Header IDs must be wired through `messages.ini`/packet registration in the same style as the rest of the emulator. If the renderer side chooses final IDs later, only the packet mapping should need adjustment.
## Security
- Reject unknown category keys.
- Reject all claims when `earnings.enabled=0`.
- Never trust reward amounts from the client.
- Clamp configured rewards to non-negative values.
- Use the database unique key to prevent concurrent double claims.
- `claim all` processes only claimable rows and returns per-category results.
## Tests
Add unit tests around the manager-level logic:
- disabled global feature returns disabled rows and rejects claims
- unknown category is rejected
- successful claim grants configured currency once
- duplicate claim in the same period is rejected
- claim-all grants all claimable rows and skips already claimed rows
Packet tests can remain light because renderer IDs may be finalized separately; the critical behavior is the server-side claim guard.