Overview
TheCosmeticService (features/cosmetic/CosmeticService.kt:51) manages cosmetic loading, caching, and rendering with a focus on performance and reduced API stress.
How It Works
Carrier-Based System
Rather than checking every player, the system uses a carrier-based approach:Refresh Carriers
Downloads a list of MD5-hashed UUIDs of players who have cosmetics (CosmeticService.kt:73)
Cosmetic Categories
The system supports multiple cosmetic types throughCosmeticCategory:
- Capes
- Other cosmetic items (extensible)
Fetching Cosmetics
For Any Player
- Checks if the UUID is in the carrier list
- Returns cached cosmetics if available
- Fetches from API if needed
- Calls the callback when ready
For Current User
The current user’s cosmetics are handled specially (CosmeticService.kt:103-120):Carrier Management
Refresh Timing
Carriers are refreshed every 60 seconds:Manual Refresh
force parameter bypasses the delay check (CosmeticService.kt:73-97).
Caching System
Carrier Cache
MD5-hashed UUIDs of cosmetic carriers:Cosmetic Cache
Fetched cosmetics mapped by player UUID:Pre-allocation
To prevent duplicate API requests, the system pre-allocates empty sets:Temporary Ownership
Transferring Cosmetics
Users can temporarily transfer cosmetic ownership to their current session:Benefits
- Allows testing cosmetics on alt accounts
- Maintains cosmetic display when switching accounts
- Automatically refreshes carrier list after transfer
Client Account Integration
TheClientAccountManager handles the authenticated user’s cosmetics:
Checking Cosmetic Availability
Event Handling
Session Events
Automatically handles cosmetic transfers when logging into accounts.Disconnect Events
Clears the cosmetic cache on disconnect to free memory:Performance Optimization
Reduced API Stress
The carrier-based approach means:- Only players with cosmetics trigger API calls
- Carrier list is shared across all cosmetic types
- Updates happen at most once per minute
Asynchronous Loading
All API calls use coroutines:Smart Caching
- Carrier list cached for 60 seconds
- Individual cosmetics cached until disconnect
- Current user cosmetics use client account (no extra API calls)
Error Handling
The service gracefully handles failures:Usage Example
API Integration
The service uses the official LiquidBounce API:CosmeticApi.getCarriers()- Get list of cosmetic carriersCosmeticApi.getCarrierCosmetics(uuid)- Get cosmetics for a specific playerclientAccount.updateCosmetics()- Update current user’s cosmeticsclientAccount.transferTemporaryOwnership(uuid)- Transfer cosmetics to session