From 37beda56ecd57a61432a8edb2836c1d39ef37991 Mon Sep 17 00:00:00 2001 From: koka Date: Sat, 29 Aug 2026 12:13:15 +0200 Subject: [PATCH] fix(onlyfun): retirer les raccourcis du Shop --- onlyfun/SHOP_CATALOG.md | 10 +++++++-- .../onlyfun/policy/OnlyFunItemPolicy.java | 9 +++++++- .../onlyfun/shop/OnlyFunShopCatalog.java | 4 +++- .../onlyfun/shop/OnlyFunShopCatalogSmoke.java | 21 +++++++++++++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/onlyfun/SHOP_CATALOG.md b/onlyfun/SHOP_CATALOG.md index ca3d12a..8ea7fda 100644 --- a/onlyfun/SHOP_CATALOG.md +++ b/onlyfun/SHOP_CATALOG.md @@ -63,6 +63,12 @@ reçoivent la bande neutre de 96 rubis jusqu’à leur override explicite. - blocs techniques ou créateurs directs de récompenses/farms : spawners, trial spawners, vault, command blocks, structure/test blocks, barrier, light, bedrock et assimilés ; - équipements uniques en titane et les deux monnaies elles-mêmes. +- tout le namespace `itsalive:*` afin que cultures, machines, recettes, plats et créatures restent + obtenus par le gameplay d’It's Alive ; +- les plats vanilla déjà préparés : aliments cuits, soupes et ragoûts, pain, gâteaux, biscuits et + tartes ; +- `minecraft:enchanted_golden_apple`, qui reste une récompense d'exploration exceptionnelle. -La même politique bloque ces identifiants à la sortie du générateur de loot, même si un futur -résultat aléatoire tente de les sélectionner. +Les identifiants économiques, techniques et de lootbox restent également bloqués à la sortie du +générateur de loot. Les exclusions culinaires sont propres au Shop : elles empêchent l’achat et +la sauvegarde d’une nouvelle offre sans supprimer un colis déjà payé ni les autres sources de jeu. diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/policy/OnlyFunItemPolicy.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/policy/OnlyFunItemPolicy.java index fca3578..2eb6ed7 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/policy/OnlyFunItemPolicy.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/policy/OnlyFunItemPolicy.java @@ -23,6 +23,12 @@ public final class OnlyFunItemPolicy { "nether_portal", "end_portal", "end_gateway", "frosted_ice", "farmland", "dirt_path", "dragon_egg", "filled_map", "written_book", "enchanted_book" ); + private static final Set VANILLA_SHOP_GAMEPLAY_BYPASSES = Set.of( + "baked_potato", "beetroot_soup", "bread", "cake", + "cooked_beef", "cooked_chicken", "cooked_cod", "cooked_mutton", + "cooked_porkchop", "cooked_rabbit", "cooked_salmon", "cookie", "dried_kelp", + "enchanted_golden_apple", "mushroom_stew", "pumpkin_pie", "rabbit_stew", "suspicious_stew" + ); private OnlyFunItemPolicy() {} @@ -35,7 +41,8 @@ public final class OnlyFunItemPolicy { if (id == null || isCurrencyOre(id)) return true; String namespace = id.getNamespace().toLowerCase(Locale.ROOT); String path = normalizedPath(id); - if (namespace.equals("canaplia")) return true; + if (namespace.equals("canaplia") || namespace.equals("itsalive")) return true; + if (namespace.equals("minecraft") && VANILLA_SHOP_GAMEPLAY_BYPASSES.contains(path)) return true; if (namespace.equals("anotherworld") && isProtectedAnotherWorldItem(path)) return true; if (TECHNICAL_OR_REWARD_BLOCKS.contains(path) || path.startsWith("infested_") || path.contains("command_block")) return true; diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalog.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalog.java index 2567d21..73e7c9c 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalog.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalog.java @@ -39,7 +39,9 @@ public final class OnlyFunShopCatalog implements ShopCatalogProvider { } @Override public boolean isAvailable(MinecraftServer server, String itemId) { - return OnlyFunBossShopGate.isAvailable(server, itemId); + Identifier id = Identifier.tryParse(itemId); + return id != null && !OnlyFunItemPolicy.excludedFromShop(id) + && OnlyFunBossShopGate.isAvailable(server, itemId); } /** Registry-derived, deterministic and duplicate-free view of the enabled CSV rows. */ diff --git a/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalogSmoke.java b/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalogSmoke.java index 6142b43..82bc2c8 100644 --- a/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalogSmoke.java +++ b/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/shop/OnlyFunShopCatalogSmoke.java @@ -2,6 +2,7 @@ package fr.koka99cab.sanctuary26.onlyfun.shop; import fr.koka99cab.sanctuary26.onlyfun.policy.OnlyFunItemPolicy; import fr.koka99cab.sanctuary26.sanctuary.shop.ShopOffer; +import fr.koka99cab.sanctuary26.sanctuary.shop.ShopOfferCatalog; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -60,6 +61,26 @@ public final class OnlyFunShopCatalogSmoke { assertConfigured("anotherworld:golden_egg", 1, 2048, 192); assertConfigured("iliketomoveit:magic_carpet", 1, 1536, 128); assertConfigured("iliketomoveit:magic_cloud", 1, 3072, 192); + OnlyFunShopCatalog.initialize(); + for (String excludedId : List.of( + "itsalive:apple_pie", "itsalive:basil", "itsalive:culinary_recipe_book", + "itsalive:fermentation_barrel", "itsalive:infected_spawn_egg", + "minecraft:baked_potato", "minecraft:beetroot_soup", "minecraft:bread", + "minecraft:cake", "minecraft:cooked_beef", "minecraft:cooked_chicken", + "minecraft:cooked_cod", "minecraft:cooked_mutton", "minecraft:cooked_porkchop", + "minecraft:cooked_rabbit", "minecraft:cooked_salmon", "minecraft:cookie", + "minecraft:dried_kelp", "minecraft:enchanted_golden_apple", "minecraft:mushroom_stew", + "minecraft:pumpkin_pie", "minecraft:rabbit_stew", "minecraft:suspicious_stew")) { + Identifier id = Identifier.parse(excludedId); + require(OnlyFunItemPolicy.excludedFromShop(id), "Gameplay bypass reached Shop policy: " + id); + require(find(all, excludedId) == null, "Gameplay bypass reached Shop catalogue: " + id); + require(ShopOfferCatalog.find(null, excludedId) == null, + "Server lookup accepted a forbidden saved offer: " + id); + } + for (String rawFoodId : List.of("minecraft:apple", "minecraft:carrot", "minecraft:potato")) { + require(!OnlyFunItemPolicy.excludedFromShop(Identifier.parse(rawFoodId)), + "Raw ingredient was removed with finished food: " + rawFoodId); + } require(OnlyFunBossShopGate.requiresBoss("iliketomoveit:magic_carpet"), "Magic Carpet must remain boss-gated"); require(OnlyFunBossShopGate.requiresBoss("iliketomoveit:magic_cloud"), -- 2.54.0