promotional bannermobile promotional banner

Arcadia Lib

Arcadia Lib is the shared foundation required by all Arcadia Pets, Prestige and AH. It provides the database layer, player data management and debug mode.

File Details

arcadia-lib-1.2.14

  • R
  • Jun 9, 2026
  • 2.57 MB
  • 1.1K
  • 1.21.1
  • NeoForge

File Name

arcadia-lib-1.2.14.jar

Supported Versions

  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:arcadia-lib-1493170:8221587"
Curse Maven does not yet support mods that have disabled 3rd party sharing

Learn more about Curse Maven

## [1.2.14] - 2026-06-08 (latest)

### Fixed

- **Staff/ranked players lost ALL cosmetics when LuckPerms bound late (regression)** — `LuckPermsBackend.createOrFallback()` ran at `ServerAboutToStartEvent`; if LuckPerms had not finished registering its provider yet, `LuckPermsProvider.get()` threw, the backend resolved to `null`, and `PermissionService` fell back to `DENY` (fail-closed) for the whole session. Every `arcadia.cosmetic.*` check — wildcard included — then returned `false`, so staff and VIP/MVP players saw all cosmetics locked. The backend now **binds lazily**: when LuckPerms is not ready at init it defers and re-resolves the provider on first use, so wildcard and grade nodes work again as soon as LuckPerms is up. No hard-coded staff bypass introduced.
- **Permission checks raced ahead of LuckPerms' user cache** — `LuckPermsBackend` returned `false`/`default` when `getUserManager().getUser()` returned `null` (user not yet cached, e.g. a GUI built on the same tick as join). It now loads the user synchronously (`loadUser().join()`) as a fallback before checking.
- **Real LuckPerms init failure cause is now logged** — `createOrFallback()` logs the exception message (not just the class name) and distinguishes "not ready yet" from "genuinely absent".
- **`AchievementManager.loaded` visibility** — Made `volatile`: it is written by `init()` and read via `isLoaded()` from background DB/scheduler threads, so a reader could observe a stale value.

### Performance

- **`LuckPermsBackend.getGrade()` resolves permission data once** — was re-resolving `QueryOptions` context up to three times per call (MVP/VIP+/VIP probes); now probes all three grade nodes against a single resolved `PermissionData`.
- **`DashboardScreen` no longer recomputes carousel neighbours every frame** — prev/next nav targets (each doing a list alloc + sort) were recomputed in `render()` and `mouseClicked()`; now cached and refreshed only when the observed tab changes.
- **`ArcadiaHubScreen.drawCard()` drops redundant `Component` allocations** — label/sub-label were wrapped in a `Component.literal(translatable.getString())` every frame per card; now kept as translatables (language-correct) and resolved lazily only on the text-wrap path.
- **`TextFormatter.format()` single-pass placeholder replacement** — replaced the per-key `String.replace()` loop (a full scan + new `String` each key) with one regex pass; values are inserted literally via `quoteReplacement` and unknown `{keys}` are preserved, matching the old semantics.

### Correctifs

- **Les joueurs staff/gradés perdaient TOUS leurs cosmétiques quand LuckPerms se liait tard (régression)** — `LuckPermsBackend.createOrFallback()` s'exécutait au `ServerAboutToStartEvent` ; si LuckPerms n'avait pas fini d'enregistrer son provider, `LuckPermsProvider.get()` levait une exception, le backend valait `null`, et `PermissionService` retombait sur `DENY` (fail-closed) pour toute la session. Toute vérification `arcadia.cosmetic.*` — wildcard inclus — renvoyait alors `false`, donc le staff et les VIP/MVP voyaient tous les cosmétiques verrouillés. Le backend se **lie désormais paresseusement** : si LuckPerms n'est pas prêt à l'init, il diffère et re-résout le provider au premier usage, donc les nodes wildcard et de grade refonctionnent dès que LuckPerms est disponible. Aucun bypass staff codé en dur introduit.
- **Les vérifications de permission devançaient le cache utilisateur de LuckPerms** — `LuckPermsBackend` renvoyait `false`/`default` quand `getUserManager().getUser()` renvoyait `null` (utilisateur pas encore en cache, ex. un GUI construit au tick de la connexion). Il charge désormais l'utilisateur de façon synchrone (`loadUser().join()`) en repli avant de vérifier.
- **La vraie cause d'échec d'init LuckPerms est désormais journalisée** — `createOrFallback()` journalise le message de l'exception (pas seulement le nom de classe) et distingue « pas encore prêt » de « réellement absent ».
- **Visibilité de `AchievementManager.loaded`** — Passé en `volatile` : écrit par `init()` et lu via `isLoaded()` depuis des threads DB/scheduler en arrière-plan, un lecteur pouvait voir une valeur périmée.

### Performance

- **`LuckPermsBackend.getGrade()` résout les données de permission une seule fois** — re-résolvait le contexte `QueryOptions` jusqu'à trois fois par appel (sondes MVP/VIP+/VIP) ; sonde désormais les trois nodes de grade contre une unique `PermissionData` résolue.
- **`DashboardScreen` ne recalcule plus les voisins du carrousel à chaque frame** — les cibles nav prev/next (chacune avec une allocation de liste + tri) étaient recalculées dans `render()` et `mouseClicked()` ; désormais mises en cache et rafraîchies seulement quand l'onglet observé change.
- **`ArcadiaHubScreen.drawCard()` supprime des allocations `Component` redondantes** — le label/sous-label était enveloppé dans un `Component.literal(translatable.getString())` à chaque frame par carte ; conservé désormais en translatable (correct pour la langue) et résolu paresseusement uniquement sur le chemin de retour à la ligne.
- **`TextFormatter.format()` remplacement des placeholders en une passe** — remplacé la boucle `String.replace()` par clé (un scan complet + une nouvelle `String` par clé) par une unique passe regex ; les valeurs sont insérées littéralement via `quoteReplacement` et les `{clés}` inconnues sont préservées, conformément à l'ancienne sémantique.