From 844686abb9dad795831a1028e5a4c620b9a0b080 Mon Sep 17 00:00:00 2001 From: Overcontrol1 Date: Wed, 26 Jun 2024 03:12:10 +1000 Subject: [PATCH] Implement blacklisting through modwide JSON and tags. Bump to 1.3. --- build.gradle | 14 +++- gradle.properties | 2 +- settings.gradle | 2 +- .../randomfishing/RandomFishing.java | 20 ++++++ .../data/RandomFishingDataLoader.java | 64 +++++++++++++++++++ .../randomfishing/mixin/MixinLootTable.java | 18 ++++-- .../data/randomfishing/blacklist.json | 1 + src/main/resources/fabric.mod.json | 8 ++- stonecutter.gradle | 2 +- 9 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/overcontrol1/randomfishing/data/RandomFishingDataLoader.java create mode 100644 src/main/resources/data/randomfishing/blacklist.json diff --git a/build.gradle b/build.gradle index e521fe1..329c0cf 100644 --- a/build.gradle +++ b/build.gradle @@ -33,11 +33,23 @@ dependencies { include modImplementation("xyz.nucleoid:server-translations-api:${project.server_translations_version}") } +final String minecraft_version = stonecutter.current.version + processResources { inputs.property "version", project.version + inputs.property "minecraft_version", minecraft_version + inputs.property "polymer_version", project.property("polymer_version") + inputs.property "server_translations_version", project.property("server_translations_version") + + filesMatching("fabric.mod.json") { - expand "version": project.version + expand ([ + "version": project.version, + "minecraft_version": minecraft_version, + "polymer_version": project.property("polymer_version"), + "server_translations_version": project.property("server_translations_version") + ]) } } diff --git a/gradle.properties b/gradle.properties index 8827e1b..6612408 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.20.1+build.10 loader_version=0.15.11 # Mod Properties -mod_version=1.2.1 +mod_version=1.3 maven_group=com.overcontrol1.randomfishing archives_base_name=randomfishing diff --git a/settings.gradle b/settings.gradle index 93add30..5bf4fb6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,7 +18,7 @@ plugins { stonecutter { shared { - versions "1.20.1" + vers "1.20.1" vers "1.20.4" } diff --git a/src/main/java/com/overcontrol1/randomfishing/RandomFishing.java b/src/main/java/com/overcontrol1/randomfishing/RandomFishing.java index dada633..1ad4b2c 100644 --- a/src/main/java/com/overcontrol1/randomfishing/RandomFishing.java +++ b/src/main/java/com/overcontrol1/randomfishing/RandomFishing.java @@ -1,11 +1,18 @@ package com.overcontrol1.randomfishing; +import com.overcontrol1.randomfishing.data.RandomFishingDataLoader; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.enchantment.Enchantment; +import net.minecraft.item.Item; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import net.minecraft.world.GameRules; @@ -16,8 +23,21 @@ public class RandomFishing implements ModInitializer { public static final GameRules.Key MAX_COUNT = GameRuleRegistry.register("randomFishingMaxCount", GameRules.Category.MISC, GameRuleFactory.createIntRule(64, 1, 64)); + public static final TagKey ITEM_BLACKLIST = TagKey.of(RegistryKeys.ITEM, new Identifier(MOD_ID, "blacklist")); + + public static boolean isBlacklisted(RegistryEntry entry) { + final Identifier id = entry.getKey().orElseThrow().getValue(); + + if (RandomFishingDataLoader.isBlacklisted(id.getNamespace())) + return true; + + return entry.isIn(ITEM_BLACKLIST); + } + @Override public void onInitialize() { + ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(RandomFishingDataLoader.INSTANCE); + Registry.register(Registries.ENCHANTMENT, new Identifier(MOD_ID, "random_fishing"), ENCHANTMENT); } } \ No newline at end of file diff --git a/src/main/java/com/overcontrol1/randomfishing/data/RandomFishingDataLoader.java b/src/main/java/com/overcontrol1/randomfishing/data/RandomFishingDataLoader.java new file mode 100644 index 0000000..8b020df --- /dev/null +++ b/src/main/java/com/overcontrol1/randomfishing/data/RandomFishingDataLoader.java @@ -0,0 +1,64 @@ +package com.overcontrol1.randomfishing.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.overcontrol1.randomfishing.RandomFishing; +import it.unimi.dsi.fastutil.objects.ObjectArraySet; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.profiler.Profiler; + +import java.io.IOException; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public final class RandomFishingDataLoader implements IdentifiableResourceReloadListener { + public static final RandomFishingDataLoader INSTANCE = new RandomFishingDataLoader(); + + private static final Identifier ID = new Identifier(RandomFishing.MOD_ID, "data"); + + private static final Identifier JSON_PATH = new Identifier(RandomFishing.MOD_ID, "blacklist.json"); + + private static final Set MOD_BLACKLIST = new ObjectOpenHashSet<>(); + + public static boolean isBlacklisted(String namespace) { + return MOD_BLACKLIST.contains(namespace); + } + + @Override + public Identifier getFabricId() { + return ID; + } + + @Override + public CompletableFuture reload(Synchronizer synchronizer, ResourceManager manager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor) { + MOD_BLACKLIST.clear(); + + final CompletableFuture> gatherer = CompletableFuture.supplyAsync(() -> load(manager)); + + return gatherer.thenCompose(synchronizer::whenPrepared) + .thenAcceptAsync(MOD_BLACKLIST::addAll); + } + + private static Set load(ResourceManager manager) { + final Set result = new ObjectArraySet<>(); + for (Resource resource : manager.getAllResources(JSON_PATH)) { + try { + final JsonElement element = JsonParser.parseReader(resource.getReader()); + final JsonArray array = element.getAsJsonArray(); + array.forEach(jsonElement -> result.add(jsonElement.getAsString())); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return result; + } + + private RandomFishingDataLoader() {} +} diff --git a/src/main/java/com/overcontrol1/randomfishing/mixin/MixinLootTable.java b/src/main/java/com/overcontrol1/randomfishing/mixin/MixinLootTable.java index 79f1db3..1ec1575 100644 --- a/src/main/java/com/overcontrol1/randomfishing/mixin/MixinLootTable.java +++ b/src/main/java/com/overcontrol1/randomfishing/mixin/MixinLootTable.java @@ -5,10 +5,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.PotionItem; -import net.minecraft.item.TippedArrowItem; +import net.minecraft.item.*; import net.minecraft.loot.LootTable; import net.minecraft.loot.context.LootContextParameterSet; import net.minecraft.loot.context.LootContextParameters; @@ -25,7 +22,7 @@ @Mixin(LootTable.class) public class MixinLootTable { - @Shadow @Final private LootContextType type; + @Shadow @Final LootContextType type; @ModifyReturnValue(method = "generateLoot(Lnet/minecraft/loot/context/LootContextParameterSet;)Lit/unimi/dsi/fastutil/objects/ObjectArrayList;", at = @At("RETURN")) public ObjectArrayList randomfishing$overrideFishingLootIfEnchantmentPresent(ObjectArrayList original, LootContextParameterSet parameterSet) { @@ -43,8 +40,15 @@ public class MixinLootTable { World world = bobberEntity.getWorld(); - Item item = Registries.ITEM.getRandom(world.random).map(RegistryEntry.Reference::value).orElse(null); - assert item != null; + final Item[] compatibleItems = Registries.ITEM.streamEntries() + .filter(entry -> entry.value() != Items.AIR && !RandomFishing.isBlacklisted(entry)) + .map(RegistryEntry.Reference::value) + .toArray(Item[]::new); + + if (compatibleItems.length == 0) + return original; + + final Item item = compatibleItems[world.random.nextInt(compatibleItems.length)]; ItemStack stack = new ItemStack(item, world.random.nextBetween(1, Math.min(item.getMaxCount(), world.getGameRules().getInt(RandomFishing.MAX_COUNT)))); if (item instanceof PotionItem || item instanceof TippedArrowItem) diff --git a/src/main/resources/data/randomfishing/blacklist.json b/src/main/resources/data/randomfishing/blacklist.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/src/main/resources/data/randomfishing/blacklist.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 43b432f..0fceb00 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,9 +23,11 @@ "randomfishing.mixins.json" ], "depends": { - "fabricloader": ">=0.15.2", - "minecraft": "1.20.1", + "fabricloader": ">=0.15.11", + "minecraft": "${minecraft_version}", "java": ">=17", - "fabric-api": "*" + "fabric-api": "*", + "polymer": "${polymer_version}", + "server-translations-api": "${server_translations_version}" } } diff --git a/stonecutter.gradle b/stonecutter.gradle index 5f1811a..8466477 100644 --- a/stonecutter.gradle +++ b/stonecutter.gradle @@ -8,4 +8,4 @@ stonecutter.active "1.20.1" /* [SC] DO NOT EDIT */ stonecutter.registerChiseled tasks.register("chiseledBuild", stonecutter.chiseled) { setGroup "project" ofTask "build" -} \ No newline at end of file +}