OniriaEconomy-1.0.4.jar
Curse Maven Snippet
What's new
EN
✨ Added
- Automatic admin-editor saving: after saving a package/item, deleting one, or moving an entry with
↑/↓,shop.jsonis validated and persisted immediately. A discreet action-bar confirmation is shown; the manual save button remains as a fallback. - Focused color cues: the OCS balance is now gold, and each label (
Pack,Item,Command,Rank,Chunk,NPC) has its own muted color without bringing multiple colors back to the rest of the interface. - Online-player picker: the “Targeted management” and “Reset limited purchases” fields now have a
▼button opening a searchable list of currently connected players. Manual input remains available. - Cleaner visual redesign: unified charcoal and steel-blue palette, simplified backdrop, quieter cards, consistent badges, and buttons without multiple competing colors. Red remains reserved for destructive actions, with no screen behavior changes.
- Shop organized with dynamic categories. Every
categoryvalue creates a filtering tab, with navigation for more than three categories and automatic legacy fallback togeneral. - Visual item reordering.
↑and↓buttons in the admin editor change the global order and the order inside categories without manual JSON editing. - Automatic FR/US language. Main screens, administration, editor, confirmations, and server messages now use Minecraft translatable components and follow each player's
fr_froren_usselection. - Language parity test ensures that French and English files expose the same keys.
- Configurable chunk purchase limit.
- New
max_purchasable_chunksoption inconfig/oniria_economy.toml([security]section, default: 10, range 0–100000). Replaces the previously hard-coded value. - All chunk-related messages now show the real configured limit (instead of the fixed "10").
- New
- New admin command
/ocsadmin chunkreset <player> [amount](OP level 4).- Without
[amount]: fully resets the player's chunk-purchase counter to 0. - With
[amount]: removes (refunds) that many chunks from the player's purchase counter. - The target player must be online; the action is logged (
CHUNK_RESET).
- Without
- Direct FTBRanks API integration (optional dependency, no compile-time coupling).
- New
FtbRanksIntegrationclass that talks to the FTBRanks API (MC 1.21.1 / v2101.x) via reflection: the mod still compiles and starts even when FTBRanks is absent. - Rank granting and removal are now performed directly through the API (
Rank.add/Rank.remove) instead of text commands (ftbranks add/remove). - Immediate persistence of the
players.snbtfile after every grant/removal (forcedsavePlayersNow()call), removing the write latency caused by FTBRanks' deferred auto-save. - Declared FTBRanks as an optional dependency in
neoforge.mods.toml(ordering = AFTER) to guarantee runtime detection.
- New
- Minutes display in the remaining time of rank subscriptions (shop, "Subscriptions" tab).
- Format
1d 23h 5m, with clean omission of leading zero units (e.g.23h 5m,5m) and anExpiredlabel when the subscription has run out.
- Format
🐛 Fixed
- PayPal cancellation is now handled. The screen remains open after launching the browser, provides an explicit cancel button, and automatically cancels if closed before the link is opened or copied.
/ocs cancelcancels after the browser was closed. The server checks PayPal first: an already-approved payment is finalized and credited instead of cancelled. - Hardened FTBRanks suggestions: IDs are read from the live FTBRanks manager first. The fallback no longer parses all of
ranks.snbtwithTagParser; it extracts root keys only and tolerates comments, apostrophes, and formatting text without raisingFTBRANKS_SUGGESTIONS_LOAD. - Fixed the rank editor: entries can no longer be saved with an empty FTBRanks id. The editor stays open, clearly identifies the required field, and validates the catalog locally before sending it to the server. Existing invalid entries now report the article name and expected correction.
- Complete PayPal flow hardening.
- Enforced the configured rate limit and one active order per player.
- Atomically persisted pending orders, resumed them after restart, and automatically credited offline players.
- Verified the order id, player binding, captured amount, and currency before any credit.
- Idempotent crediting: a PayPal order id can never grant OCS twice, including across crashes.
- Added HTTP timeouts, response-status validation, short OAuth token caching, and PayPal-domain approval URL validation.
- Each package currency is now the currency actually sent to and verified with PayPal.
- Fixed PayPal credential detection:
USE_SECRET_FILEplaceholders are no longer accepted as valid credentials. - Hardened secret storage with atomic writes, POSIX
600permissions, input validation, and missing AES-key detection without silently replacing it. - Transactional
shop.jsonvalidation.- Every package and entry is validated before writing (types, limits, items, prices, currency, required fields, and duplicate
purchase_idvalues). - Invalid configuration is rejected without replacing the file or active catalog.
- Every package and entry is validated before writing (types, limits, items, prices, currency, required fields, and duplicate
- Hardened persistent balances with legacy-format migration, atomic saves, and integer-overflow protection.
- FTBRanks mutation results are now respected: boolean returns from
Rank.addandRank.removeare no longer ignored; API refusal is reported as failure and a refused purchase is refunded. - Fixed Keep It protection for split stacks.
- A protection id is now authorized only for the quantity actually held before opening a corpse.
- Owning one item from a split stack no longer authorizes looting every other item with the same id.
- New purchased items store the buyer UUID, and Corpse compatibility fails closed when the corpse owner cannot be determined.
- Easy NPC follow wand now works for non-OP players.
- Ownership and the
follow ownerobjective are read and updated directly through the Easy NPC 6.17 API, with a server-command fallback for older versions. - The visible NPC name is no longer used for targeting: the clicked entity is always identified by its real UUID.
- Ownership and the
- Purchasing a renamed NPC.
- Import now uses the stable preset path and a server-generated entity UUID; changing the model's visible name no longer prevents future purchases from spawning it.
- The buyer is explicitly assigned as owner before follow mode is enabled.
- The editor no longer offers internal/display names read from NBT as if they were preset identifiers.
- Atomic purchase delivery: when an item, rank or NPC cannot be delivered, the charged OCS are refunded and the limited purchase is not recorded.
- Closed the chunk-limit bypass: chunk entries can no longer be purchased through the generic payload.
- False "You already own this rank" message when buying a rank the player does not actually own.
- The purchase check now relies on an exact in-memory verification through the FTBRanks API (
Rank.isAdded) instead of approximateplayers.snbtfile parsing. - Detection no longer confuses a rank with another one whose name contains it (e.g.
vipno longer falsely triggers onvip_plus).
- The purchase check now relies on an exact in-memory verification through the FTBRanks API (
- Slow
players.snbtupdates after a rank purchase/expiration: resolved by the forced immediate persistence (see Added). - Hardened fallback
players.snbtparsing: used only when the FTBRanks API is unavailable, it now performs an exact, case-insensitive rank-name match (no more substring false positives). - "Subscriptions" tab: the button used to show a generic "expires soon" text; it now shows the real countdown (days / hours / minutes).
🔁 Behavior changes
- Rank purchase/removal cleanly disabled when FTBRanks is absent.
- On purchase: clear message ("Rank purchase is unavailable: FTBRanks is not installed") and no OniriaCoins are charged.
- On expiration: removal is skipped and logged (
SKIPPED / ftbranks_unavailable) instead of running a no-op command.
🧹 Internal cleanup
- Added JUnit tests for FTBRanks mutations, Keep It allowances, and atomic writes (6 tests).
- Added a Java 21 GitHub Actions workflow that builds, runs tests, and uploads the mod JAR.
- Updated ModDevGradle to
2.0.143, added a runtime/secrets.gitignore, and fixed the executable bit on <button class="not-prose border-border-medium bg-surface-secondary hover:bg-surface-tertiary hover:border-border-strong group my-0.5 inline-flex items-center gap-1 rounded border px-1 py-0 text-left align-middle transition-colors" type="button">gradlew</button>. - Removed the now-unused
scheduleFtbranksReloadmethod (theftbranks reloadstep is no longer needed with the API integration). - Stronger grant safety: if the FTBRanks API fails to grant the rank (rank not found, etc.), the purchase is aborted and reported to the player.
Compatibility note
- Mod tested for NeoForge 21.1.231 (Minecraft 1.21.1), requires Java 21.
- FTBRanks is now required only for the shop's rank feature; it remains optional for everything else (shop, OniriaCoins, PayPal, chunks, NPC).
- The
rank_command_templateoption inconfig/oniria_economy.tomlis no longer used to grant ranks (kept for backwards compatibility; granting now goes through the FTBRanks API).
-----------------------------------------------------------------
FR
✨ Ajouts
- Sauvegarde automatique de l'éditeur admin : après l'enregistrement d'un pack/article, une suppression ou un déplacement
↑/↓,shop.jsonest validé puis sauvegardé immédiatement. Une confirmation discrète apparaît dans la barre d'action ; le bouton de sauvegarde manuelle reste disponible comme secours. - Repères colorés ciblés : le solde OCS est affiché en or et chaque étiquette (
Pack,Item,Commande,Rank,Chunk,NPC) possède maintenant sa propre couleur atténuée, sans réintroduire de couleurs sur le reste de l'interface. - Sélecteur de joueurs connectés : les champs « Gestion ciblée » et « Reset achats limités » disposent d'un bouton
▼ouvrant une liste recherchable des joueurs actuellement en ligne. La saisie manuelle reste disponible. - Refonte visuelle épurée : palette charbon et bleu acier unifiée, arrière-plan simplifié, cartes plus discrètes, badges harmonisés et boutons débarrassés des couleurs multiples. Le rouge reste réservé aux actions destructrices, sans modification du fonctionnement des écrans.
- Boutique organisée par catégories dynamiques. Chaque valeur
categorycrée un onglet filtrant les articles, avec navigation lorsque plus de trois catégories existent et compatibilité automatique des anciennes entrées viageneral. - Réorganisation visuelle des articles. Des boutons
↑et↓dans l'éditeur admin permettent de modifier l'ordre global et l'ordre à l'intérieur des catégories sans éditer le JSON manuellement. - Langue automatique FR/US. Les écrans principaux, l'administration, l'éditeur, les confirmations et les messages serveur utilisent désormais des composants traduisibles Minecraft et suivent
fr_frouen_ussélectionné par le joueur. - Test de parité linguistique garantissant que les fichiers français et anglais exposent les mêmes clés.
- Limite d'achat de chunks configurable.
- Nouvelle option
max_purchasable_chunksdansconfig/oniria_economy.toml(section[security], défaut : 10, plage 0–100000). Remplace l'ancienne valeur codée en dur. - Tous les messages liés aux chunks affichent désormais la limite réelle issue de la config (au lieu du « 10 » fixe).
- Nouvelle option
- Nouvelle commande admin
/ocsadmin chunkreset <joueur> [montant](OP niveau 4).- Sans
[montant]: réinitialise complètement le compteur d'achats de chunks du joueur à 0. - Avec
[montant]: retire (recrédite) ce nombre de chunks du compteur d'achats du joueur. - Le joueur cible doit être connecté ; l'action est tracée dans les logs (
CHUNK_RESET).
- Sans
- Intégration directe de l'API FTBRanks (dépendance optionnelle, sans couplage de compilation).
- Nouvelle classe
FtbRanksIntegrationqui parle à l'API FTBRanks (MC 1.21.1 / v2101.x) par réflexion : le mod compile et démarre même si FTBRanks est absent. - Attribution et retrait de rank désormais effectués directement via l'API (
Rank.add/Rank.remove) au lieu des commandes texte (ftbranks add/remove). - Persistance immédiate du fichier
players.snbtaprès chaque attribution/retrait (appel forcé desavePlayersNow()), ce qui élimine la latence d'écriture liée à la sauvegarde différée de FTBRanks. - Déclaration de FTBRanks comme dépendance optionnelle dans
neoforge.mods.toml(ordering = AFTER) pour garantir la détection au runtime.
- Nouvelle classe
- Affichage des minutes dans le temps restant des abonnements de rank (boutique, onglet « Abonnements »).
- Format
1j 23h 5m, avec omission propre des unités nulles de tête (ex.23h 5m,5m) et mentionExpirélorsque l'abonnement est écoulé.
- Format
🐛 Corrections
- Annulation PayPal prise en compte. L'écran reste ouvert après l'ouverture du navigateur, propose un bouton d'annulation explicite et annule automatiquement si le joueur ferme l'écran avant d'ouvrir/copier le lien. La commande
/ocs cancelpermet d'annuler après avoir fermé le navigateur. Le serveur vérifie d'abord le statut PayPal : un paiement déjà approuvé est finalisé et crédité plutôt qu'annulé. - Suggestions FTBRanks fiabilisées : les IDs sont récupérés en priorité depuis le gestionnaire FTBRanks actif. Le fallback ne parse plus tout
ranks.snbtavecTagParseret extrait uniquement les clés racine, ce qui tolère les commentaires, apostrophes et formats de texte sans générer l'alerteFTBRANKS_SUGGESTIONS_LOAD. - Éditeur de ranks corrigé : une entrée ne peut plus être enregistrée avec un identifiant FTBRanks vide. L'éditeur reste ouvert, indique clairement le champ obligatoire et valide localement le catalogue avant de l'envoyer au serveur. Les anciennes entrées invalides affichent maintenant le nom de l'article et la correction attendue.
- Durcissement complet du flux PayPal.
- Application du rate limit configuré et blocage de plusieurs ordres simultanés par joueur.
- Persistance atomique des ordres, reprise après redémarrage et crédit automatique des joueurs hors ligne.
- Vérification de l'identifiant, du rattachement au joueur, du montant et de la devise réellement capturés avant tout crédit.
- Crédit idempotent : un identifiant d'ordre PayPal ne peut jamais être crédité deux fois, y compris après un crash.
- Timeouts HTTP, validation des codes de réponse, cache court du jeton OAuth et URL d'approbation limitée au domaine PayPal.
- La devise propre à chaque pack est désormais utilisée par PayPal, au lieu de la devise globale affichée différemment.
- Détection des identifiants PayPal corrigée : les placeholders
USE_SECRET_FILEne sont plus considérés comme des credentials valides. - Stockage des secrets renforcé : écritures atomiques, permissions POSIX
600, validation des entrées et détection d'une clé AES manquante sans la remplacer silencieusement. - Validation transactionnelle de
shop.json.- Tous les packs et articles sont validés avant écriture (types, bornes, items, prix, devise, champs obligatoires et doublons de
purchase_id). - Une configuration invalide est refusée sans écraser le fichier ni le catalogue actif.
- Tous les packs et articles sont validés avant écriture (types, bornes, items, prix, devise, champs obligatoires et doublons de
- Soldes persistants sécurisés : migration automatique du format historique, sauvegarde atomique et protection contre les dépassements d'entier.
- Résultats FTBRanks respectés : les retours booléens de
Rank.addetRank.removene sont plus ignorés ; un refus de l'API est maintenant signalé comme un échec et un achat refusé est remboursé. - Protection Keep It corrigée pour les stacks divisés.
- L'autorisation d'un identifiant de protection est désormais limitée à la quantité réellement possédée avant l'ouverture d'une tombe.
- Posséder un seul objet d'un stack divisé ne permet plus de récupérer tous les autres objets portant le même identifiant.
- Les nouveaux objets enregistrent l'UUID de l'acheteur et la compatibilité Corpse échoue de manière fermée si le propriétaire de la tombe ne peut pas être déterminé.
- Baguette de suivi Easy NPC utilisable par les joueurs non-OP.
- Le propriétaire et l'objectif
follow ownersont lus et modifiés directement via l'API d'Easy NPC 6.17, avec un fallback par commande serveur pour les anciennes versions. - Le nom visible du PNJ n'est plus utilisé pour le ciblage : l'entité cliquée est toujours identifiée par son UUID réel.
- Le propriétaire et l'objectif
- Achat d'un PNJ renommé.
- L'import utilise désormais le chemin stable du preset et un UUID d'entité généré côté serveur ; renommer le nom visible du modèle n'empêche plus les futurs achats de le faire apparaître.
- L'acheteur est explicitement défini comme propriétaire avant l'activation du suivi.
- Les suggestions de l'éditeur ne proposent plus les noms internes/visibles lus dans le NBT comme s'il s'agissait d'identifiants de preset.
- Achat rendu atomique en cas d'échec de livraison : si un item, rank ou PNJ ne peut pas être livré, les OCS débités sont remboursés et l'achat limité n'est pas enregistré.
- Contournement de la limite des chunks fermé : une entrée chunk ne peut plus être achetée via le payload générique.
- Faux message « Tu possèdes déjà le rank » lors d'un achat alors que le joueur ne possède pas le rank.
- Le test d'achat s'appuie maintenant sur une vérification exacte en mémoire via l'API FTBRanks (
Rank.isAdded) au lieu de l'analyse approximative du fichierplayers.snbt. - La détection ne confond plus un rank avec un autre dont le nom est inclus (ex.
vipne déclenche plus à tort survip_plus).
- Le test d'achat s'appuie maintenant sur une vérification exacte en mémoire via l'API FTBRanks (
- Lenteur de mise à jour de
players.snbtaprès achat/expiration d'un rank : résolue par la persistance forcée immédiate (voir Ajouts). - Analyse de secours (fallback) du fichier
players.snbtdurcie : utilisée uniquement si l'API FTBRanks est indisponible, elle effectue désormais une correspondance exacte et insensible à la casse du nom de rank (fin des faux positifs sur les sous-chaînes). - Onglet « Abonnements » : le bouton affichait un texte générique « expire bientôt » ; il indique maintenant le compte à rebours réel (jours / heures / minutes).
🔁 Changements de comportement
- Achat / retrait de rank désactivé proprement si FTBRanks est absent.
- À l'achat : message clair (« L'achat de rank est indisponible : FTBRanks n'est pas installé ») et aucun débit des OniriaCoins.
- À l'expiration : le retrait est ignoré et tracé dans les logs (
SKIPPED / ftbranks_unavailable) au lieu d'exécuter une commande sans effet.
🧹 Nettoyage interne
- Ajout de tests JUnit pour les mutations FTBRanks, les quotas Keep It et les écritures atomiques (6 tests).
- Ajout d'une CI GitHub Actions Java 21 qui compile, exécute les tests et publie le JAR comme artefact.
- Mise à jour de ModDevGradle vers
2.0.143, ajout d'un.gitignorepour les secrets/runtime et correction du bit exécutable de <button class="not-prose border-border-medium bg-surface-secondary hover:bg-surface-tertiary hover:border-border-strong group my-0.5 inline-flex items-center gap-1 rounded border px-1 py-0 text-left align-middle transition-colors" type="button">gradlew</button>. - Suppression de la méthode désormais inutilisée
scheduleFtbranksReload(le rechargementftbranks reloadn'est plus nécessaire avec l'intégration API). - La sécurité d'attribution est renforcée : si l'API FTBRanks échoue à attribuer le rank (rank introuvable, etc.), l'achat est interrompu et signalé au joueur.
Note de compatibilité
- Mod testé pour NeoForge 21.1.231 (Minecraft 1.21.1), nécessite Java 21.
- FTBRanks est désormais requis uniquement pour la fonctionnalité de ranks de la boutique ; il reste optionnel pour le reste du mod (boutique, OniriaCoins, PayPal, chunks, NPC).
- L'option
rank_command_templatedu fichierconfig/oniria_economy.tomln'est plus utilisée pour l'attribution des ranks (conservée pour compatibilité ; l'attribution passe désormais par l'API FTBRanks).
This mod has no additional files

