From 24e4b8765ec2ae1fbb5107840cc1b8261b98bef9 Mon Sep 17 00:00:00 2001 From: TheMode Date: Thu, 29 Jul 2021 12:54:16 +0200 Subject: [PATCH 1/2] Remove resource gatherer, retrieve tags from our own data generator --- build.gradle | 2 +- code-generators/build.gradle | 2 +- .../net/minestom/server/MinecraftServer.java | 10 - .../gamedata/loottables/LootTableManager.java | 9 +- .../gamedata/loottables/entries/TagType.java | 10 +- .../server/gamedata/tags/RequiredTag.java | 21 -- .../minestom/server/gamedata/tags/Tag.java | 99 +++-- .../server/gamedata/tags/TagContainer.java | 9 - .../server/gamedata/tags/TagManager.java | 357 ++---------------- .../packet/server/play/TagsPacket.java | 132 +------ .../minestom/server/registry/Registry.java | 8 +- .../server/registry/ResourceGatherer.java | 216 ----------- src/test/java/loottables/TestLootTables.java | 9 - src/test/java/tags/TestTags.java | 104 ----- 14 files changed, 112 insertions(+), 876 deletions(-) delete mode 100644 src/main/java/net/minestom/server/gamedata/tags/RequiredTag.java delete mode 100644 src/main/java/net/minestom/server/gamedata/tags/TagContainer.java delete mode 100644 src/main/java/net/minestom/server/registry/ResourceGatherer.java delete mode 100644 src/test/java/tags/TestTags.java diff --git a/build.gradle b/build.gradle index 9392dc647..986c6a9c4 100644 --- a/build.gradle +++ b/build.gradle @@ -164,7 +164,7 @@ dependencies { } api "com.github.Minestom:DependencyGetter:v1.0.1" - implementation 'com.github.Minestom:MinestomDataGenerator:b13c934eba' + implementation 'com.github.Minestom:MinestomDataGenerator:7636d5d473' // Adventure, for user-interface api "net.kyori:adventure-api:$adventureVersion" diff --git a/code-generators/build.gradle b/code-generators/build.gradle index 675f41670..ec6adec11 100644 --- a/code-generators/build.gradle +++ b/code-generators/build.gradle @@ -25,7 +25,7 @@ dependencies { // SLF4J is the base logger for most libraries, therefore we can hook it into log4j2. implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.14.1' // Contains the json files - implementation 'com.github.Minestom:MinestomDataGenerator:b13c934eba' + implementation 'com.github.Minestom:MinestomDataGenerator:7636d5d473' } diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index f23b5dd38..a2981821b 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -28,7 +28,6 @@ import net.minestom.server.network.packet.server.play.ServerDifficultyPacket; import net.minestom.server.network.packet.server.play.UpdateViewDistancePacket; import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.recipe.RecipeManager; -import net.minestom.server.registry.ResourceGatherer; import net.minestom.server.scoreboard.TeamManager; import net.minestom.server.storage.StorageLocation; import net.minestom.server.storage.StorageManager; @@ -46,8 +45,6 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; - /** * The main server class used to start the server and retrieve all the managers. *

@@ -176,13 +173,6 @@ public final class MinecraftServer { nettyServer = new NettyServer(packetProcessor); - // Registry - try { - ResourceGatherer.ensureResourcesArePresent(VERSION_NAME); - } catch (IOException e) { - LOGGER.error("An error happened during resource gathering. Minestom will attempt to load anyway, but things may not work, and crashes can happen.", e); - } - initialized = true; minecraftServer = new MinecraftServer(); diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java index c96d10384..5a160f454 100644 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java +++ b/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java @@ -5,17 +5,17 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializer; import net.minestom.server.MinecraftServer; import net.minestom.server.gamedata.Condition; -import net.minestom.server.registry.ResourceGatherer; import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.NamespaceIDHashMap; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; /** * Handles loading and configuration of loot tables */ public final class LootTableManager { - private NamespaceIDHashMap> conditionDeserializers = new NamespaceIDHashMap<>(); private NamespaceIDHashMap tableTypes = new NamespaceIDHashMap<>(); private NamespaceIDHashMap entryTypes = new NamespaceIDHashMap<>(); @@ -71,7 +71,8 @@ public final class LootTableManager { } public LootTable load(NamespaceID name) throws FileNotFoundException { - return load(name, new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/loot_tables/" + name.getPath() + ".json"))); + return null; // FIXME + //return load(name, new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/loot_tables/" + name.getPath() + ".json"))); } /** diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java index 6aad1f812..b804af71f 100644 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java +++ b/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java @@ -6,9 +6,8 @@ import net.minestom.server.gamedata.loottables.LootTable; import net.minestom.server.gamedata.loottables.LootTableEntryType; import net.minestom.server.gamedata.loottables.LootTableFunction; import net.minestom.server.gamedata.loottables.LootTableManager; -import net.minestom.server.utils.NamespaceID; +import net.minestom.server.gamedata.tags.Tag; -import java.io.FileNotFoundException; import java.util.List; /** @@ -17,11 +16,6 @@ import java.util.List; public class TagType implements LootTableEntryType { @Override public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - try { - return new TagEntry(this, MinecraftServer.getTagManager().load(NamespaceID.from(name), "items"), expand, weight, quality, conditions); - } catch (FileNotFoundException e) { - MinecraftServer.getExceptionManager().handleException(e); - return null; - } + return new TagEntry(this, MinecraftServer.getTagManager().getTag(Tag.BasicType.ITEMS, name), expand, weight, quality, conditions); } } diff --git a/src/main/java/net/minestom/server/gamedata/tags/RequiredTag.java b/src/main/java/net/minestom/server/gamedata/tags/RequiredTag.java deleted file mode 100644 index 2bc2dcd24..000000000 --- a/src/main/java/net/minestom/server/gamedata/tags/RequiredTag.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.minestom.server.gamedata.tags; - -import net.minestom.server.utils.NamespaceID; - -public class RequiredTag { - private final Tag.BasicTypes type; - private final NamespaceID name; - - public RequiredTag(Tag.BasicTypes type, NamespaceID name) { - this.type = type; - this.name = name; - } - - public NamespaceID getName() { - return name; - } - - public Tag.BasicTypes getType() { - return type; - } -} diff --git a/src/main/java/net/minestom/server/gamedata/tags/Tag.java b/src/main/java/net/minestom/server/gamedata/tags/Tag.java index 7649f7309..884e25bf9 100644 --- a/src/main/java/net/minestom/server/gamedata/tags/Tag.java +++ b/src/main/java/net/minestom/server/gamedata/tags/Tag.java @@ -1,32 +1,34 @@ package net.minestom.server.gamedata.tags; +import net.minestom.server.entity.EntityType; +import net.minestom.server.instance.block.Block; +import net.minestom.server.item.Material; +import net.minestom.server.registry.Registries; +import net.minestom.server.registry.Registry; import net.minestom.server.utils.NamespaceID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.FileNotFoundException; +import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; +import java.util.function.Function; /** * Represents a group of items, blocks, fluids, entity types or function. * Immutable by design */ -public class Tag { - - public static final Tag EMPTY = new Tag(NamespaceID.from("minestom:empty")); +public final class Tag { private final NamespaceID name; - - private Set values; + private final Set values; /** * Creates a new empty tag. This does not cache the tag. */ public Tag(NamespaceID name) { this.name = name; - values = new HashSet<>(); - lockValues(); + this.values = new HashSet<>(); } /** @@ -35,42 +37,10 @@ public class Tag { public Tag(NamespaceID name, Set values) { this.name = name; this.values = new HashSet<>(values); - lockValues(); } /** - * Creates a new tag with the contents of the container - * - * @param manager Used to load tag contents (as tags are valid values inside 'values') - * @param lowerPriority Tag contents from lower priority data packs. If 'replace' is false in 'container', - * appends the contents of that pack to the one being constructed - * @param container - */ - public Tag(TagManager manager, NamespaceID name, String type, Tag lowerPriority, TagContainer container) throws FileNotFoundException { - this.name = name; - values = new HashSet<>(); - if (!container.replace) { - values.addAll(lowerPriority.values); - } - Objects.requireNonNull(container.values, "Attempted to load from a TagContainer with no 'values' array"); - for (String line : container.values) { - if (line.startsWith("#")) { // pull contents from a tag - Tag subtag = manager.load(NamespaceID.from(line.substring(1)), type); - values.addAll(subtag.values); - } else { - values.add(NamespaceID.from(line)); - } - } - - lockValues(); - } - - private void lockValues() { - values = Set.copyOf(values); - } - - /** - * Checks whether the given id in inside this tag + * Checks whether the given id in inside this tag. * * @param id the id to check against * @return 'true' iif this tag contains the given id @@ -85,40 +55,55 @@ public class Tag { * @return immutable set of values present in this tag */ public Set getValues() { - return values; + return Collections.unmodifiableSet(values); } /** * Returns the name of this tag - * - * @return */ public NamespaceID getName() { return name; } - public enum BasicTypes { - BLOCKS("minecraft:block"), - ITEMS("minecraft:item"), - FLUIDS("minecraft:fluid"), - ENTITY_TYPES("minecraft:entity_type"), - GAME_EVENTS("minecraft:game_event"); + public enum BasicType { + BLOCKS("minecraft:block", Registry.Resource.BLOCK_TAGS, + name -> Objects.requireNonNull(Block.fromNamespaceId(name)).id()), + ITEMS("minecraft:item", Registry.Resource.ITEM_TAGS, + name -> Objects.requireNonNull(Material.fromNamespaceId(name)).id()), + FLUIDS("minecraft:fluid", Registry.Resource.FLUID_TAGS, + name -> 1), // TODO + ENTITY_TYPES("minecraft:entity_type", Registry.Resource.ENTITY_TYPE_TAGS, + name -> Objects.requireNonNull(EntityType.fromNamespaceId(name)).id()), + GAME_EVENTS("minecraft:game_event", Registry.Resource.GAMEPLAY_TAGS, + name -> Registries.getFluid(name).ordinal()); - private final static BasicTypes[] VALUES = values(); + private final static BasicType[] VALUES = values(); private final String identifier; + private final Registry.Resource resource; + private final Function function; - BasicTypes(@NotNull String identifier) { + BasicType(@NotNull String identifier, + @NotNull Registry.Resource resource, + @NotNull Function function) { this.identifier = identifier; + this.resource = resource; + this.function = function; } - @NotNull - public String getIdentifier() { + public @NotNull String getIdentifier() { return identifier; } - @Nullable - public static BasicTypes fromIdentifer(@NotNull String identifier) { - for (BasicTypes value : VALUES) { + public Registry.Resource getResource() { + return resource; + } + + public Function getFunction() { + return function; + } + + public static @Nullable Tag.BasicType fromIdentifer(@NotNull String identifier) { + for (BasicType value : VALUES) { if (value.identifier.equals(identifier)) { return value; } diff --git a/src/main/java/net/minestom/server/gamedata/tags/TagContainer.java b/src/main/java/net/minestom/server/gamedata/tags/TagContainer.java deleted file mode 100644 index 7f181851a..000000000 --- a/src/main/java/net/minestom/server/gamedata/tags/TagContainer.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.minestom.server.gamedata.tags; - -/** - * Meant only for parsing tag JSON - */ -public class TagContainer { - boolean replace; - String[] values; -} diff --git a/src/main/java/net/minestom/server/gamedata/tags/TagManager.java b/src/main/java/net/minestom/server/gamedata/tags/TagManager.java index 30e46a0c9..c8805f8c3 100644 --- a/src/main/java/net/minestom/server/gamedata/tags/TagManager.java +++ b/src/main/java/net/minestom/server/gamedata/tags/TagManager.java @@ -1,340 +1,57 @@ package net.minestom.server.gamedata.tags; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import net.minestom.server.MinecraftServer; -import net.minestom.server.network.packet.server.play.TagsPacket; -import net.minestom.server.registry.ResourceGatherer; +import com.google.gson.JsonObject; +import net.minestom.server.registry.Registry; import net.minestom.server.utils.NamespaceID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; /** * Handles loading and caching of tags. */ -public class TagManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(TagManager.class); - private final Gson gson; - private final Map cache = new ConcurrentHashMap<>(); - private final List requiredTags = new LinkedList<>(); +public final class TagManager { + private final Map> tagMap = new ConcurrentHashMap<>(); public TagManager() { - gson = new GsonBuilder() - .create(); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("acacia_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("anvil")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("bamboo_plantable_on")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("banners")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("base_stone_nether")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("base_stone_overworld")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("beacon_base_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("beds")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("beehives")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("bee_growables")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("birch_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("buttons")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("campfires")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("candles")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("candle_cakes")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("carpets")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("cauldrons")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("cave_vines")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("climbable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("coal_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("copper_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("corals")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("coral_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("coral_plants")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("crimson_stems")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("crops")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("crystal_sound_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("dark_oak_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("deepslate_ore_replaceables")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("diamond_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("dirt")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("doors")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("dragon_immune")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("dripstone_replaceable_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("emerald_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("enderman_holdable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("features_cannot_replace")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("fences")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("fence_gates")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("fire")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("flowers")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("flower_pots")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("geode_invalid_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("gold_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("guarded_by_piglins")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("hoglin_repellents")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("ice")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("impermeable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("infiniburn_end")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("infiniburn_nether")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("infiniburn_overworld")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("inside_step_sound_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("iron_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("jungle_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("lapis_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("lava_pool_stone_replaceables")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("leaves")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("logs_that_burn")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("lush_ground_replaceable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("moss_replaceable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("mushroom_grow_block")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("needs_diamond_tool")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("needs_iron_tool")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("needs_stone_tool")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("non_flammable_wood")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("nylium")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("oak_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("occludes_vibration_signals")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("piglin_repellents")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("planks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("portals")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("pressure_plates")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("prevent_mob_spawning_inside")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("rails")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("redstone_ores")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("sand")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("saplings")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("shulker_boxes")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("signs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("slabs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("small_dripleaf_placeable")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("small_flowers")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("snow")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("soul_fire_base_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("soul_speed_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("spruce_logs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("stairs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("standing_signs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("stone_bricks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("stone_ore_replaceables")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("stone_pressure_plates")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("strider_warm_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("tall_flowers")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("trapdoors")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("underwater_bonemeals")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("unstable_bottom_center")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("valid_spawn")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("walls")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wall_corals")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wall_post_override")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wall_signs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("warped_stems")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wart_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wither_immune")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wither_summon_base_blocks")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_buttons")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_doors")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_fences")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_pressure_plates")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_slabs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_stairs")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wooden_trapdoors")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("wool")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("mineable/axe")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("mineable/hoe")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("mineable/pickaxe")); - addRequiredTag(Tag.BasicTypes.BLOCKS, NamespaceID.from("mineable/shovel")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("arrows")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("axolotl_always_hostiles")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("axolotl_hunt_targets")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("beehive_inhabitors")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("freeze_hurts_extra_types")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("freeze_immune_entity_types")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("impact_projectiles")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("powder_snow_walkable_mobs")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("raiders")); - addRequiredTag(Tag.BasicTypes.ENTITY_TYPES, NamespaceID.from("skeletons")); - addRequiredTag(Tag.BasicTypes.FLUIDS, NamespaceID.from("lava")); - addRequiredTag(Tag.BasicTypes.FLUIDS, NamespaceID.from("water")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("acacia_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("anvil")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("arrows")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("axolotl_tempt_items")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("banners")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("beacon_payment_items")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("beds")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("birch_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("boats")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("buttons")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("candles")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("carpets")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("cluster_max_harvestables")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("coals")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("coal_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("copper_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("creeper_drop_music_discs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("crimson_stems")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("dark_oak_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("diamond_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("doors")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("emerald_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("fences")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("fishes")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("flowers")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("fox_food")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("freeze_immune_wearables")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("gold_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("ignored_by_piglin_babies")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("iron_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("jungle_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("lapis_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("leaves")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("lectern_books")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("logs_that_burn")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("music_discs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("non_flammable_wood")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("oak_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("occludes_vibration_signals"));; - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("piglin_food")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("piglin_loved")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("piglin_repellents")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("planks")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("rails")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("redstone_ores")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("sand")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("saplings")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("signs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("slabs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("small_flowers")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("soul_fire_base_blocks")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("spruce_logs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("stairs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("stone_bricks")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("stone_crafting_materials")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("stone_tool_materials")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("tall_flowers")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("trapdoors")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("walls")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("warped_stems")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_buttons")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_doors")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_fences")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_pressure_plates")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_slabs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_stairs")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wooden_trapdoors")); - addRequiredTag(Tag.BasicTypes.ITEMS, NamespaceID.from("wool")); - addRequiredTag(Tag.BasicTypes.GAME_EVENTS, NamespaceID.from("ignore_vibrations_sneaking")); - addRequiredTag(Tag.BasicTypes.GAME_EVENTS, NamespaceID.from("vibrations")); + // Load required tags from files + for (var type : Tag.BasicType.values()) { + final var json = Registry.load(type.getResource()); + final var tagIdentifierMap = tagMap.computeIfAbsent(type, s -> new CopyOnWriteArrayList<>()); + json.keySet().forEach(tagName -> { + final var tag = new Tag(NamespaceID.from(tagName), getValues(json, tagName)); + tagIdentifierMap.add(tag); + }); + } } - /** - * Loads a tag with the given name. This method attempts to read from "data/<name.domain>/tags/<tagType>/<name.path>.json" if the given name is not already present in cache - * - * @param name - * @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants) - * @return - * @throws FileNotFoundException if the file does not exist - */ - public Tag load(NamespaceID name, String tagType) throws FileNotFoundException { - return load(name, tagType, () -> new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/tags/" + tagType + "/" + name.getPath() + ".json"))); + public @Nullable Tag getTag(Tag.BasicType type, String namespace) { + final var tags = tagMap.get(type); + for (var tag : tags) { + if (tag.getName().asString().equals(namespace)) + return tag; + } + return null; } - /** - * Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache - * - * @param name - * @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants) - * @param reader - * @return - */ - public Tag load(NamespaceID name, String tagType, Reader reader) throws FileNotFoundException { - return load(name, tagType, () -> reader); + public Map> getTagMap() { + return Collections.unmodifiableMap(tagMap); } - /** - * Loads a tag with the given name. This method reads from 'reader'. This will override the previous tag - * - * @param name - * @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants) - * @param readerSupplier - * @return - */ - public Tag forceLoad(NamespaceID name, String tagType, ReaderSupplierWithFileNotFound readerSupplier) throws FileNotFoundException { - Tag prev = cache.getOrDefault(name, Tag.EMPTY); - Tag result = create(prev, name, tagType, readerSupplier); - cache.put(name, result); + private Set getValues(JsonObject main, String value) { + JsonObject tagObject = main.getAsJsonObject(value); + final var tagValues = tagObject.getAsJsonArray("values"); + Set result = new HashSet<>(tagValues.size()); + tagValues.forEach(jsonElement -> { + final String tagString = jsonElement.getAsString(); + if (tagString.startsWith("#")) { + result.addAll(getValues(main, tagString.substring(1))); + } else { + result.add(NamespaceID.from(tagString)); + } + }); return result; } - - /** - * Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache - * - * @param name - * @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants) - * @param readerSupplier - * @return - */ - public Tag load(NamespaceID name, String tagType, ReaderSupplierWithFileNotFound readerSupplier) throws FileNotFoundException { - Tag prev = cache.getOrDefault(name, Tag.EMPTY); - Tag result = cache.get(name); - if (result == null) { - result = create(prev, name, tagType, readerSupplier); - cache.put(name, result); - } - return result; - } - - private Tag create(Tag prev, NamespaceID name, String tagType, ReaderSupplierWithFileNotFound reader) throws FileNotFoundException { - TagContainer container = gson.fromJson(reader.get(), TagContainer.class); - try { - return new Tag(this, name, tagType, prev, container); - } catch (FileNotFoundException e) { - LOGGER.error("Failed to load tag due to error", e); - return Tag.EMPTY; - } - } - - /** - * Adds the required tags for the game to function correctly - * - * @param tagsPacket the packet to add the tags to - */ - public void addRequiredTagsToPacket(TagsPacket tagsPacket) { - for (RequiredTag requiredTag : requiredTags) { - final Tag tag = silentLoad(requiredTag.getName(), requiredTag.getType().name().toLowerCase()); - var map = tagsPacket.tagsMap.computeIfAbsent(requiredTag.getType(), s -> new ArrayList<>()); - map.add(tag); - } - } - - /** - * Adds a required tag to send to players when they connect - * - * @param type type of tag to send. Required so the client knows its use - * @param name the name of the tag to load - */ - public void addRequiredTag(Tag.BasicTypes type, NamespaceID name) { - requiredTags.add(new RequiredTag(type, name)); - } - - private Tag silentLoad(NamespaceID name, String type) { - try { - return load(name, type); - } catch (FileNotFoundException e) { - MinecraftServer.getExceptionManager().handleException(e); - return Tag.EMPTY; - } - } - - public interface ReaderSupplierWithFileNotFound { - Reader get() throws FileNotFoundException; - } } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/TagsPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/TagsPacket.java index 14b9bb6a3..823eccf2a 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/TagsPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/TagsPacket.java @@ -1,34 +1,28 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.MinecraftServer; -import net.minestom.server.entity.EntityType; import net.minestom.server.gamedata.tags.Tag; -import net.minestom.server.instance.block.Block; -import net.minestom.server.item.Material; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.registry.Registries; -import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class TagsPacket implements ServerPacket { + private static final TagsPacket REQUIRED_TAGS_PACKET = new TagsPacket(MinecraftServer.getTagManager().getTagMap()); - private static final TagsPacket REQUIRED_TAGS_PACKET = new TagsPacket(); + public Map> tagsMap; - static { - MinecraftServer.getTagManager().addRequiredTagsToPacket(REQUIRED_TAGS_PACKET); + public TagsPacket(Map> tagsMap) { + this.tagsMap = tagsMap; } - public Map> tagsMap = new HashMap<>(); - - /** - * Default constructor, required for reflection operations. - */ public TagsPacket() { + this(new HashMap<>()); } @Override @@ -37,105 +31,14 @@ public class TagsPacket implements ServerPacket { for (var entry : tagsMap.entrySet()) { final var type = entry.getKey(); final var tags = entry.getValue(); - // Tag type writer.writeSizedString(type.getIdentifier()); - switch (type) { - case BLOCKS: { - // Number of tags - writer.writeVarInt(tags.size()); - for (Tag tag : tags) { - // name - writer.writeSizedString(tag.getName().toString()); - final Set values = tag.getValues(); - // count - writer.writeVarInt(values.size()); - // entries - for (NamespaceID name : values) { - Block b = Block.fromNamespaceId(name); - if (b == null) { - writer.writeVarInt(-1); - continue; - } - writer.writeVarInt(b.id()); - } - } - break; - } - case ENTITY_TYPES: { - // Number of tags - writer.writeVarInt(tags.size()); - for (Tag tag : tags) { - // name - writer.writeSizedString(tag.getName().toString()); - - final Set values = tag.getValues(); - // count - writer.writeVarInt(values.size()); - // entries - for (NamespaceID name : values) { - EntityType et = EntityType.fromNamespaceId(name); - if (et == null) { - writer.writeVarInt(-1); - } else { - writer.writeVarInt(et.id()); - } - } - } - break; - } - case FLUIDS: { - // Number of tags - writer.writeVarInt(tags.size()); - for (Tag tag : tags) { - // name - writer.writeSizedString(tag.getName().toString()); - - final Set values = tag.getValues(); - // count - writer.writeVarInt(values.size()); - // entries - for (NamespaceID name : values) { - writer.writeVarInt(Registries.getFluid(name).ordinal()); - } - } - break; - } - case GAME_EVENTS: { - // Number of tags - writer.writeVarInt(tags.size()); - for (Tag tag : tags) { - // name - writer.writeSizedString(tag.getName().toString()); - - final Set values = tag.getValues(); - // count - writer.writeVarInt(values.size()); - // entries - for (NamespaceID name : values) { - // TODO: GameEvents - writer.writeVarInt(-1); - } - } - break; - } - case ITEMS: { - // Number of tags - writer.writeVarInt(tags.size()); - for (Tag tag : tags) { - // name - writer.writeSizedString(tag.getName().toString()); - - final Set values = tag.getValues(); - // count - writer.writeVarInt(values.size()); - // entries - for (NamespaceID name : values) { - // FIXME: invalid namespace - final var material = Objects.requireNonNullElse(Material.fromNamespaceId(name), Material.AIR); - writer.writeVarInt(material.id()); - } - } - break; + writer.writeVarInt(tags.size()); + for (var tag : tags) { + writer.writeSizedString(tag.getName().asString()); + final var values = tag.getValues(); + writer.writeVarInt(values.size()); + for (var name : values) { + writer.writeVarInt(type.getFunction().apply(name.asString())); } } } @@ -148,7 +51,7 @@ public class TagsPacket implements ServerPacket { final int typeCount = reader.readVarInt(); for (int i = 0; i < typeCount; i++) { // Read tag type - final Tag.BasicTypes tagType = Tag.BasicTypes.fromIdentifer(reader.readSizedString()); + final Tag.BasicType tagType = Tag.BasicType.fromIdentifer(reader.readSizedString()); if (tagType == null) { throw new IllegalArgumentException("Tag type could not be resolved"); } @@ -173,8 +76,7 @@ public class TagsPacket implements ServerPacket { * * @return the default tags packet */ - @NotNull - public static TagsPacket getRequiredTagsPacket() { + public static @NotNull TagsPacket getRequiredTagsPacket() { return REQUIRED_TAGS_PACKET; } } diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 2fc18266e..488ad880a 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -56,7 +56,13 @@ public class Registry { STATISTICS("custom_statistics"), POTION_EFFECTS("potion_effects"), POTION_TYPES("potions"), - PARTICLES("particles"); + PARTICLES("particles"), + + BLOCK_TAGS("tags/block_tags"), + ENTITY_TYPE_TAGS("tags/entity_type_tags"), + FLUID_TAGS("tags/fluid_tags"), + GAMEPLAY_TAGS("tags/gameplay_tags"), + ITEM_TAGS("tags/item_tags"); private final String name; diff --git a/src/main/java/net/minestom/server/registry/ResourceGatherer.java b/src/main/java/net/minestom/server/registry/ResourceGatherer.java deleted file mode 100644 index 307cd0ce7..000000000 --- a/src/main/java/net/minestom/server/registry/ResourceGatherer.java +++ /dev/null @@ -1,216 +0,0 @@ -package net.minestom.server.registry; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import it.unimi.dsi.fastutil.io.FastBufferedInputStream; -import net.minestom.server.utils.StringUtils; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Responsible for making sure Minestom has the necessary files to run (notably registry files) - */ -public class ResourceGatherer { - public static final File DATA_FOLDER = new File("./minecraft_data/"); - private static final Gson GSON = new Gson(); - private static final Logger LOGGER = LoggerFactory.getLogger(ResourceGatherer.class); - private static final File TMP_FOLDER = new File("./.minestom_tmp/"); - - /** - * Checks if registry/ folder is present - * If it is not, download the minecraft server jar, run the data generator and extract the wanted files - * If it is already present, directly return - */ - public static void ensureResourcesArePresent(String version) throws IOException { - if (DATA_FOLDER.exists()) { - return; - } - LOGGER.info("{} folder does not exist. Minestom will now generate the necessary files.", DATA_FOLDER); - - if (!TMP_FOLDER.exists() && !TMP_FOLDER.mkdirs()) { - throw new IOException("Failed to create tmp folder."); - } - - LOGGER.info("Starting download of Minecraft server jar for version {} from Mojang servers...", version); - File serverJar = downloadServerJar(version); - LOGGER.info("Download complete."); - - runDataGenerator(serverJar); - - moveAndCleanup(version); - LOGGER.info("Resource gathering done!"); - } - - private static void moveAndCleanup(String version) throws IOException { - Path dataFolderPath = DATA_FOLDER.toPath(); - Path tmpFolderPath = TMP_FOLDER.toPath(); - Path generatedFolder = tmpFolderPath.resolve("generated"); - LOGGER.info("Data generator successful, removing server jar"); - Files.delete(tmpFolderPath.resolve("server_" + version + ".jar")); - LOGGER.info("Removal successful, now moving data to {}", DATA_FOLDER); - Files.walkFileTree(tmpFolderPath, new SimpleFileVisitor<>() { - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - Path relativePath = generatedFolder.relativize(dir); - if (dir.startsWith(generatedFolder)) { // don't copy logs - Path resolvedPath = dataFolderPath.resolve(relativePath); - LOGGER.info("> Creating sub-folder {}", resolvedPath); - Files.createDirectories(resolvedPath); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - LOGGER.info("> Deleting folder {}", dir); - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Path relativePath = generatedFolder.relativize(file); - if (file.startsWith(generatedFolder)) { // don't copy logs - Path resolvedPath = dataFolderPath.resolve(relativePath); - LOGGER.info("> Moving {}", relativePath); - Files.move(file, resolvedPath); - } else { - LOGGER.info("> Deleting {}", relativePath); - Files.delete(file); - } - return FileVisitResult.CONTINUE; - } - }); - } - - private static void runDataGenerator(File serverJar) throws IOException { - final String javaExecutable = System.getProperty("java.home") + "/bin/java"; - ProcessBuilder dataGenerator = new ProcessBuilder(javaExecutable, "-cp", serverJar.getName(), "net.minecraft.data.Main", "--all", "--server", "--dev"); - dataGenerator.directory(TMP_FOLDER); - LOGGER.info("Now running data generator with options '--dev', '--server', '--all'"); - LOGGER.info("Executing: {}", String.join(StringUtils.SPACE, dataGenerator.command())); - LOGGER.info("Minestom will now wait for it to finish, here's its output:"); - LOGGER.info(""); - Process dataGeneratorProcess = dataGenerator.start(); - new BufferedReader( - new InputStreamReader(dataGeneratorProcess.getInputStream()) - ).lines().forEach(LOGGER::info); - new BufferedReader( - new InputStreamReader(dataGeneratorProcess.getErrorStream()) - ).lines().forEach(LOGGER::error); - LOGGER.info(""); - - try { - int resultCode = dataGeneratorProcess.waitFor(); - if (resultCode != 0) { - throw new IOException("Data generator finished with non-zero return code " + resultCode + " verify that you have 'java' cli"); - } - } catch (InterruptedException e) { - throw new IOException("Data generator was interrupted.", e); - } - } - - private static File downloadServerJar(String version) throws IOException { - // Mojang's version manifest is located at https://launchermeta.mojang.com/mc/game/version_manifest.json - // If we query this (it's a json object), we can then search for the id we want. - InputStream versionManifestStream = new URL("https://launchermeta.mojang.com/mc/game/version_manifest.json").openStream(); - LOGGER.debug("Successfully queried Mojang's version_manifest.json."); - - JsonObject versionManifestJson = GSON.fromJson(new InputStreamReader(versionManifestStream), JsonObject.class); - LOGGER.debug("Successfully read Mojang's version_manifest.json into a json object."); - - JsonArray versionArray = versionManifestJson.getAsJsonArray("versions"); - LOGGER.debug("Iterating over the version manifest to find a version with the id {}.", version); - - JsonObject versionEntry = null; - for (JsonElement element : versionArray) { - if (element.isJsonObject()) { - JsonObject entry = element.getAsJsonObject(); - if (entry.get("id").getAsString().equals(version)) { - LOGGER.debug("Successfully found a version with the id {}.", version); - versionEntry = entry; - break; - } - } - } - if (versionEntry == null) { - throw new IOException("Could not find " + version + " in Mojang's official list of minecraft versions."); - } - // We now have the entry we want and it gives us access to the json file containing the downloads. - String versionUrl = versionEntry.get("url").getAsString(); - InputStream versionStream = new URL(versionUrl).openStream(); - LOGGER.debug("Successfully queried {}.json.", version); - - JsonObject versionJson = GSON.fromJson(new InputStreamReader(versionStream), JsonObject.class); - LOGGER.debug("Successfully read {}.json into a json object.", version); - - // Now we need to navigate to "downloads.client.url" and "downloads.server.url" } - JsonObject downloadsJson = versionJson.getAsJsonObject("downloads"); - - // Designated spot if we ever need the client. - - // Server - { - JsonObject serverJson = downloadsJson.getAsJsonObject("server"); - final String jarURL = serverJson.get("url").getAsString(); - final String sha1 = serverJson.get("sha1").getAsString(); - - LOGGER.debug("Found all information required to download the server JAR file."); - LOGGER.debug("Attempting download."); - return download(version, jarURL, sha1); - } - } - - private static File download(@NotNull String version, @NotNull String url, @NotNull String sha1Source) throws IOException { - File target = new File(TMP_FOLDER, "server_" + version + ".jar"); - // Download - try (FastBufferedInputStream in = new FastBufferedInputStream(new URL(url).openStream())) { - Files.copy(in, target.toPath(), StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new IOException("Failed to download Minecraft server jar.", e); - } - // Verify checksum - try (FileInputStream fis = new FileInputStream(target)) { - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); - messageDigest.reset(); - messageDigest.update(fis.readAllBytes()); - byte[] digest = messageDigest.digest(); - StringBuffer sb = new StringBuffer(); - for (byte b : digest) { - sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); - } - // This just converts the sha1 back into a readable string. - String sha1Target = sb.toString(); - if (!sha1Target.equals(sha1Source)) { - LOGGER.error("The checksum test failed after downloading the Minecraft server jar."); - LOGGER.error("The expected checksum was: {}.", sha1Source); - LOGGER.error("The calculated checksum was: {}.", sha1Target); - throw new IOException("Failed to download Minecraft server jar."); - } - } catch (NoSuchAlgorithmException e) { - LOGGER.error("Failed to find SHA-1 hashing algorithm in Java Environment."); - throw new IOException("Failed to download Minecraft server jar."); - } - return target; - } -} diff --git a/src/test/java/loottables/TestLootTables.java b/src/test/java/loottables/TestLootTables.java index 45bc350e9..d84a8f714 100644 --- a/src/test/java/loottables/TestLootTables.java +++ b/src/test/java/loottables/TestLootTables.java @@ -1,6 +1,5 @@ package loottables; -import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; import net.minestom.server.data.DataImpl; import net.minestom.server.gamedata.conditions.SurvivesExplosionCondition; @@ -11,14 +10,12 @@ import net.minestom.server.gamedata.loottables.entries.ItemType; import net.minestom.server.gamedata.loottables.tabletypes.BlockType; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; -import net.minestom.server.registry.ResourceGatherer; import net.minestom.server.utils.NamespaceID; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.FileNotFoundException; -import java.io.IOException; import java.io.StringReader; import java.util.List; @@ -28,12 +25,6 @@ public class TestLootTables { @BeforeEach public void init() { - try { - ResourceGatherer.ensureResourcesArePresent(MinecraftServer.VERSION_NAME); - } catch (IOException e) { - e.printStackTrace(); - } - tableManager = new LootTableManager(); tableManager.registerConditionDeserializer(NamespaceID.from("minecraft:survives_explosion"), new SurvivesExplosionCondition.Deserializer()); tableManager.registerTableType(NamespaceID.from("minecraft:block"), new BlockType()); diff --git a/src/test/java/tags/TestTags.java b/src/test/java/tags/TestTags.java deleted file mode 100644 index 94da727cb..000000000 --- a/src/test/java/tags/TestTags.java +++ /dev/null @@ -1,104 +0,0 @@ -package tags; - -import net.minestom.server.gamedata.tags.Tag; -import net.minestom.server.gamedata.tags.TagManager; -import net.minestom.server.utils.NamespaceID; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.FileNotFoundException; -import java.io.StringReader; - -public class TestTags { - - private TagManager tags; - - @BeforeEach - public void init() { - tags = new TagManager(); - } - - @Test - public void testSubTag() throws FileNotFoundException { - String tag1 = "{\n" + - "\t\"replace\": false,\n" + - "\t\"values\": [\n" + - "\t\t\"minestom:an_item\"\n" + - "\t]\n" + - "}"; - - String tag2 = "{\n" + - "\t\"replace\": false,\n" + - "\t\"values\": [\n" + - "\t\t\"#minestom:test_sub\",\n" + - "\t\t\"minestom:some_other_item\"\n" + - "\t]\n" + - "}"; - Assertions.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test_sub"), "any", new StringReader(tag1))); - Tag loaded = tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag2)); - NamespaceID[] values = loaded.getValues().toArray(new NamespaceID[0]); - Assertions.assertEquals(2, values.length); - Assertions.assertTrue(loaded.contains(NamespaceID.from("minestom:an_item"))); - Assertions.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item"))); - Assertions.assertFalse(loaded.contains(NamespaceID.from("minestom:some_other_item_that_is_not_in_the_tag"))); - } - - /** - * A value of 'true' in 'replace' should replace previous contents - */ - @Test - public void testReplacement() throws FileNotFoundException { - String tag1 = "{\n" + - "\t\"replace\": false,\n" + - "\t\"values\": [\n" + - "\t\t\"minestom:an_item\"\n" + - "\t]\n" + - "}"; - - String tag2 = "{\n" + - "\t\"replace\": true,\n" + - "\t\"values\": [\n" + - "\t\t\"minestom:some_other_item\"\n" + - "\t]\n" + - "}"; - Assertions.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag1))); - Tag loaded = tags.forceLoad(NamespaceID.from("minestom:test"), "any", () -> new StringReader(tag2)); - Assertions.assertNotEquals(Tag.EMPTY, loaded); - Assertions.assertEquals(1, loaded.getValues().size()); - Assertions.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item"))); - Assertions.assertFalse(loaded.contains(NamespaceID.from("minestom:an_item"))); - } - - /** - * A value of 'false' in 'replace' should append to previous contents - */ - @Test - public void testAppend() throws FileNotFoundException { - String tag1 = "{\n" + - "\t\"replace\": false,\n" + - "\t\"values\": [\n" + - "\t\t\"minestom:an_item\"\n" + - "\t]\n" + - "}"; - - String tag2 = "{\n" + - "\t\"replace\": false,\n" + - "\t\"values\": [\n" + - "\t\t\"minestom:some_other_item\"\n" + - "\t]\n" + - "}"; - Assertions.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag1))); - Tag loaded = tags.forceLoad(NamespaceID.from("minestom:test"), "any", () -> new StringReader(tag2)); - Assertions.assertNotEquals(Tag.EMPTY, loaded); - Assertions.assertEquals(2, loaded.getValues().size()); - Assertions.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item"))); - Assertions.assertTrue(loaded.contains(NamespaceID.from("minestom:an_item"))); - } - - @AfterEach - public void cleanup() { - tags = null; - } -} From 34c5f5133e04b3641ba2b41fe2e29ebafab17a49 Mon Sep 17 00:00:00 2001 From: TheMode Date: Thu, 29 Jul 2021 13:24:29 +0200 Subject: [PATCH 2/2] Remove loot table api --- .../net/minestom/server/MinecraftServer.java | 13 -- .../minestom/server/gamedata/Condition.java | 20 --- .../SurvivesExplosionCondition.java | 34 ----- .../loottables/ConditionContainer.java | 36 ----- .../ConditionedFunctionWrapper.java | 30 ---- .../server/gamedata/loottables/LootTable.java | 134 ----------------- .../loottables/LootTableContainer.java | 115 -------------- .../loottables/LootTableEntryType.java | 10 -- .../loottables/LootTableFunction.java | 22 --- .../gamedata/loottables/LootTableManager.java | 136 ----------------- .../gamedata/loottables/LootTableType.java | 6 - .../gamedata/loottables/RangeContainer.java | 49 ------ .../loottables/entries/AlternativesEntry.java | 29 ---- .../loottables/entries/AlternativesType.java | 19 --- .../entries/AnotherLootTableEntry.java | 22 --- .../entries/AnotherLootTableType.java | 27 ---- .../loottables/entries/DynamicEntry.java | 36 ----- .../loottables/entries/DynamicType.java | 19 --- .../loottables/entries/GroupEntry.java | 24 --- .../loottables/entries/GroupType.java | 19 --- .../loottables/entries/ItemEntry.java | 42 ------ .../gamedata/loottables/entries/ItemType.java | 22 --- .../loottables/entries/SequenceEntry.java | 29 ---- .../loottables/entries/SequenceType.java | 19 --- .../gamedata/loottables/entries/TagEntry.java | 45 ------ .../gamedata/loottables/entries/TagType.java | 21 --- .../loottables/tabletypes/BlockType.java | 6 - src/test/java/loottables/TestLootTables.java | 140 ------------------ 28 files changed, 1124 deletions(-) delete mode 100644 src/main/java/net/minestom/server/gamedata/Condition.java delete mode 100644 src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/ConditionedFunctionWrapper.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTable.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTableEntryType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTableFunction.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/LootTableType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/RangeContainer.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/GroupEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/GroupType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/ItemEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/ItemType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/TagEntry.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java delete mode 100644 src/main/java/net/minestom/server/gamedata/loottables/tabletypes/BlockType.java delete mode 100644 src/test/java/loottables/TestLootTables.java diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index a2981821b..4d1b2a742 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -12,7 +12,6 @@ import net.minestom.server.exception.ExceptionManager; import net.minestom.server.extensions.Extension; import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.fluid.Fluid; -import net.minestom.server.gamedata.loottables.LootTableManager; import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.InstanceManager; @@ -129,7 +128,6 @@ public final class MinecraftServer { private static ResponseDataConsumer responseDataConsumer; private static String brandName = "Minestom"; private static Difficulty difficulty = Difficulty.NORMAL; - private static LootTableManager lootTableManager; private static TagManager tagManager; public static MinecraftServer init() { @@ -168,7 +166,6 @@ public final class MinecraftServer { updateManager = new UpdateManager(); - lootTableManager = new LootTableManager(); tagManager = new TagManager(); nettyServer = new NettyServer(packetProcessor); @@ -609,16 +606,6 @@ public final class MinecraftServer { return responseDataConsumer; } - /** - * Gets the manager handling loot tables. - * - * @return the loot table manager - */ - public static LootTableManager getLootTableManager() { - checkInitStatus(lootTableManager); - return lootTableManager; - } - /** * Gets the manager handling dimensions. * diff --git a/src/main/java/net/minestom/server/gamedata/Condition.java b/src/main/java/net/minestom/server/gamedata/Condition.java deleted file mode 100644 index 32fbf43eb..000000000 --- a/src/main/java/net/minestom/server/gamedata/Condition.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.minestom.server.gamedata; - -import net.minestom.server.data.Data; - -/** - * Represents a condition, used by predicates in MC functions and in loot tables. - */ -@FunctionalInterface -public interface Condition { - - /** - * Tests this condition. Subclasses are free to throw runtime exceptions if the arguments passed through data are not valid or missing - * @param data arguments to give to the condition. May be null if the condition supports it - * @return 'true' if the condition passed, 'false' otherwise - */ - boolean test(Data data); - - Condition ALWAYS_YES = (_d) -> true; - Condition ALWAYS_NO = (_d) -> false; -} diff --git a/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java b/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java deleted file mode 100644 index 84f087165..000000000 --- a/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.minestom.server.gamedata.conditions; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; - -import java.lang.reflect.Type; -import java.util.Random; - -/** - * Requires 'explosionPower' double argument - */ -public class SurvivesExplosionCondition implements Condition { - private Random rng = new Random(); - - @Override - public boolean test(Data data) { - if(data == null) - return true; // no explosion here - if(!data.hasKey("explosionPower")) - return true; // no explosion here - return rng.nextDouble() <= 1.0/data.get("explosionPower"); - } - - public static class Deserializer implements JsonDeserializer { - @Override - public SurvivesExplosionCondition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - return new SurvivesExplosionCondition(); - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java b/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java deleted file mode 100644 index 8d23962a5..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import com.google.gson.*; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.utils.NamespaceID; - -import java.lang.reflect.Type; - -public abstract class ConditionContainer { - private ConditionContainer() {} - - public abstract Condition create(LootTableManager lootTableManager); - - - static class Deserializer implements JsonDeserializer { - - private final LootTableManager lootTableManager; - - Deserializer(LootTableManager lootTableManager) { - this.lootTableManager = lootTableManager; - } - - @Override - public ConditionContainer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - JsonObject obj = json.getAsJsonObject(); - String type = obj.get("condition").getAsString(); - JsonDeserializer deserializer = lootTableManager.getConditionDeserializer(NamespaceID.from(type)); - return new ConditionContainer() { - @Override - public Condition create(LootTableManager lootTableManager) { - return deserializer.deserialize(obj, typeOfT, context); - } - }; - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/ConditionedFunctionWrapper.java b/src/main/java/net/minestom/server/gamedata/loottables/ConditionedFunctionWrapper.java deleted file mode 100644 index 4b4b9d0f6..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/ConditionedFunctionWrapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.item.ItemStack; - -import java.util.Collection; - -/** - * Loot table function that must meet some conditions to be applied - */ -public class ConditionedFunctionWrapper implements LootTableFunction { - - private final LootTableFunction baseFunction; - private final Collection conditions; - - public ConditionedFunctionWrapper(LootTableFunction baseFunction, Collection conditions) { - this.baseFunction = baseFunction; - this.conditions = conditions; - } - - @Override - public ItemStack apply(ItemStack stack, Data data) { - for (Condition c : conditions) { - if (!c.test(data)) - return stack; - } - return baseFunction.apply(stack, data); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTable.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTable.java deleted file mode 100644 index db39e47fc..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTable.java +++ /dev/null @@ -1,134 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.item.ItemStack; -import net.minestom.server.utils.WeightedRandom; -import net.minestom.server.utils.WeightedRandomItem; - -import java.util.LinkedList; -import java.util.List; -import java.util.Random; - -public class LootTable { - - public static final String LUCK_KEY = "minecraft:luck"; - - private final LootTableType type; - private final List pools; - - public LootTable(LootTableType type, List pools) { - this.type = type; - this.pools = pools; - } - - public LootTableType getType() { - return type; - } - - public List getPools() { - return pools; - } - - public List generate(Data arguments) { - if (arguments == null) - arguments = Data.EMPTY; - List output = new LinkedList<>(); - for (Pool p : pools) { - p.generate(output, arguments); - } - return output; - } - - public static class Pool { - private final int minRollCount; - private final int maxRollCount; - private final int bonusMinRollCount; - private final int bonusMaxRollCount; - private final List entries; - private final List conditions; - - public Pool(int minRollCount, int maxRollCount, int bonusMinRollCount, int bonusMaxRollCount, List entries, List conditions) { - this.minRollCount = minRollCount; - this.maxRollCount = maxRollCount; - this.bonusMinRollCount = bonusMinRollCount; - this.bonusMaxRollCount = bonusMaxRollCount; - this.entries = entries; - this.conditions = conditions; - } - - public List getConditions() { - return conditions; - } - - public int getMinRollCount() { - return minRollCount; - } - - public int getMaxRollCount() { - return maxRollCount; - } - - public List getEntries() { - return entries; - } - - public void generate(List output, Data arguments) { - for (Condition c : conditions) { - if (!c.test(arguments)) - return; - } - Random rng = new Random(); - int luck = arguments.getOrDefault(LUCK_KEY, 0); - int rollCount = rng.nextInt(maxRollCount - minRollCount + 1 /*inclusive*/) + minRollCount; - int bonusRollCount = rng.nextInt(bonusMaxRollCount - bonusMinRollCount + 1 /*inclusive*/) + bonusMinRollCount; - bonusRollCount *= luck; - // TODO: implement luck (quality/weight) weight=floor( weight + (quality * generic.luck)) - WeightedRandom weightedRandom = new WeightedRandom<>(entries); - for (int i = 0; i < rollCount + bonusRollCount; i++) { - Entry entry = weightedRandom.get(rng); - entry.generateStacks(output, arguments); - } - } - } - - public abstract static class Entry implements WeightedRandomItem { - private final LootTableEntryType type; - private final int weight; - private final int quality; - private final List conditions; - - public Entry(LootTableEntryType type, int weight, int quality, List conditions) { - this.type = type; - this.weight = weight; - this.quality = quality; - this.conditions = conditions; - } - - public List getConditions() { - return conditions; - } - - public int getQuality() { - return quality; - } - - public double getWeight() { - return weight; - } - - public LootTableEntryType getType() { - return type; - } - - public final void generateStacks(List output, Data arguments) { - for (Condition c : conditions) { - if (!c.test(arguments)) - return; - } - generate(output, arguments); - } - - protected abstract void generate(List output, Data arguments); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java deleted file mode 100644 index 23723148a..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java +++ /dev/null @@ -1,115 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.utils.NamespaceID; - -import java.util.LinkedList; -import java.util.List; - -/** - * Meant only for parsing loot tables - */ -class LootTableContainer { - - - private String type; - private LootTableContainer.Pool[] pools; - - private LootTableContainer() {} - - public LootTable createTable(LootTableManager lootTableManager) { - LootTableType type = lootTableManager.getTableType(NamespaceID.from(this.type)); - List pools = new LinkedList<>(); - if(this.pools != null) { - for(Pool p : this.pools) { - pools.add(p.create(lootTableManager)); - } - } - return new LootTable(type, pools); - } - - private static class Pool { - private ConditionContainer[] conditions; - private FunctionContainer[] functions; - private RangeContainer rolls; - private RangeContainer bonus_rools; - - private Entry[] entries; - - private Pool() {} - - public LootTable.Pool create(LootTableManager lootTableManager) { - List entries = new LinkedList<>(); - List conditions = new LinkedList<>(); - if(this.entries != null) { - for (Entry e : this.entries) { - entries.add(e.create(lootTableManager)); - } - } - if(this.conditions != null) { - for (ConditionContainer c : this.conditions) { - conditions.add(c.create(lootTableManager)); - } - } - if(rolls == null) - rolls = new RangeContainer(0,0); - if(bonus_rools == null) - bonus_rools = new RangeContainer(0,0); - return new LootTable.Pool(rolls.getMin(), rolls.getMax(), bonus_rools.getMin(), bonus_rools.getMax(), entries, conditions); - } - } - - private static class Entry { - private ConditionContainer[] conditions; - private String type; - private String name; - private Entry[] children; - private boolean expand; - private FunctionContainer[] functions; - private int weight; - private int quality; - - private Entry() {} - - public LootTable.Entry create(LootTableManager lootTableManager) { - LootTableEntryType entryType = lootTableManager.getEntryType(NamespaceID.from(type)); - List conditions = new LinkedList<>(); - if(this.conditions != null) { - for(ConditionContainer c : this.conditions) { - conditions.add(c.create(lootTableManager)); - } - } - List children = new LinkedList<>(); - if(this.children != null) { - for (Entry c : this.children) { - children.add(c.create(lootTableManager)); - } - } - List functions = new LinkedList<>(); - if(this.functions != null) { - for(FunctionContainer c : this.functions) { - functions.add(c.create(lootTableManager)); - } - } - return entryType.create(lootTableManager, name, conditions, children, expand, functions, weight, quality); - } - } - - private static class FunctionContainer { - private String function; - private ConditionContainer[] conditions; - - private FunctionContainer() {} - - public LootTableFunction create(LootTableManager lootTableManager) { - List conditions = new LinkedList<>(); - if(this.conditions != null) { - for(ConditionContainer c : this.conditions) { - conditions.add(c.create(lootTableManager)); - } - } - return new ConditionedFunctionWrapper(lootTableManager.getFunction(NamespaceID.from(function)), conditions); - } - } - -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableEntryType.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableEntryType.java deleted file mode 100644 index fa1a817d3..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableEntryType.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import net.minestom.server.gamedata.Condition; - -import java.util.List; - -@FunctionalInterface -public interface LootTableEntryType { - LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality); -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableFunction.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableFunction.java deleted file mode 100644 index 96ba2d901..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableFunction.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import net.minestom.server.data.Data; -import net.minestom.server.item.ItemStack; - -/** - * Changes to apply to the stack being produced - */ -@FunctionalInterface -public interface LootTableFunction { - - /** - * Applies changes to the stack being produced - * @param stack - * @param data arguments to pass to the function. - * @return - */ - ItemStack apply(ItemStack stack, Data data); - - LootTableFunction IDENTITY = (stack, _d) -> stack; -} - diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java deleted file mode 100644 index 5a160f454..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java +++ /dev/null @@ -1,136 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializer; -import net.minestom.server.MinecraftServer; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.utils.NamespaceID; -import net.minestom.server.utils.NamespaceIDHashMap; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Reader; - -/** - * Handles loading and configuration of loot tables - */ -public final class LootTableManager { - private NamespaceIDHashMap> conditionDeserializers = new NamespaceIDHashMap<>(); - private NamespaceIDHashMap tableTypes = new NamespaceIDHashMap<>(); - private NamespaceIDHashMap entryTypes = new NamespaceIDHashMap<>(); - private NamespaceIDHashMap functions = new NamespaceIDHashMap<>(); - private NamespaceIDHashMap cache = new NamespaceIDHashMap<>(); - private Gson gson; - - public LootTableManager() { - gson = new GsonBuilder() - .registerTypeAdapter(RangeContainer.class, new RangeContainer.Deserializer()) - .registerTypeAdapter(ConditionContainer.class, new ConditionContainer.Deserializer(this)) - .create(); - } - - /** - * Registers a condition factory to the given namespaceID - * - * @param namespaceID - * @param factory - */ - public void registerConditionDeserializer(NamespaceID namespaceID, JsonDeserializer factory) { - conditionDeserializers.put(namespaceID, factory); - } - - /** - * Registers a loot table type to the given namespaceID - * - * @param namespaceID - * @param type - */ - public void registerTableType(NamespaceID namespaceID, LootTableType type) { - tableTypes.put(namespaceID, type); - } - - /** - * Registers a loot table entry type to the given namespaceID - * - * @param namespaceID - * @param type - */ - public void registerEntryType(NamespaceID namespaceID, LootTableEntryType type) { - entryTypes.put(namespaceID, type); - } - - /** - * Registers a loot table function to the given namespaceID - * - * @param namespaceID - * @param function - */ - public void registerFunction(NamespaceID namespaceID, LootTableFunction function) { - functions.put(namespaceID, function); - } - - public LootTable load(NamespaceID name) throws FileNotFoundException { - return null; // FIXME - //return load(name, new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/loot_tables/" + name.getPath() + ".json"))); - } - - /** - * Loads a loot table with the given name. Loot tables can be cached, so 'reader' is used only on cache misses - * - * @param name the name to cache the loot table with - * @param reader the reader to read the loot table from, if none cached. **Will** be closed no matter the results of this call - * @return - */ - public LootTable load(NamespaceID name, Reader reader) { - try (reader) { - return cache.computeIfAbsent(name, _name -> create(reader)); - } catch (IOException e) { - MinecraftServer.getExceptionManager().handleException(e); - return null; - } - } - - private LootTable create(Reader reader) { - LootTableContainer container = gson.fromJson(reader, LootTableContainer.class); - return container.createTable(this); - } - - /** - * Returns the registered table type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException} - * - * @param id - * @return - */ - public LootTableType getTableType(NamespaceID id) { - if (!tableTypes.containsKey(id)) - throw new IllegalArgumentException("Unknown table type: " + id); - return tableTypes.get(id); - } - - /** - * Returns the registered entry type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException} - * - * @param id - * @return - */ - public LootTableEntryType getEntryType(NamespaceID id) { - if (!entryTypes.containsKey(id)) - throw new IllegalArgumentException("Unknown entry type: " + id); - return entryTypes.get(id); - } - - /** - * Returns the registered table type corresponding to the given namespace ID. If none is registered, returns {@link LootTableFunction#IDENTITY} - * - * @param id - * @return - */ - public LootTableFunction getFunction(NamespaceID id) { - return functions.getOrDefault(id, LootTableFunction.IDENTITY); - } - - public JsonDeserializer getConditionDeserializer(NamespaceID id) { - return conditionDeserializers.getOrDefault(id, (json, typeOfT, context) -> Condition.ALWAYS_NO); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableType.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableType.java deleted file mode 100644 index 053e29806..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableType.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -public interface LootTableType { - - // TODO -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/RangeContainer.java b/src/main/java/net/minestom/server/gamedata/loottables/RangeContainer.java deleted file mode 100644 index 7a415a1b8..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/RangeContainer.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.minestom.server.gamedata.loottables; - -import com.google.gson.*; - -import java.lang.reflect.Type; - -public class RangeContainer { - - private int min; - private int max; - - RangeContainer() {} - - public RangeContainer(int min, int max) { - this.min = min; - this.max = max; - } - - public int getMin() { - return min; - } - - public int getMax() { - return max; - } - - public static class Deserializer implements JsonDeserializer { - - @Override - public RangeContainer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - RangeContainer range = new RangeContainer(); - if(json.isJsonPrimitive()) { - range.min = json.getAsInt(); - range.max = json.getAsInt(); - } else if(json.isJsonObject()) { - JsonObject obj = json.getAsJsonObject(); - if(!obj.has("min")) - throw new IllegalArgumentException("Missing 'min' property"); - if(!obj.has("max")) - throw new IllegalArgumentException("Missing 'max' property"); - range.min = obj.get("min").getAsInt(); - range.max = obj.get("max").getAsInt(); - } else { - throw new IllegalArgumentException("Range must be single integer or an object with 'min' and 'max' properties"); - } - return range; - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesEntry.java deleted file mode 100644 index 6ede7cea8..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesEntry.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.item.ItemStack; - -import java.util.List; - -public class AlternativesEntry extends LootTable.Entry { - private final List children; - - public AlternativesEntry(AlternativesType type, List children, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.children = children; - } - - @Override - public void generate(List output, Data arguments) { - for (LootTable.Entry c : children) { - int previousSize = output.size(); - c.generateStacks(output, arguments); - int newSize = output.size(); - if (newSize != previousSize) { // an entry managed to generate, stop here - return; - } - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesType.java deleted file mode 100644 index 0b4ffbdfd..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/AlternativesType.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; - -import java.util.List; - -/** - * minecraft:alternatives - */ -public class AlternativesType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - return new AlternativesEntry(this, children, weight, quality, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableEntry.java deleted file mode 100644 index 131ae71ed..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableEntry.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.item.ItemStack; - -import java.util.List; - -public class AnotherLootTableEntry extends LootTable.Entry { - private final LootTable table; - - public AnotherLootTableEntry(AnotherLootTableType type, LootTable table, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.table = table; - } - - @Override - public void generate(List output, Data arguments) { - output.addAll(table.generate(arguments)); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableType.java deleted file mode 100644 index 0d9a78041..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/AnotherLootTableType.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; -import net.minestom.server.utils.NamespaceID; - -import java.io.FileNotFoundException; -import java.util.List; - -/** - * Allows to sample from a different loot table - * - * minecraft:loot_table - */ -public class AnotherLootTableType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - try { - return new AnotherLootTableEntry(this, lootTableManager.load(NamespaceID.from(name)), weight, quality, conditions); - } catch (FileNotFoundException e) { - throw new IllegalArgumentException(name+" is not a valid loot table name", e); - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicEntry.java deleted file mode 100644 index 24eb51e2f..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicEntry.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.item.ItemStack; - -import java.util.Collections; -import java.util.List; - -public class DynamicEntry extends LootTable.Entry { - - public static final String DROP_LIST_KEY = "minestom:loot_table_drop_list"; - - private final DynamicEntry.Type entryType; - - public DynamicEntry(DynamicType type, DynamicEntry.Type entryType, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.entryType = entryType; - } - - @Override - public void generate(List output, Data arguments) { - List toDrop = arguments.getOrDefault(DROP_LIST_KEY, Collections.emptyList()); - output.addAll(toDrop); - } - - public DynamicEntry.Type getEntryType() { - return entryType; - } - - public enum Type { - SELF, - CONTENTS - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicType.java deleted file mode 100644 index ff71fa425..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/DynamicType.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; - -import java.util.List; - -/** - * minecraft:dynamic - */ -public class DynamicType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - return new DynamicEntry(this, DynamicEntry.Type.valueOf(name.toUpperCase()), weight, quality, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupEntry.java deleted file mode 100644 index 6ae72c5c5..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupEntry.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.item.ItemStack; - -import java.util.List; - -public class GroupEntry extends LootTable.Entry { - private final List children; - - public GroupEntry(GroupType type, List children, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.children = children; - } - - @Override - public void generate(List output, Data arguments) { - for (LootTable.Entry child : children) { - child.generateStacks(output, arguments); - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupType.java deleted file mode 100644 index 2681560cd..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/GroupType.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; - -import java.util.List; - -/** - * minecraft:group - */ -public class GroupType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - return new GroupEntry(this, children, weight, quality, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemEntry.java deleted file mode 100644 index 9d5b257bc..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemEntry.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; - -import java.util.LinkedList; -import java.util.List; - -public class ItemEntry extends LootTable.Entry { - - private final List functions; - private final Material item; - - ItemEntry(ItemType type, Material baseItem, int weight, int quality, List functions, List conditions) { - super(type, weight, quality, conditions); - this.item = baseItem; - this.functions = new LinkedList<>(functions); - } - - @Override - public void generate(List output, Data arguments) { - ItemStack stack = ItemStack.of(item); - for (LootTableFunction function : functions) { - stack = function.apply(stack, arguments); - } - if (!stack.isAir()) { - output.add(stack); - } - } - - public List getFunctions() { - return functions; - } - - public Material getItem() { - return item; - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemType.java deleted file mode 100644 index dc3fc8be7..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/ItemType.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; -import net.minestom.server.item.Material; -import net.minestom.server.utils.NamespaceID; - -import java.util.List; - -/** - * minecraft:item - */ -public class ItemType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - NamespaceID itemID = NamespaceID.from(name); - return new ItemEntry(this, Material.fromNamespaceId(itemID), weight, quality, functions, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceEntry.java deleted file mode 100644 index f1245e8e3..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceEntry.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.item.ItemStack; - -import java.util.List; - -public class SequenceEntry extends LootTable.Entry { - private final List children; - - public SequenceEntry(SequenceType type, List children, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.children = children; - } - - @Override - public void generate(List output, Data arguments) { - for (LootTable.Entry c : children) { - int previousSize = output.size(); - c.generateStacks(output, arguments); - int newSize = output.size(); - if (newSize == previousSize) { // an entry failed to generate, stop here - return; - } - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceType.java deleted file mode 100644 index 6e2c3f884..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/SequenceType.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; - -import java.util.List; - -/** - * minecraft:sequence - */ -public class SequenceType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - return new SequenceEntry(this, children, weight, quality, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagEntry.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/TagEntry.java deleted file mode 100644 index c01eb7284..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagEntry.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.data.Data; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.tags.Tag; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.minestom.server.utils.NamespaceID; - -import java.util.List; -import java.util.Random; -import java.util.Set; - -public class TagEntry extends LootTable.Entry { - private final Tag tag; - private final boolean expand; - private Random rng = new Random(); - - TagEntry(TagType type, Tag tag, boolean expand, int weight, int quality, List conditions) { - super(type, weight, quality, conditions); - this.tag = tag; - this.expand = expand; - } - - @Override - public void generate(List output, Data arguments) { - Set values = tag.getValues(); - if (values.isEmpty()) - return; - Material[] asArrayOfItems = new Material[values.size()]; - int ptr = 0; - for (NamespaceID id : values) { - asArrayOfItems[ptr++] = Material.fromNamespaceId(id); - } - if (expand) { - Material selectedMaterial = asArrayOfItems[rng.nextInt(asArrayOfItems.length)]; - output.add(ItemStack.of(selectedMaterial)); - } else { - for (Material material : asArrayOfItems) { - output.add(ItemStack.of(material)); - } - } - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java b/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java deleted file mode 100644 index b804af71f..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/entries/TagType.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.minestom.server.gamedata.loottables.entries; - -import net.minestom.server.MinecraftServer; -import net.minestom.server.gamedata.Condition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableEntryType; -import net.minestom.server.gamedata.loottables.LootTableFunction; -import net.minestom.server.gamedata.loottables.LootTableManager; -import net.minestom.server.gamedata.tags.Tag; - -import java.util.List; - -/** - * minecraft:tag - */ -public class TagType implements LootTableEntryType { - @Override - public LootTable.Entry create(LootTableManager lootTableManager, String name, List conditions, List children, boolean expand, List functions, int weight, int quality) { - return new TagEntry(this, MinecraftServer.getTagManager().getTag(Tag.BasicType.ITEMS, name), expand, weight, quality, conditions); - } -} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/tabletypes/BlockType.java b/src/main/java/net/minestom/server/gamedata/loottables/tabletypes/BlockType.java deleted file mode 100644 index e41500785..000000000 --- a/src/main/java/net/minestom/server/gamedata/loottables/tabletypes/BlockType.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.minestom.server.gamedata.loottables.tabletypes; - -import net.minestom.server.gamedata.loottables.LootTableType; - -public class BlockType implements LootTableType { -} diff --git a/src/test/java/loottables/TestLootTables.java b/src/test/java/loottables/TestLootTables.java deleted file mode 100644 index d84a8f714..000000000 --- a/src/test/java/loottables/TestLootTables.java +++ /dev/null @@ -1,140 +0,0 @@ -package loottables; - -import net.minestom.server.data.Data; -import net.minestom.server.data.DataImpl; -import net.minestom.server.gamedata.conditions.SurvivesExplosionCondition; -import net.minestom.server.gamedata.loottables.LootTable; -import net.minestom.server.gamedata.loottables.LootTableManager; -import net.minestom.server.gamedata.loottables.entries.ItemEntry; -import net.minestom.server.gamedata.loottables.entries.ItemType; -import net.minestom.server.gamedata.loottables.tabletypes.BlockType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.minestom.server.utils.NamespaceID; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.FileNotFoundException; -import java.io.StringReader; -import java.util.List; - -public class TestLootTables { - - private LootTableManager tableManager; - - @BeforeEach - public void init() { - tableManager = new LootTableManager(); - tableManager.registerConditionDeserializer(NamespaceID.from("minecraft:survives_explosion"), new SurvivesExplosionCondition.Deserializer()); - tableManager.registerTableType(NamespaceID.from("minecraft:block"), new BlockType()); - tableManager.registerEntryType(NamespaceID.from("minecraft:item"), new ItemType()); - } - - @Test - public void loadFromString() { - // from acacia_button.json - final String lootTableJson = "{\n" + - " \"type\": \"minecraft:block\",\n" + - " \"pools\": [\n" + - " {\n" + - " \"rolls\": 1,\n" + - " \"entries\": [\n" + - " {\n" + - " \"type\": \"minecraft:item\",\n" + - " \"name\": \"minecraft:acacia_button\"\n" + - " }\n" + - " ],\n" + - " \"conditions\": [\n" + - " {\n" + - " \"condition\": \"minecraft:survives_explosion\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - "}"; - LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button"), new StringReader(lootTableJson)); - Assertions.assertTrue(lootTable.getType() instanceof BlockType); - Assertions.assertEquals(1, lootTable.getPools().size()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getMinRollCount()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getMaxRollCount()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getEntries().size()); - Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0).getType() instanceof ItemType); - Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0) instanceof ItemEntry); - ItemEntry entry = (ItemEntry) lootTable.getPools().get(0).getEntries().get(0); - Assertions.assertEquals(Material.ACACIA_BUTTON, entry.getItem()); - Assertions.assertEquals(0, entry.getFunctions().size()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getConditions().size()); - Assertions.assertTrue(lootTable.getPools().get(0).getConditions().get(0) instanceof SurvivesExplosionCondition); - } - - @Test - public void loadFromFile() throws FileNotFoundException { - LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button")); - Assertions.assertTrue(lootTable.getType() instanceof BlockType); - Assertions.assertEquals(1, lootTable.getPools().size()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getMinRollCount()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getMaxRollCount()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getEntries().size()); - Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0).getType() instanceof ItemType); - Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0) instanceof ItemEntry); - ItemEntry entry = (ItemEntry) lootTable.getPools().get(0).getEntries().get(0); - Assertions.assertEquals(Material.ACACIA_BUTTON, entry.getItem()); - Assertions.assertEquals(0, entry.getFunctions().size()); - Assertions.assertEquals(1, lootTable.getPools().get(0).getConditions().size()); - Assertions.assertTrue(lootTable.getPools().get(0).getConditions().get(0) instanceof SurvivesExplosionCondition); - } - - @Test - public void caching() throws FileNotFoundException { - LootTable lootTable1 = tableManager.load(NamespaceID.from("blocks/acacia_button")); - LootTable lootTable2 = tableManager.load(NamespaceID.from("blocks/acacia_button")); - Assertions.assertSame(lootTable1, lootTable2); - } - - @Test - public void simpleGenerate() throws FileNotFoundException { - LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button")); - Data arguments = new DataImpl(); - List stacks = lootTable.generate(arguments); - Assertions.assertEquals(1, stacks.size()); - Assertions.assertEquals(Material.ACACIA_BUTTON, stacks.get(0).getMaterial()); - } - - @Test - public void testExplosion() throws FileNotFoundException { - LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button")); - Data arguments = new DataImpl(); - // negative value will force the condition to fail - arguments.set("explosionPower", -1.0, Double.class); - List stacks = lootTable.generate(arguments); - Assertions.assertEquals(0, stacks.size()); - } - - @Test - public void unknownCondition() { - // from acacia_button.json - final String lootTableJson = "{\n" + - " \"type\": \"minecraft:block\",\n" + - " \"pools\": [\n" + - " {\n" + - " \"rolls\": 1,\n" + - " \"entries\": [\n" + - " {\n" + - " \"type\": \"minecraft:item\",\n" + - " \"name\": \"minecraft:acacia_button\"\n" + - " }\n" + - " ],\n" + - " \"conditions\": [\n" + - " {\n" + - " \"condition\": \"minestom:unknown\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - "}"; - LootTable lootTable = tableManager.load(NamespaceID.from("blocks/none"), new StringReader(lootTableJson)); - List stacks = lootTable.generate(Data.EMPTY); - Assertions.assertEquals(0, stacks.size()); - } -}