You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 15:36:17 +00:00
107 lines
4.0 KiB
Markdown
107 lines
4.0 KiB
Markdown
# 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.
|
|
|
|
Supported configured reward types are credits, pixels/duckets, seasonal points, badges, furni items, and HC days.
|
|
|
|
## 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`
|
|
- `earnings.<category>.badge=`
|
|
- `earnings.<category>.item_id=0`
|
|
- `earnings.<category>.item.quantity=1`
|
|
- `earnings.<category>.hc.days=0`
|
|
|
|
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 and bounded item/HC limits.
|
|
- Roll back the claim record if a DB-backed reward grant fails.
|
|
- 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
|
|
- badge/item/HC reward rows are included in state
|
|
- failed reward grants roll back the claim record
|
|
|
|
Packet tests can remain light because renderer IDs may be finalized separately; the critical behavior is the server-side claim guard.
|