feat(m4): player self-service & game data
All checks were successful
PR Checks / android-build (pull_request) Successful in 10m18s

Account self-service over the role-agnostic /auth/me/account* surface
(change username/password, TOTP enroll/disable, linked SSO identities),
game-account linking ([link one-time code + hybrid signup gated on the
public gameAccountSignup flag), and text-only own game data: per-account
character roster -> character sheet (attributes/vitals/resistances/skills/
equipment + guild/governor standing), player vendors + recent sales, and
own houses (decay/IDOC).

Adds three PLAYER-access menu groups (My Characters/Vendors/Houses)
revealed only when the session role is player, with a PlayerGate that
sends a signed-out or server-side-demoted user home. Each per-account
read carries its own load state, so a down shard (503) degrades that
account to offline/retry without blocking the rest (7).

Pure consumer of the existing bearer API -- no backend/protocol change.
17 new JVM unit tests cover the account + player-shard DTO decode (hex
serials, permissive objects, equipment mods) and the character-sheet
title/skill display helpers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
This commit is contained in:
2026-07-19 22:33:22 -05:00
committed by Claude
parent ca704caaaf
commit d4f7fcb241
25 changed files with 2546 additions and 34 deletions

View File

@@ -42,6 +42,9 @@
<string name="menu_about">About</string>
<string name="menu_contact">Contact</string>
<string name="menu_account">My account</string>
<string name="menu_my_characters">My characters</string>
<string name="menu_my_vendors">My vendors</string>
<string name="menu_my_houses">My houses</string>
<string name="menu_sign_in">Sign in</string>
<string name="menu_sign_out">Sign out</string>
<string name="menu_change_server">Change server</string>
@@ -67,6 +70,112 @@
<string name="account_title">My account</string>
<string name="account_sign_out">Sign out</string>
<string name="account_sign_out_all">Sign out on all devices</string>
<!-- Username -->
<string name="account_username_title">Username</string>
<string name="account_username_action">Change username</string>
<string name="account_username_changed">Username updated.</string>
<string name="account_username_taken">That username is already taken.</string>
<string name="account_username_error">Couldn\'t change your username.</string>
<!-- Password -->
<string name="account_password_title">Password</string>
<string name="account_password_set_title">Set a password</string>
<string name="account_password_set_hint">Your account was created through a linked provider and has no password yet. Set one to also sign in with a username and password.</string>
<string name="account_password_current">Current password</string>
<string name="account_password_new">New password</string>
<string name="account_password_action">Change password</string>
<string name="account_password_set_action">Set password</string>
<string name="account_password_changed">Password changed.</string>
<string name="account_password_error">Couldn\'t change your password. Check your current password and try again.</string>
<!-- Two-factor -->
<string name="account_totp_title">Two-factor authentication</string>
<string name="account_totp_on">Enabled</string>
<string name="account_totp_off">Not enabled</string>
<string name="account_totp_scan">Scan this code with your authenticator app, then enter the current code.</string>
<string name="account_totp_qr_desc">Two-factor QR code</string>
<string name="account_totp_setup">Set up two-factor</string>
<string name="account_totp_confirm">Confirm &amp; enable</string>
<string name="account_totp_cancel">Cancel</string>
<string name="account_totp_disable">Disable two-factor</string>
<string name="account_totp_enabled">Two-factor is now enabled.</string>
<string name="account_totp_disabled">Two-factor has been disabled.</string>
<string name="account_totp_code_error">That code isn\'t valid. Try the current code.</string>
<string name="account_totp_setup_error">Couldn\'t start two-factor setup.</string>
<!-- Linked identities -->
<string name="account_identities_title">Linked accounts</string>
<string name="account_identities_empty">No linked sign-in providers.</string>
<string name="account_identity_unlink">Unlink</string>
<string name="account_identity_unlinked">Account unlinked.</string>
<string name="account_identity_error">Couldn\'t unlink that account.</string>
<!-- ── Player: game-account linking (§6.3) ─────────────────────────── -->
<string name="player_link_title">Link your game account</string>
<string name="player_link_hint">In game, type [link to get a one-time code, then enter it here to see your characters, vendors and houses.</string>
<string name="player_link_code">Link code</string>
<string name="player_link_action">Link account</string>
<string name="player_link_ok">Account linked.</string>
<string name="player_link_bad_code">That code is unknown or has expired. Run [link in game for a new one.</string>
<string name="player_link_error">Couldn\'t link that code. Please try again.</string>
<string name="player_create_title">Create a game account</string>
<string name="player_create_account">Account name</string>
<string name="player_create_password">Password</string>
<string name="player_create_action">Create account</string>
<string name="player_create_ok">Game account created and linked.</string>
<string name="player_create_taken">That account name is already taken.</string>
<string name="player_create_capped">The account limit for your network has been reached.</string>
<string name="player_create_unavailable">Game-account signup isn\'t available right now.</string>
<string name="player_create_rejected">That account name or password wasn\'t accepted.</string>
<string name="player_create_error">Couldn\'t create that account. Please try again.</string>
<!-- ── Player: characters (§6.3) ───────────────────────────────────── -->
<string name="player_characters_empty">Link a game account above to see your characters.</string>
<string name="player_roster_loading">Loading…</string>
<string name="player_roster_empty">No characters on this account.</string>
<string name="player_char_unknown">Unknown</string>
<string name="player_char_online">Online</string>
<string name="player_char_offline">Offline</string>
<!-- Character sheet -->
<string name="player_char_governor">Governor of %1$s</string>
<string name="player_char_guildmaster">Guildmaster, %1$s</string>
<string name="player_char_attributes">Attributes</string>
<string name="player_char_str">STR</string>
<string name="player_char_dex">DEX</string>
<string name="player_char_int">INT</string>
<string name="player_char_hits">Hits</string>
<string name="player_char_mana">Mana</string>
<string name="player_char_stam">Stamina</string>
<string name="player_char_resistances">Resistances</string>
<string name="player_char_phys">Physical</string>
<string name="player_char_fire">Fire</string>
<string name="player_char_cold">Cold</string>
<string name="player_char_pois">Poison</string>
<string name="player_char_energy">Energy</string>
<string name="player_char_skills">Skills</string>
<string name="player_char_equipment">Equipment</string>
<string name="player_char_item">Item</string>
<string name="player_char_item_id">id %1$d</string>
<string name="player_char_item_hue">hue %1$d</string>
<!-- ── Player: vendors &amp; sales (§6.3) ──────────────────────────── -->
<string name="player_sales_title">Recent sales</string>
<string name="player_sales_empty">No recent sales.</string>
<string name="player_gold_amount">%1$s gp</string>
<string name="player_vendors_no_accounts">Link a game account to see your vendors.</string>
<string name="player_vendors_empty">No vendors on this account.</string>
<string name="player_vendor_fallback">Player vendor</string>
<string name="player_vendor_hold">Holding %1$s gp</string>
<string name="player_vendor_no_listings">No items listed.</string>
<string name="player_listing_item">Item %1$d ×%2$d</string>
<!-- ── Player: houses (§6.3) ───────────────────────────────────────── -->
<string name="player_houses_empty">You don\'t have any houses on your linked accounts.</string>
<string name="player_house_fallback">A house</string>
<string name="player_house_stage">Status: %1$s</string>
<string name="role_player">Player</string>
<string name="role_moderator">Moderator</string>
<string name="role_editor">Editor</string>