diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index f619b94eb..519d95707 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -46,6 +46,7 @@ public final class MinecraftServer { public static final String VERSION_NAME = "1.20.5-pre1"; public static final int PROTOCOL_VERSION = 1073742009; + public static final int DATA_VERSION = 3829; // Threads public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark"; diff --git a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java index d919c6fee..488e27697 100644 --- a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java +++ b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java @@ -7,7 +7,6 @@ import net.minestom.server.entity.metadata.animal.*; import net.minestom.server.entity.metadata.animal.tameable.CatMeta; import net.minestom.server.entity.metadata.animal.tameable.ParrotMeta; import net.minestom.server.entity.metadata.animal.tameable.WolfMeta; -import net.minestom.server.entity.metadata.projectile.*; import net.minestom.server.entity.metadata.display.BlockDisplayMeta; import net.minestom.server.entity.metadata.display.ItemDisplayMeta; import net.minestom.server.entity.metadata.display.TextDisplayMeta; @@ -20,11 +19,13 @@ import net.minestom.server.entity.metadata.item.*; import net.minestom.server.entity.metadata.minecart.*; import net.minestom.server.entity.metadata.monster.*; import net.minestom.server.entity.metadata.monster.raider.*; +import net.minestom.server.entity.metadata.monster.skeleton.BoggedMeta; import net.minestom.server.entity.metadata.monster.skeleton.SkeletonMeta; import net.minestom.server.entity.metadata.monster.skeleton.StrayMeta; import net.minestom.server.entity.metadata.monster.skeleton.WitherSkeletonMeta; import net.minestom.server.entity.metadata.monster.zombie.*; import net.minestom.server.entity.metadata.other.*; +import net.minestom.server.entity.metadata.projectile.*; import net.minestom.server.entity.metadata.villager.VillagerMeta; import net.minestom.server.entity.metadata.villager.WanderingTraderMeta; import net.minestom.server.entity.metadata.water.AxolotlMeta; @@ -39,8 +40,6 @@ import java.util.Collection; import java.util.Map; import java.util.function.BiFunction; -import static java.util.Map.entry; - record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ENTITIES, (namespace, properties) -> new EntityTypeImpl(Registry.entity(namespace, properties))); @@ -73,132 +72,136 @@ record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { private static Map> createMetaMap() { return Map.>ofEntries( - entry("minecraft:allay", AllayMeta::new), - entry("minecraft:area_effect_cloud", AreaEffectCloudMeta::new), - entry("minecraft:armor_stand", ArmorStandMeta::new), - entry("minecraft:arrow", ArrowMeta::new), - entry("minecraft:axolotl", AxolotlMeta::new), - entry("minecraft:bat", BatMeta::new), - entry("minecraft:bee", BeeMeta::new), - entry("minecraft:blaze", BlazeMeta::new), - entry("minecraft:block_display", BlockDisplayMeta::new), - entry("minecraft:boat", BoatMeta::new), - entry("minecraft:breeze", BreezeMeta::new), - entry("minecraft:chest_boat", BoatMeta::new), - entry("minecraft:camel", CamelMeta::new), - entry("minecraft:cat", CatMeta::new), - entry("minecraft:cave_spider", CaveSpiderMeta::new), - entry("minecraft:chicken", ChickenMeta::new), - entry("minecraft:cod", CodMeta::new), - entry("minecraft:cow", CowMeta::new), - entry("minecraft:creeper", CreeperMeta::new), - entry("minecraft:dolphin", DolphinMeta::new), - entry("minecraft:donkey", DonkeyMeta::new), - entry("minecraft:dragon_fireball", DragonFireballMeta::new), - entry("minecraft:drowned", DrownedMeta::new), - entry("minecraft:elder_guardian", ElderGuardianMeta::new), - entry("minecraft:end_crystal", EndCrystalMeta::new), - entry("minecraft:ender_dragon", EnderDragonMeta::new), - entry("minecraft:enderman", EndermanMeta::new), - entry("minecraft:endermite", EndermiteMeta::new), - entry("minecraft:evoker", EvokerMeta::new), - entry("minecraft:evoker_fangs", EvokerFangsMeta::new), - entry("minecraft:experience_orb", ExperienceOrbMeta::new), - entry("minecraft:eye_of_ender", EyeOfEnderMeta::new), - entry("minecraft:falling_block", FallingBlockMeta::new), - entry("minecraft:firework_rocket", FireworkRocketMeta::new), - entry("minecraft:fox", FoxMeta::new), - entry("minecraft:frog", FrogMeta::new), - entry("minecraft:ghast", GhastMeta::new), - entry("minecraft:giant", GiantMeta::new), - entry("minecraft:glow_item_frame", GlowItemFrameMeta::new), - entry("minecraft:glow_squid", GlowSquidMeta::new), - entry("minecraft:goat", GoatMeta::new), - entry("minecraft:guardian", GuardianMeta::new), - entry("minecraft:hoglin", HoglinMeta::new), - entry("minecraft:horse", HorseMeta::new), - entry("minecraft:husk", HuskMeta::new), - entry("minecraft:illusioner", IllusionerMeta::new), - entry("minecraft:interaction", InteractionMeta::new), - entry("minecraft:iron_golem", IronGolemMeta::new), - entry("minecraft:item", ItemEntityMeta::new), - entry("minecraft:item_display", ItemDisplayMeta::new), - entry("minecraft:item_frame", ItemFrameMeta::new), - entry("minecraft:fireball", FireballMeta::new), - entry("minecraft:leash_knot", LeashKnotMeta::new), - entry("minecraft:lightning_bolt", LightningBoltMeta::new), - entry("minecraft:llama", LlamaMeta::new), - entry("minecraft:llama_spit", LlamaSpitMeta::new), - entry("minecraft:magma_cube", MagmaCubeMeta::new), - entry("minecraft:marker", MarkerMeta::new), - entry("minecraft:minecart", MinecartMeta::new), - entry("minecraft:chest_minecart", ChestMinecartMeta::new), - entry("minecraft:command_block_minecart", CommandBlockMinecartMeta::new), - entry("minecraft:furnace_minecart", FurnaceMinecartMeta::new), - entry("minecraft:hopper_minecart", HopperMinecartMeta::new), - entry("minecraft:spawner_minecart", SpawnerMinecartMeta::new), - entry("minecraft:text_display", TextDisplayMeta::new), - entry("minecraft:tnt_minecart", TntMinecartMeta::new), - entry("minecraft:mule", MuleMeta::new), - entry("minecraft:mooshroom", MooshroomMeta::new), - entry("minecraft:ocelot", OcelotMeta::new), - entry("minecraft:painting", PaintingMeta::new), - entry("minecraft:panda", PandaMeta::new), - entry("minecraft:parrot", ParrotMeta::new), - entry("minecraft:phantom", PhantomMeta::new), - entry("minecraft:pig", PigMeta::new), - entry("minecraft:piglin", PiglinMeta::new), - entry("minecraft:piglin_brute", PiglinBruteMeta::new), - entry("minecraft:pillager", PillagerMeta::new), - entry("minecraft:polar_bear", PolarBearMeta::new), - entry("minecraft:tnt", PrimedTntMeta::new), - entry("minecraft:pufferfish", PufferfishMeta::new), - entry("minecraft:rabbit", RabbitMeta::new), - entry("minecraft:ravager", RavagerMeta::new), - entry("minecraft:salmon", SalmonMeta::new), - entry("minecraft:sheep", SheepMeta::new), - entry("minecraft:shulker", ShulkerMeta::new), - entry("minecraft:shulker_bullet", ShulkerBulletMeta::new), - entry("minecraft:silverfish", SilverfishMeta::new), - entry("minecraft:skeleton", SkeletonMeta::new), - entry("minecraft:skeleton_horse", SkeletonHorseMeta::new), - entry("minecraft:slime", SlimeMeta::new), - entry("minecraft:small_fireball", SmallFireballMeta::new), - entry("minecraft:sniffer", SnifferMeta::new), - entry("minecraft:snow_golem", SnowGolemMeta::new), - entry("minecraft:snowball", SnowballMeta::new), - entry("minecraft:spectral_arrow", SpectralArrowMeta::new), - entry("minecraft:spider", SpiderMeta::new), - entry("minecraft:squid", SquidMeta::new), - entry("minecraft:stray", StrayMeta::new), - entry("minecraft:strider", StriderMeta::new), - entry("minecraft:tadpole", TadpoleMeta::new), - entry("minecraft:egg", ThrownEggMeta::new), - entry("minecraft:ender_pearl", ThrownEnderPearlMeta::new), - entry("minecraft:experience_bottle", ThrownExperienceBottleMeta::new), - entry("minecraft:potion", ThrownPotionMeta::new), - entry("minecraft:trident", ThrownTridentMeta::new), - entry("minecraft:trader_llama", TraderLlamaMeta::new), - entry("minecraft:tropical_fish", TropicalFishMeta::new), - entry("minecraft:turtle", TurtleMeta::new), - entry("minecraft:vex", VexMeta::new), - entry("minecraft:villager", VillagerMeta::new), - entry("minecraft:vindicator", VindicatorMeta::new), - entry("minecraft:wandering_trader", WanderingTraderMeta::new), - entry("minecraft:warden", WardenMeta::new), - entry("minecraft:wind_charge", WindChargeMeta::new), - entry("minecraft:witch", WitchMeta::new), - entry("minecraft:wither", WitherMeta::new), - entry("minecraft:wither_skeleton", WitherSkeletonMeta::new), - entry("minecraft:wither_skull", WitherSkullMeta::new), - entry("minecraft:wolf", WolfMeta::new), - entry("minecraft:zoglin", ZoglinMeta::new), - entry("minecraft:zombie", ZombieMeta::new), - entry("minecraft:zombie_horse", ZombieHorseMeta::new), - entry("minecraft:zombie_villager", ZombieVillagerMeta::new), - entry("minecraft:zombified_piglin", ZombifiedPiglinMeta::new), - entry("minecraft:player", PlayerMeta::new), - entry("minecraft:fishing_bobber", FishingHookMeta::new) + Map.entry("minecraft:allay", AllayMeta::new), + Map.entry("minecraft:area_effect_cloud", AreaEffectCloudMeta::new), + Map.entry("minecraft:armadillo", ArmadilloMeta::new), + Map.entry("minecraft:armor_stand", ArmorStandMeta::new), + Map.entry("minecraft:arrow", ArrowMeta::new), + Map.entry("minecraft:axolotl", AxolotlMeta::new), + Map.entry("minecraft:bat", BatMeta::new), + Map.entry("minecraft:bee", BeeMeta::new), + Map.entry("minecraft:blaze", BlazeMeta::new), + Map.entry("minecraft:block_display", BlockDisplayMeta::new), + Map.entry("minecraft:boat", BoatMeta::new), + Map.entry("minecraft:bogged", BoggedMeta::new), + Map.entry("minecraft:breeze", BreezeMeta::new), + Map.entry("minecraft:breeze_wind_charge", BreezeWindChargeMeta::new), + Map.entry("minecraft:chest_boat", BoatMeta::new), + Map.entry("minecraft:camel", CamelMeta::new), + Map.entry("minecraft:cat", CatMeta::new), + Map.entry("minecraft:cave_spider", CaveSpiderMeta::new), + Map.entry("minecraft:chicken", ChickenMeta::new), + Map.entry("minecraft:cod", CodMeta::new), + Map.entry("minecraft:cow", CowMeta::new), + Map.entry("minecraft:creeper", CreeperMeta::new), + Map.entry("minecraft:dolphin", DolphinMeta::new), + Map.entry("minecraft:donkey", DonkeyMeta::new), + Map.entry("minecraft:dragon_fireball", DragonFireballMeta::new), + Map.entry("minecraft:drowned", DrownedMeta::new), + Map.entry("minecraft:elder_guardian", ElderGuardianMeta::new), + Map.entry("minecraft:end_crystal", EndCrystalMeta::new), + Map.entry("minecraft:ender_dragon", EnderDragonMeta::new), + Map.entry("minecraft:enderman", EndermanMeta::new), + Map.entry("minecraft:endermite", EndermiteMeta::new), + Map.entry("minecraft:evoker", EvokerMeta::new), + Map.entry("minecraft:evoker_fangs", EvokerFangsMeta::new), + Map.entry("minecraft:experience_orb", ExperienceOrbMeta::new), + Map.entry("minecraft:eye_of_ender", EyeOfEnderMeta::new), + Map.entry("minecraft:falling_block", FallingBlockMeta::new), + Map.entry("minecraft:firework_rocket", FireworkRocketMeta::new), + Map.entry("minecraft:fox", FoxMeta::new), + Map.entry("minecraft:frog", FrogMeta::new), + Map.entry("minecraft:ghast", GhastMeta::new), + Map.entry("minecraft:giant", GiantMeta::new), + Map.entry("minecraft:glow_item_frame", GlowItemFrameMeta::new), + Map.entry("minecraft:glow_squid", GlowSquidMeta::new), + Map.entry("minecraft:goat", GoatMeta::new), + Map.entry("minecraft:guardian", GuardianMeta::new), + Map.entry("minecraft:hoglin", HoglinMeta::new), + Map.entry("minecraft:horse", HorseMeta::new), + Map.entry("minecraft:husk", HuskMeta::new), + Map.entry("minecraft:illusioner", IllusionerMeta::new), + Map.entry("minecraft:interaction", InteractionMeta::new), + Map.entry("minecraft:iron_golem", IronGolemMeta::new), + Map.entry("minecraft:item", ItemEntityMeta::new), + Map.entry("minecraft:item_display", ItemDisplayMeta::new), + Map.entry("minecraft:item_frame", ItemFrameMeta::new), + Map.entry("minecraft:fireball", FireballMeta::new), + Map.entry("minecraft:leash_knot", LeashKnotMeta::new), + Map.entry("minecraft:lightning_bolt", LightningBoltMeta::new), + Map.entry("minecraft:llama", LlamaMeta::new), + Map.entry("minecraft:llama_spit", LlamaSpitMeta::new), + Map.entry("minecraft:magma_cube", MagmaCubeMeta::new), + Map.entry("minecraft:marker", MarkerMeta::new), + Map.entry("minecraft:minecart", MinecartMeta::new), + Map.entry("minecraft:chest_minecart", ChestMinecartMeta::new), + Map.entry("minecraft:command_block_minecart", CommandBlockMinecartMeta::new), + Map.entry("minecraft:furnace_minecart", FurnaceMinecartMeta::new), + Map.entry("minecraft:hopper_minecart", HopperMinecartMeta::new), + Map.entry("minecraft:spawner_minecart", SpawnerMinecartMeta::new), + Map.entry("minecraft:text_display", TextDisplayMeta::new), + Map.entry("minecraft:tnt_minecart", TntMinecartMeta::new), + Map.entry("minecraft:mule", MuleMeta::new), + Map.entry("minecraft:mooshroom", MooshroomMeta::new), + Map.entry("minecraft:ocelot", OcelotMeta::new), + Map.entry("minecraft:ominous_item_spawner", OminousItemSpawnerMeta::new), + Map.entry("minecraft:painting", PaintingMeta::new), + Map.entry("minecraft:panda", PandaMeta::new), + Map.entry("minecraft:parrot", ParrotMeta::new), + Map.entry("minecraft:phantom", PhantomMeta::new), + Map.entry("minecraft:pig", PigMeta::new), + Map.entry("minecraft:piglin", PiglinMeta::new), + Map.entry("minecraft:piglin_brute", PiglinBruteMeta::new), + Map.entry("minecraft:pillager", PillagerMeta::new), + Map.entry("minecraft:polar_bear", PolarBearMeta::new), + Map.entry("minecraft:tnt", PrimedTntMeta::new), + Map.entry("minecraft:pufferfish", PufferfishMeta::new), + Map.entry("minecraft:rabbit", RabbitMeta::new), + Map.entry("minecraft:ravager", RavagerMeta::new), + Map.entry("minecraft:salmon", SalmonMeta::new), + Map.entry("minecraft:sheep", SheepMeta::new), + Map.entry("minecraft:shulker", ShulkerMeta::new), + Map.entry("minecraft:shulker_bullet", ShulkerBulletMeta::new), + Map.entry("minecraft:silverfish", SilverfishMeta::new), + Map.entry("minecraft:skeleton", SkeletonMeta::new), + Map.entry("minecraft:skeleton_horse", SkeletonHorseMeta::new), + Map.entry("minecraft:slime", SlimeMeta::new), + Map.entry("minecraft:small_fireball", SmallFireballMeta::new), + Map.entry("minecraft:sniffer", SnifferMeta::new), + Map.entry("minecraft:snow_golem", SnowGolemMeta::new), + Map.entry("minecraft:snowball", SnowballMeta::new), + Map.entry("minecraft:spectral_arrow", SpectralArrowMeta::new), + Map.entry("minecraft:spider", SpiderMeta::new), + Map.entry("minecraft:squid", SquidMeta::new), + Map.entry("minecraft:stray", StrayMeta::new), + Map.entry("minecraft:strider", StriderMeta::new), + Map.entry("minecraft:tadpole", TadpoleMeta::new), + Map.entry("minecraft:egg", ThrownEggMeta::new), + Map.entry("minecraft:ender_pearl", ThrownEnderPearlMeta::new), + Map.entry("minecraft:experience_bottle", ThrownExperienceBottleMeta::new), + Map.entry("minecraft:potion", ThrownPotionMeta::new), + Map.entry("minecraft:trident", ThrownTridentMeta::new), + Map.entry("minecraft:trader_llama", TraderLlamaMeta::new), + Map.entry("minecraft:tropical_fish", TropicalFishMeta::new), + Map.entry("minecraft:turtle", TurtleMeta::new), + Map.entry("minecraft:vex", VexMeta::new), + Map.entry("minecraft:villager", VillagerMeta::new), + Map.entry("minecraft:vindicator", VindicatorMeta::new), + Map.entry("minecraft:wandering_trader", WanderingTraderMeta::new), + Map.entry("minecraft:warden", WardenMeta::new), + Map.entry("minecraft:wind_charge", WindChargeMeta::new), + Map.entry("minecraft:witch", WitchMeta::new), + Map.entry("minecraft:wither", WitherMeta::new), + Map.entry("minecraft:wither_skeleton", WitherSkeletonMeta::new), + Map.entry("minecraft:wither_skull", WitherSkullMeta::new), + Map.entry("minecraft:wolf", WolfMeta::new), + Map.entry("minecraft:zoglin", ZoglinMeta::new), + Map.entry("minecraft:zombie", ZombieMeta::new), + Map.entry("minecraft:zombie_horse", ZombieHorseMeta::new), + Map.entry("minecraft:zombie_villager", ZombieVillagerMeta::new), + Map.entry("minecraft:zombified_piglin", ZombifiedPiglinMeta::new), + Map.entry("minecraft:player", PlayerMeta::new), + Map.entry("minecraft:fishing_bobber", FishingHookMeta::new) ); } } diff --git a/src/main/java/net/minestom/server/entity/metadata/projectile/BreezeWindChargeMeta.java b/src/main/java/net/minestom/server/entity/metadata/projectile/BreezeWindChargeMeta.java new file mode 100644 index 000000000..943888c9f --- /dev/null +++ b/src/main/java/net/minestom/server/entity/metadata/projectile/BreezeWindChargeMeta.java @@ -0,0 +1,40 @@ +package net.minestom.server.entity.metadata.projectile; + +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.Metadata; +import net.minestom.server.entity.metadata.EntityMeta; +import net.minestom.server.entity.metadata.ObjectDataProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class BreezeWindChargeMeta extends EntityMeta implements ObjectDataProvider, ProjectileMeta { + public static final byte OFFSET = EntityMeta.MAX_OFFSET; + public static final byte MAX_OFFSET = OFFSET + 0; + + private Entity shooter; + + public BreezeWindChargeMeta(@NotNull Entity entity, @NotNull Metadata metadata) { + super(entity, metadata); + } + + @Override + @Nullable + public Entity getShooter() { + return shooter; + } + + @Override + public void setShooter(@Nullable Entity shooter) { + this.shooter = shooter; + } + + @Override + public int getObjectData() { + return this.shooter == null ? 0 : this.shooter.getEntityId(); + } + + @Override + public boolean requiresVelocityPacketAtSpawn() { + return true; + } +} diff --git a/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java b/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java index 1162e0307..6c63a2585 100644 --- a/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java +++ b/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java @@ -95,10 +95,10 @@ public class AnvilLoader implements IChunkLoader { } private @NotNull CompletableFuture<@Nullable Chunk> loadMCA(Instance instance, int chunkX, int chunkZ) throws IOException { - final RegionFile mcaFile = getMCAFile(instance, chunkX, chunkZ); + final RegionFile mcaFile = getMCAFile(chunkX, chunkZ); if (mcaFile == null) return CompletableFuture.completedFuture(null); - final CompoundBinaryTag chunkData = mcaFile.getChunk(chunkX, chunkZ); + final CompoundBinaryTag chunkData = mcaFile.readChunkData(chunkX, chunkZ); if (chunkData == null) return CompletableFuture.completedFuture(null); @@ -142,7 +142,7 @@ public class AnvilLoader implements IChunkLoader { return CompletableFuture.completedFuture(chunk); } - private @Nullable RegionFile getMCAFile(Instance instance, int chunkX, int chunkZ) { + private @Nullable RegionFile getMCAFile(int chunkX, int chunkZ) { final int regionX = ChunkUtils.toRegionCoordinate(chunkX); final int regionZ = ChunkUtils.toRegionCoordinate(chunkZ); return alreadyLoaded.computeIfAbsent(RegionFile.getFileName(regionX, regionZ), n -> { @@ -154,7 +154,7 @@ public class AnvilLoader implements IChunkLoader { try { Set previousVersion = perRegionLoadedChunks.put(new IntIntImmutablePair(regionX, regionZ), new HashSet<>()); assert previousVersion == null : "The AnvilLoader cache should not already have data for this region."; - return new RegionFile(regionPath, regionX, regionZ, instance.getDimensionType()); + return new RegionFile(regionPath); } catch (IOException e) { MinecraftServer.getExceptionManager().handleException(e); return null; @@ -322,49 +322,91 @@ public class AnvilLoader implements IChunkLoader { @Override public @NotNull CompletableFuture saveChunk(@NotNull Chunk chunk) { -// final int chunkX = chunk.getChunkX(); -// final int chunkZ = chunk.getChunkZ(); -// RegionFile mcaFile; -// synchronized (alreadyLoaded) { -// mcaFile = getMCAFile(chunk.instance, chunkX, chunkZ); -// if (mcaFile == null) { -// final int regionX = CoordinatesKt.chunkToRegion(chunkX); -// final int regionZ = CoordinatesKt.chunkToRegion(chunkZ); -// final String n = RegionFile.Companion.createFileName(regionX, regionZ); -// File regionFile = new File(regionPath.toFile(), n); -// try { -// if (!regionFile.exists()) { -// if (!regionFile.getParentFile().exists()) { -// regionFile.getParentFile().mkdirs(); -// } -// regionFile.createNewFile(); -// } -// mcaFile = new RegionFile(new RandomAccessFile(regionFile, "rw"), regionX, regionZ); -// alreadyLoaded.put(n, mcaFile); -// } catch (AnvilException | IOException e) { -// LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); -// MinecraftServer.getExceptionManager().handleException(e); -// return AsyncUtils.VOID_FUTURE; -// } -// } -// } -// ChunkWriter writer = new ChunkWriter(SupportedVersion.Companion.getLatest()); -// save(chunk, writer); -// try { -// LOGGER.debug("Attempt saving at {} {}", chunk.getChunkX(), chunk.getChunkZ()); -// mcaFile.writeColumnData(writer.toNBT(), chunk.getChunkX(), chunk.getChunkZ()); -// } catch (IOException e) { -// LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); -// MinecraftServer.getExceptionManager().handleException(e); -// return AsyncUtils.VOID_FUTURE; -// } + final int chunkX = chunk.getChunkX(); + final int chunkZ = chunk.getChunkZ(); + + // Find the region file or create an empty one if missing + RegionFile mcaFile = getMCAFile(chunkX, chunkZ); + if (mcaFile == null) { + final int regionX = ChunkUtils.toRegionCoordinate(chunkX); + final int regionZ = ChunkUtils.toRegionCoordinate(chunkZ); + final String regionFileName = RegionFile.getFileName(regionX, regionZ); + try { + Path regionFile = regionPath.resolve(regionFileName); + if (!Files.exists(regionFile)) { + Files.createDirectories(regionFile.getParent()); + Files.createFile(regionFile); + } + + mcaFile = new RegionFile(regionFile); + alreadyLoaded.put(regionFileName, mcaFile); + } catch (IOException e) { + LOGGER.error("Failed to create region file for " + chunkX + ", " + chunkZ, e); + MinecraftServer.getExceptionManager().handleException(e); + return AsyncUtils.VOID_FUTURE; + } + } + + try { + final CompoundBinaryTag.Builder chunkData = CompoundBinaryTag.builder(); + + chunkData.putInt("DataVersion", MinecraftServer.DATA_VERSION); + chunkData.putInt("xPos", chunkX); + chunkData.putInt("zPos", chunkZ); + chunkData.putInt("yPos", chunk.getMinSection()); + chunkData.putString("status", "minecraft:full"); + chunkData.putLong("LastUpdate", chunk.getInstance().getWorldAge()); + + saveSectionData(chunk, chunkData); + + LOGGER.debug("Attempt saving at {} {}", chunk.getChunkX(), chunk.getChunkZ()); + mcaFile.writeChunkData(chunkX, chunkZ, chunkData.build()); + } catch (IOException e) { + LOGGER.error("Failed to save chunk " + chunkX + ", " + chunkZ, e); + MinecraftServer.getExceptionManager().handleException(e); + } return AsyncUtils.VOID_FUTURE; } // private BlockState getBlockState(final Block block) { // return blockStateId2ObjectCacheTLS.get().computeIfAbsent(block.stateId(), _unused -> new BlockState(block.name(), block.properties())); // } + + private void saveSectionData(@NotNull Chunk chunk, @NotNull CompoundBinaryTag.Builder chunkData) { + + + final int minY = chunk.getMinSection() * Chunk.CHUNK_SECTION_SIZE; + final int maxY = chunk.getMaxSection() * Chunk.CHUNK_SECTION_SIZE - 1; + for (int sectionY = chunk.getMinSection(); sectionY < chunk.getMaxSection(); sectionY++) { + final Section section = chunk.getSection(sectionY); + + final CompoundBinaryTag.Builder sectionData = CompoundBinaryTag.builder(); + sectionData.putInt("Y", sectionY); + + // Lighting + byte[] skyLight = section.skyLight().array(); + if (skyLight != null && skyLight.length > 0) + sectionData.putByteArray("SkyLight", skyLight); + byte[] blockLight = section.blockLight().array(); + if (blockLight != null && blockLight.length > 0) + sectionData.putByteArray("BlockLight", blockLight); + + // Build block & biome palettes + //todo +// int[] blockStates = new int[Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SECTION_SIZE]; +// int[] biomes = new int[64]; // +// for (int localY = 0; localY < Chunk.CHUNK_SECTION_SIZE; localY++) { +// for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) { +// for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) { +// +// } +// } +// } + throw new UnsupportedOperationException("Not implemented"); + } + + } // private void save(Chunk chunk, ChunkWriter chunkWriter) { // final int minY = chunk.getMinSection() * Chunk.CHUNK_SECTION_SIZE; // final int maxY = chunk.getMaxSection() * Chunk.CHUNK_SECTION_SIZE - 1; @@ -376,14 +418,7 @@ public class AnvilLoader implements IChunkLoader { // int[] palettedBiomes = new int[ChunkSection.Companion.getBiomeArraySize()]; // int[] palettedBlockStates = new int[Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SECTION_SIZE * Chunk.CHUNK_SIZE_Z]; // for (int sectionY = chunk.getMinSection(); sectionY < chunk.getMaxSection(); sectionY++) { -// ChunkSectionWriter sectionWriter = new ChunkSectionWriter(SupportedVersion.Companion.getLatest(), (byte) sectionY); -// -// Section section = chunk.getSection(sectionY); -// sectionWriter.setSkyLights(section.skyLight().array()); -// sectionWriter.setBlockLights(section.blockLight().array()); -// -// BiomePalette biomePalette = new BiomePalette(); -// BlockPalette blockPalette = new BlockPalette(); + // for (int sectionLocalY = 0; sectionLocalY < Chunk.CHUNK_SECTION_SIZE; sectionLocalY++) { // for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) { // for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) { @@ -437,38 +472,41 @@ public class AnvilLoader implements IChunkLoader { // chunkWriter.setSectionsData(NBT.List(NBTType.TAG_Compound, sectionData)); // chunkWriter.setBlockEntityData(NBT.List(NBTType.TAG_Compound, blockEntities)); // } -// -// /** -// * Unload a given chunk. Also unloads a region when no chunk from that region is loaded. -// * -// * @param chunk the chunk to unload -// */ -// @Override -// public void unloadChunk(Chunk chunk) { -// final int regionX = CoordinatesKt.chunkToRegion(chunk.chunkX); -// final int regionZ = CoordinatesKt.chunkToRegion(chunk.chunkZ); -// -// final IntIntImmutablePair regionKey = new IntIntImmutablePair(regionX, regionZ); -// synchronized (perRegionLoadedChunks) { -// Set chunks = perRegionLoadedChunks.get(regionKey); -// if (chunks != null) { // if null, trying to unload a chunk from a region that was not created by the AnvilLoader -// // don't check return value, trying to unload a chunk not created by the AnvilLoader is valid -// chunks.remove(new IntIntImmutablePair(chunk.chunkX, chunk.chunkZ)); -// -// if (chunks.isEmpty()) { -// perRegionLoadedChunks.remove(regionKey); -// RegionFile regionFile = alreadyLoaded.remove(RegionFile.Companion.createFileName(regionX, regionZ)); -// if (regionFile != null) { -// try { -// regionFile.close(); -// } catch (IOException e) { -// MinecraftServer.getExceptionManager().handleException(e); -// } -// } -// } -// } -// } -// } + + /** + * Unload a given chunk. Also unloads a region when no chunk from that region is loaded. + * + * @param chunk the chunk to unload + */ + @Override + public void unloadChunk(Chunk chunk) { + final int regionX = ChunkUtils.toRegionCoordinate(chunk.getChunkX()); + final int regionZ = ChunkUtils.toRegionCoordinate(chunk.getChunkZ()); + final IntIntImmutablePair regionKey = new IntIntImmutablePair(regionX, regionZ); + + perRegionLoadedChunksLock.lock(); + try { + Set chunks = perRegionLoadedChunks.get(regionKey); + if (chunks != null) { // if null, trying to unload a chunk from a region that was not created by the AnvilLoader + // don't check return value, trying to unload a chunk not created by the AnvilLoader is valid + chunks.remove(new IntIntImmutablePair(chunk.getChunkX(), chunk.getChunkZ())); + + if (chunks.isEmpty()) { + perRegionLoadedChunks.remove(regionKey); + RegionFile regionFile = alreadyLoaded.remove(RegionFile.getFileName(regionX, regionZ)); + if (regionFile != null) { + try { + regionFile.close(); + } catch (IOException e) { + MinecraftServer.getExceptionManager().handleException(e); + } + } + } + } + } finally { + perRegionLoadedChunksLock.unlock(); + } + } @Override public boolean supportsParallelLoading() { diff --git a/src/main/java/net/minestom/server/instance/anvil/RegionFile.java b/src/main/java/net/minestom/server/instance/anvil/RegionFile.java index be1cab63d..860dbf748 100644 --- a/src/main/java/net/minestom/server/instance/anvil/RegionFile.java +++ b/src/main/java/net/minestom/server/instance/anvil/RegionFile.java @@ -5,14 +5,16 @@ import it.unimi.dsi.fastutil.booleans.BooleanList; import net.kyori.adventure.nbt.BinaryTagIO; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.utils.chunk.ChunkUtils; -import net.minestom.server.world.DimensionType; +import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.file.Path; +import java.util.Map; import java.util.concurrent.locks.ReentrantLock; /** @@ -27,8 +29,12 @@ final class RegionFile implements AutoCloseable { private static final int SECTOR_SIZE = 4096; private static final int SECTOR_1MB = 1024 * 1024 / SECTOR_SIZE; private static final int HEADER_LENGTH = MAX_ENTRY_COUNT * 2 * 4; // 2 4-byte fields per entry + private static final int CHUNK_HEADER_LENGTH = 4 + 1; // Length + Compression type (todo non constant to support custom compression) + + private static final int COMPRESSION_ZLIB = 2; private static final BinaryTagIO.Reader TAG_READER = BinaryTagIO.unlimitedReader(); + private static final BinaryTagIO.Writer TAG_WRITER = BinaryTagIO.writer(); public static @NotNull String getFileName(int regionX, int regionZ) { return "r." + regionX + "." + regionZ + ".mca"; @@ -41,7 +47,7 @@ final class RegionFile implements AutoCloseable { private final int[] timestamps = new int[MAX_ENTRY_COUNT]; private final BooleanList freeSectors = new BooleanArrayList(2); - public RegionFile(@NotNull Path path, int regionX, int regionZ, @NotNull DimensionType dimensionType) throws IOException { + public RegionFile(@NotNull Path path) throws IOException { this.file = new RandomAccessFile(path.toFile(), "rw"); readHeader(); @@ -56,7 +62,7 @@ final class RegionFile implements AutoCloseable { } } - public @Nullable CompoundBinaryTag getChunk(int chunkX, int chunkZ) throws IOException { + public @Nullable CompoundBinaryTag readChunkData(int chunkX, int chunkZ) throws IOException { lock.lock(); try { if (!hasChunkData(chunkX, chunkZ)) return null; @@ -67,7 +73,7 @@ final class RegionFile implements AutoCloseable { int compressionType = file.readByte(); BinaryTagIO.Compression compression = switch (compressionType) { case 1 -> BinaryTagIO.Compression.GZIP; - case 2 -> BinaryTagIO.Compression.ZLIB; + case COMPRESSION_ZLIB -> BinaryTagIO.Compression.ZLIB; case 3 -> BinaryTagIO.Compression.NONE; default -> throw new IOException("Unsupported compression type: " + compressionType); }; @@ -83,12 +89,56 @@ final class RegionFile implements AutoCloseable { } } + public void writeChunkData(int chunkX, int chunkZ, @NotNull CompoundBinaryTag data) throws IOException { + // Write the data (compressed) + ByteArrayOutputStream out = new ByteArrayOutputStream(); + TAG_WRITER.writeNamed(Map.entry("", data), out, BinaryTagIO.Compression.ZLIB); + byte[] dataBytes = out.toByteArray(); + int chunkLength = CHUNK_HEADER_LENGTH + dataBytes.length; + + int sectorCount = (int) Math.ceil(chunkLength / (double) SECTOR_SIZE); + Check.stateCondition(sectorCount >= SECTOR_1MB, "Chunk data is too large to fit in a region file"); + + lock.lock(); + try { + // We don't attempt to reuse the current allocation, just write it to a new position and free the old one. + int oldLocation = getChunkIndex(chunkX, chunkZ); + + // Find a new location + int firstSector = findFreeSectors(sectorCount); + if (firstSector == -1) { + firstSector = allocSectors(sectorCount); + } + int newLocation = (firstSector << 8) | sectorCount; + + // Mark the sectors as used & free the old sectors + markLocation(oldLocation, true); + markLocation(newLocation, false); + + // Write the chunk data + file.seek((long) firstSector * SECTOR_SIZE); + file.writeInt(chunkLength); + file.writeByte(COMPRESSION_ZLIB); + file.write(dataBytes); + + // Update the header and write it + locations[oldLocation] = newLocation; + timestamps[oldLocation] = (int) (System.currentTimeMillis() / 1000); + writeHeader(); + } finally { + lock.unlock(); + } + } @Override - public void close() throws Exception { + public void close() throws IOException { file.close(); } + private int getChunkIndex(int chunkX, int chunkZ) { + return (ChunkUtils.toRegionLocal(chunkZ) << 5) | ChunkUtils.toRegionLocal(chunkX); + } + private void readHeader() throws IOException { file.seek(0); if (file.length() < HEADER_LENGTH) { @@ -105,13 +155,8 @@ final class RegionFile implements AutoCloseable { file.seek(0); for (int i = 0; i < MAX_ENTRY_COUNT; i++) { int location = locations[i] = file.readInt(); - int offset = location >> 8; - int length = location & 0xFF; - - if (location != 0 && offset + length <= freeSectors.size()) { - for (int sectorIndex = 0; sectorIndex < length; sectorIndex++) { - freeSectors.set(sectorIndex + offset, false); - } + if (location != 0) { + markLocation(location, false); } } @@ -121,7 +166,49 @@ final class RegionFile implements AutoCloseable { } } - private int getChunkIndex(int chunkX, int chunkZ) { - return (ChunkUtils.toRegionLocal(chunkZ) << 5) | ChunkUtils.toRegionLocal(chunkX); + private void writeHeader() throws IOException { + file.seek(0); + for (int location : locations) { + file.writeInt(location); + } + for (int timestamp : timestamps) { + file.writeInt(timestamp); + } + } + + private int findFreeSectors(int length) { + for (int start = 0; start < freeSectors.size() - length; start++) { + boolean found = true; + for (int i = 0; i < length; i++) { + if (!freeSectors.getBoolean(start++)) { + found = false; + break; + } + } + if (found) return start; + } + return -1; + } + + private int allocSectors(int count) throws IOException { + var eof = file.length(); + file.seek(eof); + + byte[] emptySector = new byte[SECTOR_SIZE]; + for (int i = 0; i < count; i++) { + freeSectors.add(true); + file.write(emptySector); + } + + return (int) (eof / SECTOR_SIZE); + } + + private void markLocation(int location, boolean free) { + int sectorCount = locations[location] & 0xFF; + int sectorStart = locations[location] >> 8; + Check.stateCondition(sectorStart + sectorCount > freeSectors.size(), "Invalid sector count"); + for (int i = sectorStart; i < sectorStart + sectorCount; i++) { + freeSectors.set(i, free); + } } } diff --git a/src/main/java/net/minestom/server/instance/block/predicate/PropertiesPredicate.java b/src/main/java/net/minestom/server/instance/block/predicate/PropertiesPredicate.java index 3c3716910..ed5ea7d05 100644 --- a/src/main/java/net/minestom/server/instance/block/predicate/PropertiesPredicate.java +++ b/src/main/java/net/minestom/server/instance/block/predicate/PropertiesPredicate.java @@ -50,6 +50,10 @@ public record PropertiesPredicate(@NotNull Map propertie } ); + public static @NotNull PropertiesPredicate exact(@NotNull String key, @NotNull String value) { + return new PropertiesPredicate(Map.of(key, new ValuePredicate.Exact(value))); + } + public PropertiesPredicate { properties = Map.copyOf(properties); } diff --git a/src/main/java/net/minestom/server/item/ItemComponent.java b/src/main/java/net/minestom/server/item/ItemComponent.java index 78bf92658..08cd88ea9 100644 --- a/src/main/java/net/minestom/server/item/ItemComponent.java +++ b/src/main/java/net/minestom/server/item/ItemComponent.java @@ -12,6 +12,7 @@ import net.minestom.server.utils.nbt.BinaryTagSerializer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.List; import static net.minestom.server.item.ItemComponentImpl.declare; @@ -95,4 +96,8 @@ public sealed interface ItemComponent extends StaticProtocolObject permits It static @Nullable ItemComponent fromId(int id) { return ItemComponentImpl.IDS.get(id); } + + static @NotNull Collection> values() { + return ItemComponentImpl.NAMESPACES.values(); + } } diff --git a/src/main/java/net/minestom/server/item/ItemStackImpl.java b/src/main/java/net/minestom/server/item/ItemStackImpl.java index 413178804..c18901aa8 100644 --- a/src/main/java/net/minestom/server/item/ItemStackImpl.java +++ b/src/main/java/net/minestom/server/item/ItemStackImpl.java @@ -120,11 +120,14 @@ record ItemStackImpl(Material material, int amount, ItemComponentPatch component } private static @NotNull CompoundBinaryTag toCompound(@NotNull ItemStack itemStack) { - return CompoundBinaryTag.builder() - .putString("id", itemStack.material().name()) - .putInt("count", itemStack.amount()) - .put("components", ItemComponentPatch.NBT_TYPE.write(((ItemStackImpl) itemStack).components)) - .build(); + CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder(); + tag.putString("id", itemStack.material().name()); + tag.putInt("count", itemStack.amount()); + + CompoundBinaryTag components = (CompoundBinaryTag) ItemComponentPatch.NBT_TYPE.write(((ItemStackImpl) itemStack).components); + if (components.size() > 0) tag.put("components", components); + + return tag.build(); } static final class Builder implements ItemStack.Builder { diff --git a/src/main/java/net/minestom/server/item/component/WrittenBookContent.java b/src/main/java/net/minestom/server/item/component/WrittenBookContent.java index 5ab694a26..ce4d55bd2 100644 --- a/src/main/java/net/minestom/server/item/component/WrittenBookContent.java +++ b/src/main/java/net/minestom/server/item/component/WrittenBookContent.java @@ -66,6 +66,10 @@ public record WrittenBookContent(@NotNull List> pages, @ pages = List.copyOf(pages); } + public WrittenBookContent(@NotNull List pages, @NotNull String title, @NotNull String author) { + this(pages, title, author, 0, true); + } + public WrittenBookContent(@NotNull List pages, @NotNull String title, @NotNull String author, int generation, boolean resolved) { this(pages.stream().map(page -> new FilteredText<>(page, null)).toList(), new FilteredText<>(title, null), author, generation, resolved); } diff --git a/src/test/java/net/minestom/server/command/ArgumentTypeTest.java b/src/test/java/net/minestom/server/command/ArgumentTypeTest.java index d014694f3..5d5dc318f 100644 --- a/src/test/java/net/minestom/server/command/ArgumentTypeTest.java +++ b/src/test/java/net/minestom/server/command/ArgumentTypeTest.java @@ -1,10 +1,15 @@ package net.minestom.server.command; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.arguments.Argument; import net.minestom.server.command.builder.arguments.ArgumentEnum; import net.minestom.server.command.builder.arguments.ArgumentType; @@ -21,7 +26,6 @@ import net.minestom.server.utils.location.RelativeVec; import net.minestom.server.utils.math.FloatRange; import net.minestom.server.utils.math.IntRange; import net.minestom.server.utils.time.TimeUnit; -import org.jglrxavpok.hephaistos.nbt.NBT; import org.junit.jupiter.api.Test; import java.time.Duration; @@ -32,11 +36,15 @@ import static org.junit.jupiter.api.Assertions.*; public class ArgumentTypeTest { + static { + MinecraftServer.init(); + } + @Test public void testArgumentEnchantment() { var arg = ArgumentType.Enchantment("enchantment"); assertInvalidArg(arg, "minecraft:invalid_enchantment"); - assertArg(arg, Enchantment.SWEEPING, Enchantment.SWEEPING.name()); + assertArg(arg, Enchantment.SWEEPING_EDGE, Enchantment.SWEEPING_EDGE.name()); assertArg(arg, Enchantment.MENDING, Enchantment.MENDING.name()); } @@ -169,11 +177,10 @@ public class ArgumentTypeTest { @Test public void testArgumentNbtCompoundTag() { var arg = ArgumentType.NbtCompound("nbt_compound"); - assertArg(arg, NBT.Compound(mut -> mut.put("long_array", NBT.LongArray(12, 49, 119))), "{\"long_array\":[L;12L,49L,119L]}"); - assertArg(arg, NBT.Compound(mut -> mut.put("nested", NBT.Compound(mut2 -> - mut2.put("complex", NBT.IntArray(124, 999, 33256)) - )) - ), "{\"nested\": {\"complex\": [I;124,999,33256]}}"); + assertArg(arg, CompoundBinaryTag.builder().putLongArray("long_array", new long[]{12, 49, 119}).build(), + "{\"long_array\":[L;12L,49L,119L]}"); + assertArg(arg, CompoundBinaryTag.builder().put("nested", CompoundBinaryTag.builder().putIntArray("complex", new int[]{124, 999, 33256}).build()).build(), + "{\"nested\": {\"complex\": [I;124,999,33256]}}"); assertInvalidArg(arg, "string"); assertInvalidArg(arg, "\"string\""); @@ -184,11 +191,12 @@ public class ArgumentTypeTest { @Test public void testArgumentNbtTag() { var arg = ArgumentType.NBT("nbt"); - assertArg(arg, NBT.String("string"), "string"); - assertArg(arg, NBT.String("string"), "\"string\""); - assertArg(arg, NBT.Int(44), "44"); - assertArg(arg, NBT.IntArray(11, 49, 33), "[I;11,49,33]"); - assertArg(arg, NBT.Compound(mut -> mut.put("long_array", NBT.LongArray(12, 49, 119))), "{\"long_array\":[L;12L,49L,119L]}"); + assertArg(arg, StringBinaryTag.stringBinaryTag("string"), "string"); + assertArg(arg, StringBinaryTag.stringBinaryTag("string"), "\"string\""); + assertArg(arg, IntBinaryTag.intBinaryTag(44), "44"); + assertArg(arg, IntArrayBinaryTag.intArrayBinaryTag(11, 49, 33), "[I;11,49,33]"); + assertArg(arg, CompoundBinaryTag.builder().putLongArray("long_array", new long[]{12, 49, 119}).build(), + "{\"long_array\":[L;12L,49L,119L]}"); assertInvalidArg(arg, "\"unbalanced string"); assertInvalidArg(arg, "dd}"); diff --git a/src/test/java/net/minestom/server/command/CommandSenderTest.java b/src/test/java/net/minestom/server/command/CommandSenderTest.java index fe2b5186f..7cbabb81a 100644 --- a/src/test/java/net/minestom/server/command/CommandSenderTest.java +++ b/src/test/java/net/minestom/server/command/CommandSenderTest.java @@ -2,19 +2,20 @@ package net.minestom.server.command; import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.permission.Permission; import net.minestom.server.tag.TagHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; import java.util.HashSet; import java.util.Set; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; public class CommandSenderTest { @@ -23,7 +24,7 @@ public class CommandSenderTest { CommandSender sender = new SenderTest(); - Permission permission = new Permission("permission.test", new NBTCompound()); + Permission permission = new Permission("permission.test", CompoundBinaryTag.empty()); assertEquals(sender.getAllPermissions(), Set.of()); diff --git a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java index ce434dd34..fdd5a2554 100644 --- a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java @@ -42,11 +42,14 @@ public class EntityMetaIntegrationTest { assertEquals(2, packets.size()); validMetaDataPackets(packets, player.getEntityId(), entry -> { final Object content = entry.value(); - switch (entry.type()) { - case Metadata.TYPE_BYTE -> assertEquals((byte) 34, content); - case Metadata.TYPE_BOOLEAN -> assertTrue((boolean) content); - case Metadata.TYPE_POSE -> assertEquals(Entity.Pose.SNEAKING, content); - default -> Assertions.fail("Invalid MetaData entry"); + if (entry.type() == Metadata.TYPE_BYTE) { + assertEquals((byte) 34, content); + } else if (entry.type() == Metadata.TYPE_BOOLEAN) { + assertTrue((boolean) content); + } else if (entry.type() == Metadata.TYPE_POSE) { + assertEquals(Entity.Pose.SNEAKING, content); + } else { + Assertions.fail("Invalid MetaData entry"); } }); @@ -58,11 +61,14 @@ public class EntityMetaIntegrationTest { packets = incomingPackets.collect(); validMetaDataPackets(packets, player.getEntityId(), entry -> { final Object content = entry.value(); - switch (entry.type()) { - case Metadata.TYPE_BYTE -> assertTrue(content.equals((byte) 2) || content.equals((byte) 0)); - case Metadata.TYPE_BOOLEAN -> assertFalse((boolean) content); - case Metadata.TYPE_POSE -> assertEquals(Entity.Pose.STANDING, content); - default -> Assertions.fail("Invalid MetaData entry"); + if (entry.type() == Metadata.TYPE_BYTE) { + assertTrue(content.equals((byte) 2) || content.equals((byte) 0)); + } else if (entry.type() == Metadata.TYPE_BOOLEAN) { + assertFalse((boolean) content); + } else if (entry.type() == Metadata.TYPE_POSE) { + assertEquals(Entity.Pose.STANDING, content); + } else { + Assertions.fail("Invalid MetaData entry"); } }); // 4 changes, for two viewers diff --git a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java index da08fe40c..b0380f0c1 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java @@ -5,8 +5,13 @@ import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockFace; +import net.minestom.server.instance.block.predicate.BlockPredicate; +import net.minestom.server.instance.block.predicate.BlockTypeFilter; +import net.minestom.server.instance.block.predicate.PropertiesPredicate; +import net.minestom.server.item.ItemComponent; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; +import net.minestom.server.item.component.BlockPredicates; import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket; import net.minestom.testing.Env; import net.minestom.testing.EnvTest; @@ -23,7 +28,7 @@ public class PlayerBlockPlacementIntegrationTest { @ParameterizedTest @MethodSource("placeBlockFromAdventureModeParams") - public void placeBlockFromAdventureMode(Block baseBlock, Block canPlaceOn, Env env) { + public void placeBlockFromAdventureMode(Block baseBlock, BlockPredicates canPlaceOn, Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -31,7 +36,7 @@ public class PlayerBlockPlacementIntegrationTest { instance.setBlock(2, 41, 0, baseBlock); player.setGameMode(GameMode.ADVENTURE); - player.setItemInMainHand(ItemStack.builder(Material.WHITE_WOOL).meta(m -> m.canPlaceOn(canPlaceOn)).build()); + player.setItemInMainHand(ItemStack.builder(Material.WHITE_WOOL).set(ItemComponent.CAN_PLACE_ON, canPlaceOn).build()); var packet = new ClientPlayerBlockPlacementPacket( Player.Hand.MAIN, new Pos(2, 41, 0), BlockFace.WEST, @@ -42,16 +47,16 @@ public class PlayerBlockPlacementIntegrationTest { player.interpretPacketQueue(); var placedBlock = instance.getBlock(1, 41, 0); - assertEquals("minecraft:white_wool", placedBlock.name()); } private static Stream placeBlockFromAdventureModeParams() { return Stream.of( - Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"), Block.ACACIA_STAIRS), - Arguments.of(Block.ACACIA_STAIRS, Block.ACACIA_STAIRS.withProperty("facing", "south")), - Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"), Block.ACACIA_STAIRS.withProperty("facing", "south")), - Arguments.of(Block.AMETHYST_BLOCK, Block.AMETHYST_BLOCK)); + Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"), new BlockPredicates(new BlockPredicate(new BlockTypeFilter.Blocks(Block.ACACIA_STAIRS)))), + Arguments.of(Block.ACACIA_STAIRS, new BlockPredicates(new BlockPredicate(new BlockTypeFilter.Blocks(Block.ACACIA_STAIRS), PropertiesPredicate.exact("facing", "south"), null))), + Arguments.of(Block.ACACIA_STAIRS.withProperty("facing", "south"), new BlockPredicates(new BlockPredicate(new BlockTypeFilter.Blocks(Block.ACACIA_STAIRS), PropertiesPredicate.exact("facing", "south"), null))), + Arguments.of(Block.AMETHYST_BLOCK, new BlockPredicates(new BlockPredicate(new BlockTypeFilter.Blocks(Block.AMETHYST_BLOCK)))) + ); } } diff --git a/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java b/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java index 400271ef5..712780344 100644 --- a/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java +++ b/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java @@ -1,18 +1,16 @@ package net.minestom.server.instance; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.tag.Tag; import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.block.BlockUtils; import org.jetbrains.annotations.NotNull; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; import java.util.Collection; import java.util.List; -import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -23,9 +21,9 @@ public class BlockClientNbtTest { public void basic() { assertNull(BlockUtils.extractClientNbt(Block.STONE)); assertNull(BlockUtils.extractClientNbt(Block.GRASS_BLOCK)); - assertEquals(NBTCompound.EMPTY, BlockUtils.extractClientNbt(Block.CHEST)); + assertEquals(CompoundBinaryTag.empty(), BlockUtils.extractClientNbt(Block.CHEST)); - var nbt = NBT.Compound(Map.of("test", NBT.String("test"))); + var nbt = CompoundBinaryTag.builder().putString("test", "test").build(); assertEquals(nbt, BlockUtils.extractClientNbt(Block.CHEST.withNbt(nbt))); } @@ -43,11 +41,11 @@ public class BlockClientNbtTest { } }; - var nbt = NBT.Compound(Map.of("test", NBT.String("test"))); + var nbt = CompoundBinaryTag.builder().putString("test", "test").build(); assertNull(BlockUtils.extractClientNbt(Block.STONE.withNbt(nbt).withHandler(handler))); assertEquals(nbt, BlockUtils.extractClientNbt(Block.CHEST.withNbt(nbt).withHandler(handler))); assertEquals(nbt, BlockUtils.extractClientNbt(Block.CHEST - .withNbt(NBT.Compound(Map.of("test", NBT.String("test"), "test2", NBT.String("test")))) + .withNbt(CompoundBinaryTag.builder().putString("test", "test").putString("test2", "test2").build()) .withHandler(handler))); } } diff --git a/src/test/java/net/minestom/server/instance/BlockTest.java b/src/test/java/net/minestom/server/instance/BlockTest.java index 1f6468b1d..eadc2e821 100644 --- a/src/test/java/net/minestom/server/instance/BlockTest.java +++ b/src/test/java/net/minestom/server/instance/BlockTest.java @@ -1,11 +1,10 @@ package net.minestom.server.instance; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Vec; import net.minestom.server.instance.block.Block; import net.minestom.server.tag.Tag; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; import java.util.Map; @@ -21,7 +20,7 @@ public class BlockTest { assertFalse(block.hasNbt()); assertNull(block.nbt()); - var nbt = new NBTCompound(Map.of("key", NBT.Int(5))); + var nbt = CompoundBinaryTag.builder().putInt("key", 5).build(); block = block.withNbt(nbt); assertTrue(block.hasNbt()); assertEquals(block.nbt(), nbt); @@ -61,7 +60,7 @@ public class BlockTest { @Test public void testEquality() { - var nbt = new NBTCompound(Map.of("key", NBT.Int(5))); + var nbt = CompoundBinaryTag.builder().putInt("key", 5).build(); Block b1 = Block.CHEST; Block b2 = Block.CHEST; assertEquals(b1.withNbt(nbt), b2.withNbt(nbt)); diff --git a/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java b/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java index e2ddf7d46..280fd4871 100644 --- a/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java @@ -1,14 +1,13 @@ package net.minestom.server.instance; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; import net.minestom.testing.EnvTest; -import net.minestom.server.instance.block.Block; -import org.jglrxavpok.hephaistos.nbt.NBT; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -21,7 +20,7 @@ public class GeneratorIntegrationTest { @ValueSource(booleans = {false, true}) public void loader(boolean data, Env env) { var manager = env.process().instance(); - var block = data ? Block.STONE.withNbt(NBT.Compound(Map.of("key", NBT.String("value")))) : Block.STONE; + var block = data ? Block.STONE.withNbt(CompoundBinaryTag.builder().putString("key", "value").build()) : Block.STONE; var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> unit.modifier().fill(block)); instance.loadChunk(0, 0).join(); diff --git a/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java index 32e9b8703..1c73062d6 100644 --- a/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java @@ -1,7 +1,7 @@ package net.minestom.server.instance; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.TagStringIOExt; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.instance.block.Block; @@ -10,12 +10,11 @@ import net.minestom.server.network.packet.server.play.BlockChangePacket; import net.minestom.server.network.packet.server.play.BlockEntityDataPacket; import net.minestom.server.tag.Tag; import net.minestom.server.utils.NamespaceID; +import net.minestom.testing.Env; +import net.minestom.testing.EnvTest; import org.jetbrains.annotations.NotNull; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import org.jglrxavpok.hephaistos.parser.SNBTParser; import org.junit.jupiter.api.Test; -import java.io.StringReader; import java.util.Collection; import java.util.List; @@ -72,10 +71,10 @@ public class InstanceBlockPacketIntegrationTest { assertEquals(Block.AIR, instance.getBlock(blockPoint)); final Block block; - final NBTCompound data; + final CompoundBinaryTag data; try { - data = (NBTCompound) new SNBTParser(new StringReader("{\"GlowingText\":0B,\"Color\":\"black\",\"Text1\":\"{\\\"text\\\":\\\"wawsd\\\"}\"," + - "\"Text2\":\"{\\\"text\\\":\\\"\\\"}\",\"Text3\":\"{\\\"text\\\":\\\"\\\"}\",\"Text4\":\"{\\\"text\\\":\\\"\\\"}\"}")).parse(); + data = (CompoundBinaryTag) TagStringIOExt.readTag("{\"GlowingText\":0B,\"Color\":\"black\",\"Text1\":\"{\\\"text\\\":\\\"wawsd\\\"}\"," + + "\"Text2\":\"{\\\"text\\\":\\\"\\\"}\",\"Text3\":\"{\\\"text\\\":\\\"\\\"}\",\"Text4\":\"{\\\"text\\\":\\\"\\\"}\"}"); block = Block.OAK_SIGN.withHandler(signHandler).withNbt(data); } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java b/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java index da61ba340..f5c17f8ad 100644 --- a/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java @@ -6,23 +6,17 @@ import net.minestom.server.instance.InstanceContainer; import net.minestom.server.instance.LightingChunk; import net.minestom.server.instance.Section; import net.minestom.server.instance.anvil.AnvilLoader; -import net.minestom.server.instance.block.Block; import net.minestom.server.instance.palette.Palette; import net.minestom.testing.Env; import net.minestom.testing.EnvTest; -import org.jglrxavpok.hephaistos.mca.AnvilException; -import org.jglrxavpok.hephaistos.mca.BlockState; -import org.jglrxavpok.hephaistos.mca.ChunkSection; -import org.jglrxavpok.hephaistos.mca.RegionFile; import org.junit.jupiter.api.Test; -import java.io.File; import java.io.IOException; -import java.io.RandomAccessFile; import java.net.URISyntaxException; -import java.net.URL; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -32,7 +26,7 @@ public class LightParityIntegrationTest { private static final int REGION_SIZE = 3; @Test - public void test(Env env) throws URISyntaxException, IOException, AnvilException { + public void test(Env env) throws URISyntaxException, IOException { Map sections = retrieveSections(); // Generate our own light @@ -130,45 +124,48 @@ public class LightParityIntegrationTest { record SectionEntry(Palette blocks, byte[] sky, byte[] block) { } - private static Map retrieveSections() throws IOException, URISyntaxException, AnvilException { - URL defaultImage = LightParityIntegrationTest.class.getResource("/net/minestom/server/instance/lighting/region/r.0.0.mca"); - assert defaultImage != null; - File imageFile = new File(defaultImage.toURI()); - var regionFile = new RegionFile(new RandomAccessFile(imageFile, "rw"), - 0, 0, -64, 384); + private static Map retrieveSections() throws IOException, URISyntaxException { - Map sections = new HashMap<>(); - // Read from anvil - for (int x = 1; x < REGION_SIZE - 1; x++) { - for (int z = 1; z < REGION_SIZE - 1; z++) { - var chunk = regionFile.getChunk(x, z); - if (chunk == null) continue; - - for (int yLevel = chunk.getMinY(); yLevel <= chunk.getMaxY(); yLevel += 16) { - var section = chunk.getSection((byte) (yLevel/16)); - var palette = loadBlocks(section); - var sky = section.getSkyLights(); - var block = section.getBlockLights(); - sections.put(new Vec(x, section.getY(), z), new SectionEntry(palette, sky, block)); - } - } - } - return sections; + //todo +// URL defaultImage = LightParityIntegrationTest.class.getResource("/net/minestom/server/instance/lighting/region/r.0.0.mca"); +// assert defaultImage != null; +// File imageFile = new File(defaultImage.toURI()); +// var regionFile = new RegionFile(new RandomAccessFile(imageFile, "rw"), +// 0, 0, -64, 384); +// +// Map sections = new HashMap<>(); +// // Read from anvil +// for (int x = 1; x < REGION_SIZE - 1; x++) { +// for (int z = 1; z < REGION_SIZE - 1; z++) { +// var chunk = regionFile.getChunk(x, z); +// if (chunk == null) continue; +// +// for (int yLevel = chunk.getMinY(); yLevel <= chunk.getMaxY(); yLevel += 16) { +// var section = chunk.getSection((byte) (yLevel/16)); +// var palette = loadBlocks(section); +// var sky = section.getSkyLights(); +// var block = section.getBlockLights(); +// sections.put(new Vec(x, section.getY(), z), new SectionEntry(palette, sky, block)); +// } +// } +// } +// return sections; + throw new UnsupportedOperationException("todo"); } - private static Palette loadBlocks(ChunkSection section) throws AnvilException { - var palette = Palette.blocks(); - for (int x = 0; x < Chunk.CHUNK_SECTION_SIZE; x++) { - for (int z = 0; z < Chunk.CHUNK_SECTION_SIZE; z++) { - for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) { - final BlockState blockState = section.get(x, y, z); - String blockName = blockState.getName(); - Block block = Objects.requireNonNull(Block.fromNamespaceId(blockName), blockName) - .withProperties(blockState.getProperties()); - palette.set(x, y, z, block.stateId()); - } - } - } - return palette; - } +// private static Palette loadBlocks(ChunkSection section) throws AnvilException { +// var palette = Palette.blocks(); +// for (int x = 0; x < Chunk.CHUNK_SECTION_SIZE; x++) { +// for (int z = 0; z < Chunk.CHUNK_SECTION_SIZE; z++) { +// for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) { +// final BlockState blockState = section.get(x, y, z); +// String blockName = blockState.getName(); +// Block block = Objects.requireNonNull(Block.fromNamespaceId(blockName), blockName) +// .withProperties(blockState.getProperties()); +// palette.set(x, y, z, block.stateId()); +// } +// } +// } +// return palette; +// } } \ No newline at end of file diff --git a/src/test/java/net/minestom/server/item/ItemAirTest.java b/src/test/java/net/minestom/server/item/ItemAirTest.java index db3d855f8..1dd8a87d1 100644 --- a/src/test/java/net/minestom/server/item/ItemAirTest.java +++ b/src/test/java/net/minestom/server/item/ItemAirTest.java @@ -15,7 +15,7 @@ public class ItemAirTest { assertEquals(emptyItem, ItemStack.AIR, "AIR item can be compared to empty item"); assertSame(emptyItem, ItemStack.AIR, "AIR item identity can be compared to empty item"); - assertSame(ItemStack.AIR, ItemStack.fromNBT(Material.DIAMOND, null, 0)); + assertSame(ItemStack.AIR, ItemStack.of(Material.DIAMOND, 0)); assertSame(ItemStack.AIR, ItemStack.builder(Material.DIAMOND).amount(0).build()); } } diff --git a/src/test/java/net/minestom/server/item/ItemAttributeTest.java b/src/test/java/net/minestom/server/item/ItemAttributeTest.java deleted file mode 100644 index f7c8d82a3..000000000 --- a/src/test/java/net/minestom/server/item/ItemAttributeTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.minestom.server.item; - -import net.minestom.server.attribute.Attribute; -import net.minestom.server.entity.attribute.AttributeOperation; -import net.minestom.server.item.attribute.AttributeSlot; -import net.minestom.server.item.attribute.ItemAttribute; -import net.minestom.server.tag.TagHandler; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.UUID; - -import static net.minestom.testing.TestUtils.assertEqualsSNBT; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ItemAttributeTest { - - @Test - public void attribute() { - var attributes = List.of(new ItemAttribute( - new UUID(0, 0), "generic.attack_damage", Attribute.ATTACK_DAMAGE, - AttributeOperation.ADDITION, 2, AttributeSlot.MAINHAND)); - var item = ItemStack.builder(Material.STICK) - .meta(builder -> builder.attributes(attributes)) - .build(); - assertEquals(attributes, item.meta().getAttributes()); - } - - @Test - public void attributeReader() { - var attributes = List.of(new ItemAttribute( - new UUID(0, 0), "generic.attack_damage", Attribute.ATTACK_DAMAGE, - AttributeOperation.ADDITION, 2, AttributeSlot.MAINHAND)); - - TagHandler handler = TagHandler.newHandler(); - handler.setTag(ItemTags.ATTRIBUTES, attributes); - var item = ItemStack.fromNBT(Material.STICK, handler.asCompound()); - - assertEquals(attributes, item.meta().getAttributes()); - } - - @Test - public void attributeNbt() { - var item = ItemStack.builder(Material.STICK) - .meta(builder -> builder.attributes( - List.of(new ItemAttribute( - new UUID(0, 0), "generic.attack_damage", Attribute.ATTACK_DAMAGE, - AttributeOperation.ADDITION, 2, AttributeSlot.MAINHAND)))) - .build(); - assertEqualsSNBT(""" - {"AttributeModifiers":[ - { - "Amount":2.0D, - "UUID":[I;0,0,0,0], - "Slot":"mainhand", - "Operation":0, - "AttributeName":"generic.attack_damage", - "Name":"generic.attack_damage" - } - ]} - """, item.meta().toNBT()); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemBlockTest.java b/src/test/java/net/minestom/server/item/ItemBlockTest.java deleted file mode 100644 index 495e3de49..000000000 --- a/src/test/java/net/minestom/server/item/ItemBlockTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package net.minestom.server.item; - -import net.minestom.server.instance.block.Block; -import org.junit.jupiter.api.Test; - -import static net.minestom.testing.TestUtils.assertEqualsSNBT; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class ItemBlockTest { - - @Test - public void canPlace() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canPlaceOn(Block.STONE)) - .build(); - assertTrue(item.meta().getCanPlaceOn().contains(Block.STONE.name())); - assertTrue(item.meta().canPlaceOn(Block.STONE)); - } - - @Test - public void canPlaceNbt() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canPlaceOn(Block.STONE)) - .build(); - assertEqualsSNBT(""" - {"CanPlaceOn":["minecraft:stone"]} - """, item.meta().toNBT()); - } - - @Test - public void canPlaceMismatchProperties() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canPlaceOn(Block.SANDSTONE_STAIRS.withProperty("facing", "south"))) - .build(); - assertTrue(item.meta().getCanPlaceOn().contains(Block.SANDSTONE_STAIRS.name())); - assertTrue(item.meta().getCanPlaceOn().contains(Block.SANDSTONE_STAIRS.withProperty("facing", "south").name())); - assertTrue(item.meta().canPlaceOn(Block.SANDSTONE_STAIRS.withProperty("facing", "south"))); - } - - @Test - public void canDestroy() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canDestroy(Block.STONE)) - .build(); - assertTrue(item.meta().getCanDestroy().contains(Block.STONE.name())); - assertTrue(item.meta().canDestroy(Block.STONE)); - } - - @Test - public void canDestroyNbt() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canDestroy(Block.STONE)) - .build(); - assertEqualsSNBT(""" - {"CanDestroy":["minecraft:stone"]} - """, item.meta().toNBT()); - } - - @Test - public void canDestroyMismatchProperties() { - var item = ItemStack.builder(Material.STONE) - .meta(builder -> builder.canDestroy(Block.SANDSTONE_STAIRS.withProperty("facing", "south"))) - .build(); - assertTrue(item.meta().getCanDestroy().contains(Block.SANDSTONE_STAIRS.name())); - assertTrue(item.meta().getCanDestroy().contains(Block.SANDSTONE_STAIRS.withProperty("facing", "south").name())); - assertTrue(item.meta().canDestroy(Block.SANDSTONE_STAIRS.withProperty("facing", "south"))); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemDisplayTest.java b/src/test/java/net/minestom/server/item/ItemDisplayTest.java deleted file mode 100644 index 87700dc15..000000000 --- a/src/test/java/net/minestom/server/item/ItemDisplayTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.minestom.server.item; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import org.jglrxavpok.hephaistos.nbt.NBTString; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.*; - -public class ItemDisplayTest { - - @Test - public void lore() { - var item = ItemStack.of(Material.DIAMOND_SWORD); - assertEquals(List.of(), item.getLore()); - assertNull(item.meta().toNBT().get("display")); - - { - var lore = List.of(Component.text("Hello")); - item = item.withLore(lore); - assertEquals(lore, item.getLore()); - var loreNbt = item.meta().toNBT().getCompound("display").getList("Lore"); - assertNotNull(loreNbt); - assertEquals(1, loreNbt.getSize()); - assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); - } - - { - var lore = List.of(Component.text("Hello"), Component.text("World")); - item = item.withLore(lore); - assertEquals(lore, item.getLore()); - var loreNbt = item.meta().toNBT().getCompound("display").getList("Lore"); - assertNotNull(loreNbt); - assertEquals(2, loreNbt.getSize()); - assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); - } - - { - var lore = Stream.of("string test").map(Component::text).toList(); - item = item.withLore(lore); - assertEquals(lore, item.getLore()); - var loreNbt = item.meta().toNBT().getCompound("display").getList("Lore"); - assertNotNull(loreNbt); - assertEquals(1, loreNbt.getSize()); - assertEquals(lore, loreNbt.asListView().stream().map(line -> GsonComponentSerializer.gson().deserialize(line.getValue())).toList()); - } - - // Ensure that lore can be properly removed without residual (display compound) - item = item.withLore(List.of()); - assertNull(item.meta().toNBT().get("display")); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemEnchantTest.java b/src/test/java/net/minestom/server/item/ItemEnchantTest.java deleted file mode 100644 index db702681b..000000000 --- a/src/test/java/net/minestom/server/item/ItemEnchantTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.minestom.server.item; - -import net.minestom.server.item.enchant.Enchantment; -import org.junit.jupiter.api.Test; - -import java.util.Map; - -public class ItemEnchantTest { - - @Test - public void enchant() { - var item = ItemStack.of(Material.DIAMOND_SWORD); - var enchantments = item.meta().getEnchantmentMap(); - assertTrue(enchantments.isEmpty(), "items do not have enchantments by default"); - - item = item.withMeta(meta -> meta.enchantment(Enchantment.EFFICIENCY, (short) 10)); - enchantments = item.meta().getEnchantmentMap(); - assertEquals(enchantments.size(), 1); - assertEquals(enchantments.get(Enchantment.EFFICIENCY), (short) 10); - - item = item.withMeta(meta -> meta.enchantment(Enchantment.INFINITY, (short) 5)); - enchantments = item.meta().getEnchantmentMap(); - assertEquals(enchantments.size(), 2); - assertEquals(enchantments.get(Enchantment.EFFICIENCY), (short) 10); - assertEquals(enchantments.get(Enchantment.INFINITY), (short) 5); - - item = item.withMeta(meta -> meta.enchantments(Map.of())); - enchantments = item.meta().getEnchantmentMap(); - assertTrue(enchantments.isEmpty()); - - // Ensure that enchantments can still be modified after being emptied - item = item.withMeta(meta -> meta.enchantment(Enchantment.EFFICIENCY, (short) 10)); - enchantments = item.meta().getEnchantmentMap(); - assertEquals(enchantments.get(Enchantment.EFFICIENCY), (short) 10); - - item = item.withMeta(ItemMeta.Builder::clearEnchantment); - enchantments = item.meta().getEnchantmentMap(); - assertTrue(enchantments.isEmpty()); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemMetaTest.java b/src/test/java/net/minestom/server/item/ItemMetaTest.java deleted file mode 100644 index 30ee3dd2d..000000000 --- a/src/test/java/net/minestom/server/item/ItemMetaTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.minestom.server.item; - -import net.kyori.adventure.text.Component; -import net.minestom.server.entity.PlayerSkin; -import net.minestom.server.item.metadata.BundleMeta; -import net.minestom.server.item.metadata.PlayerHeadMeta; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.junit.jupiter.api.Test; - -import java.util.Map; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class ItemMetaTest { - @Test - public void defaultMeta() { - var item = ItemStack.builder(Material.BUNDLE).build(); - assertNotNull(item.meta()); - } - - @Test - public void fromNBT() { - var compound = NBT.Compound(Map.of("value", NBT.Int(5))); - var item = ItemStack.builder(Material.BUNDLE).meta(compound).build(); - assertEquals(compound, item.meta().toNBT()); - } - - @Test - public void bundle() { - var item = ItemStack.builder(Material.BUNDLE) - .meta(BundleMeta.class, bundleMetaBuilder -> { - bundleMetaBuilder.addItem(ItemStack.of(Material.DIAMOND, 5)); - bundleMetaBuilder.addItem(ItemStack.of(Material.RABBIT_FOOT, 5)); - }) - .build(); - assertEquals(2, item.meta(BundleMeta.class).getItems().size()); - } - - @Test - public void buildView() { - var uuid = UUID.randomUUID(); - var skin = new PlayerSkin("xx", "yy"); - var meta = new PlayerHeadMeta.Builder() - .skullOwner(uuid) - .playerSkin(skin) - .build(); - var item = ItemStack.builder(Material.PLAYER_HEAD) - .meta(meta) - .displayName(Component.text("Name")) - .build(); - PlayerHeadMeta view = item.meta(PlayerHeadMeta.class); - assertEquals(uuid, view.getSkullOwner()); - assertEquals(skin, view.getPlayerSkin()); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemMetaViewTest.java b/src/test/java/net/minestom/server/item/ItemMetaViewTest.java deleted file mode 100644 index 4c20e7b82..000000000 --- a/src/test/java/net/minestom/server/item/ItemMetaViewTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.minestom.server.item; - -import net.minestom.server.item.metadata.BundleMeta; -import net.minestom.server.tag.TagHandler; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - -public class ItemMetaViewTest { - @Test - public void viewType() { - assertEquals(BundleMeta.Builder.class, ItemMetaViewImpl.viewType(BundleMeta.class)); - } - - @Test - public void construct() { - assertInstanceOf(BundleMeta.Builder.class, ItemMetaViewImpl.constructBuilder(BundleMeta.class, TagHandler.newHandler())); - } -} diff --git a/src/test/java/net/minestom/server/item/ItemMetaWrittenBookTest.java b/src/test/java/net/minestom/server/item/ItemMetaWrittenBookTest.java deleted file mode 100644 index 0878637dd..000000000 --- a/src/test/java/net/minestom/server/item/ItemMetaWrittenBookTest.java +++ /dev/null @@ -1,209 +0,0 @@ -package net.minestom.server.item; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; -import net.minestom.server.item.metadata.WrittenBookMeta; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import org.jglrxavpok.hephaistos.parser.SNBTParser; -import org.junit.jupiter.api.Test; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.fail; - -public class ItemMetaWrittenBookTest { - @Test - public void testPages() { - ItemStack book = ItemStack.of(Material.WRITTEN_BOOK); - - Component pageA = Component.text("Page A"); - Component pageB = Component.text("Page B").append(Component.newline()).append(Component.text("Page B")); - Component pageC = Component.text("Page C"); - List originalPages = List.of(pageA, pageB, pageC); - - book = book.withMeta(WrittenBookMeta.class, meta -> meta.pages(List.of(pageA, pageB, pageC))); - - WrittenBookMeta meta = book.meta(WrittenBookMeta.class); - - assertEquals(originalPages, meta.getPages(), "written book output meta must equal original input meta"); - } - - @Test - public void testStyleComponents() { - List colors = List.of(NamedTextColor.BLUE, NamedTextColor.WHITE, NamedTextColor.DARK_BLUE); - List decorations = List.of(TextDecoration.UNDERLINED, TextDecoration.STRIKETHROUGH, TextDecoration.ITALIC); - List clicks = List.of( - ClickEvent.runCommand("/test"), - ClickEvent.openUrl("https://minestom.net"), - ClickEvent.changePage(2), - ClickEvent.openFile("/test"), - ClickEvent.copyToClipboard("clipboard text"), - ClickEvent.suggestCommand("/test")); - List> hovers = List.of( - HoverEvent.showText(Component.text("Hover text")), - ItemStack.of(Material.STONE).asHoverEvent(), - HoverEvent.showText(Component.text("Hover text")), - HoverEvent.showText(Component.text("Hover text"))); - - for (TextColor color : colors) { - for (TextDecoration decoration : decorations) { - for (ClickEvent click : clicks) { - for (HoverEvent hover : hovers) { - - Component pageA = Component.text("Page A").style(style -> { - style.color(color); - style.decoration(decoration, true); - style.clickEvent(click); - style.hoverEvent(hover); - }); - Component pageB = Component.text("test"); - - List originalPages = List.of(pageA, pageB); - - ItemStack book = ItemStack.of(Material.WRITTEN_BOOK) - .withMeta(WrittenBookMeta.class, meta -> meta.pages(pageA, pageB)); - - WrittenBookMeta meta = book.meta(WrittenBookMeta.class); - assertEquals(originalPages, meta.getPages(), "written book output meta must equal original input meta"); - } - } - } - } - } - - @Test - public void buildFromVanillSNBT() { - String vanillaSNBT = """ -{ - pages:['[ - "", - {"text":"\\\\n\\\\ntest\\\\n\\\\n"}, - {"text":"TESTSETSET","clickEvent":{"action":"run_command","value":"hi"}}, - {"text":"\\\\n\\\\n"}, - {"text":"COLORS","color":"dark_red"}, - {"text":"\\\\n\\\\n","color":"reset"}, - {"text":"EVERYTHING","bold":true,"italic":true,"strikethrough":true,"underlined":true,"obfuscated":true, - "color":"green","clickEvent":{"action":"run_command","value":"EVERYTHING"}, - "hoverEvent":{"action":"show_text","contents":"Test"}} - ]'], - title:"Minestom Book", - author:"https://minestom.net/", - display:{Lore:["Minestom."]} -} - """; - SNBTParser parser = new SNBTParser(new StringReader(vanillaSNBT)); - - ItemStack book = ItemStack.of(Material.WRITTEN_BOOK).withMeta(WrittenBookMeta.class, meta -> { - List pageA = new ArrayList<>(); - - pageA.add(Component.newline()); - pageA.add(Component.newline()); - pageA.add(Component.text("test")); - pageA.add(Component.newline()); - pageA.add(Component.newline()); - pageA.add(Component.text("TESTSETSET").clickEvent(ClickEvent.runCommand("hi"))); - pageA.add(Component.newline()); - pageA.add(Component.newline()); - pageA.add(Component.text("COLORS").color(NamedTextColor.DARK_RED)); - pageA.add(Component.newline()); - pageA.add(Component.newline()); - pageA.add(Component.text("EVERYTHING").style(style -> { - style.decoration(TextDecoration.BOLD, true); - style.decoration(TextDecoration.ITALIC, true); - style.decoration(TextDecoration.UNDERLINED, true); - style.decoration(TextDecoration.STRIKETHROUGH, true); - style.decoration(TextDecoration.OBFUSCATED, true); - style.color(NamedTextColor.GREEN); - style.clickEvent(ClickEvent.runCommand("EVERYTHING")); - style.hoverEvent(HoverEvent.showText(Component.text("Test"))); - })); - - Component firstPage = pageA.stream().reduce(Component::append).orElseGet(Component::empty); - - meta.pages(firstPage.compact()); - meta.title(Component.text("Minestom Book")); - meta.author(Component.text("https://minestom.net/")); - meta.lore(Component.text("Minestom.")); - }); - - try { - NBTCompound nbt = (NBTCompound) parser.parse(); - ItemStack vanillaBook = ItemStack.fromNBT(Material.WRITTEN_BOOK, nbt); - - var pagesA = vanillaBook.meta(WrittenBookMeta.class).getPages(); - var pagesB = book.meta(WrittenBookMeta.class).getPages(); - - // Compact the components to ensure they are the same format. - pagesA = pagesA.stream().map(Component::compact).toList(); - pagesB = pagesB.stream().map(Component::compact).toList(); - - assertEquals(pagesA, pagesB, "written book output meta must equal original input meta"); - } catch (Throwable e) { - fail(e); - } - } - - // TODO: Compare to vanilla snbt. This depends on a modern serializer that defaults to legacy in some properties. -// @Test -// public void compareToVanilla() { -// String vanillaSNBT = """ -//{ -// pages:['[ -// "", -// {"text":"\\\\n\\\\ntest\\\\n\\\\n"}, -// {"text":"TESTSETSET","clickEvent":{"action":"run_command","value":"hi"}}, -// {"text":"\\\\n\\\\n"}, -// {"text":"COLORS","color":"dark_red"}, -// {"text":"\\\\n\\\\n","color":"reset"}, -// {"text":"EVERYTHING","bold":true,"italic":true,"strikethrough":true,"underlined":true,"obfuscated":true, -// "color":"green","clickEvent":{"action":"run_command","value":"EVERYTHING"}, -// "hoverEvent":{"action":"show_text","contents":"Test"}} -// ]'], -// title:"Minestom Book", -// author:"https://minestom.net/", -// display:{Lore:["Minestom."]} -//} -// """; -// -// ItemStack book = ItemStack.of(Material.WRITTEN_BOOK).withMeta(WrittenBookMeta.class, meta -> { -// List pageA = new ArrayList<>(); -// -// pageA.add(Component.newline()); -// pageA.add(Component.newline()); -// pageA.add(Component.text("test")); -// pageA.add(Component.newline()); -// pageA.add(Component.newline()); -// pageA.add(Component.text("TESTSETSET").clickEvent(ClickEvent.runCommand("hi"))); -// pageA.add(Component.newline()); -// pageA.add(Component.newline()); -// pageA.add(Component.text("COLORS").color(NamedTextColor.DARK_RED)); -// pageA.add(Component.newline()); -// pageA.add(Component.newline()); -// pageA.add(Component.text("EVERYTHING").style(style -> { -// style.decoration(TextDecoration.BOLD, true); -// style.decoration(TextDecoration.ITALIC, true); -// style.decoration(TextDecoration.UNDERLINED, true); -// style.decoration(TextDecoration.STRIKETHROUGH, true); -// style.decoration(TextDecoration.OBFUSCATED, true); -// style.color(NamedTextColor.GREEN); -// style.clickEvent(ClickEvent.runCommand("EVERYTHING")); -// style.hoverEvent(HoverEvent.showText(Component.text("Test"))); -// })); -// -// Component firstPage = pageA.stream().reduce(Component::append).orElseGet(() -> Component.empty()); -// -// meta.pages(firstPage.compact()); -// meta.title(Component.text("Minestom Book")); -// meta.author(Component.text("https://minestom.net/")); -// meta.lore(Component.text("Minestom.")); -// }); -// -// TestUtils.assertEqualsSNBT(vanillaSNBT, (NBTCompound) book.toItemNBT().get("tag")); -// } -} diff --git a/src/test/java/net/minestom/server/item/ItemTest.java b/src/test/java/net/minestom/server/item/ItemTest.java index 2bdb517b3..9c196d051 100644 --- a/src/test/java/net/minestom/server/item/ItemTest.java +++ b/src/test/java/net/minestom/server/item/ItemTest.java @@ -3,10 +3,11 @@ package net.minestom.server.item; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.entity.EntityType; +import net.minestom.server.item.component.EnchantmentList; import net.minestom.server.item.enchant.Enchantment; -import org.jglrxavpok.hephaistos.nbt.NBT; import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; @@ -18,10 +19,20 @@ public class ItemTest { var item = ItemStack.of(Material.DIAMOND_SWORD); assertEquals(item.material(), Material.DIAMOND_SWORD, "Material must be the same"); assertEquals(item.amount(), 1, "Default item amount must be 1"); - assertNull(item.getDisplayName(), "Default item display name must be null"); - assertTrue(item.getLore().isEmpty(), "Default item lore must be empty"); + + // Should have the exact same components as the material prototype + var prototype = Material.DIAMOND_SWORD.registry().prototype(); + for (ItemComponent component : ItemComponent.values()) { + var proto = prototype.get(component); + if (proto == null) { + assertFalse(item.has(component), "Item should not have component " + component); + } else { + assertEquals(proto, item.get(component), "Item should have the same component as the prototype"); + } + } + ItemStack finalItem = item; - assertThrows(Exception.class, () -> finalItem.getLore().add(Component.text("Hey!")), "Lore list cannot be modified directly"); + assertThrows(UnsupportedOperationException.class, () -> finalItem.get(ItemComponent.LORE).add(Component.text("Hey!")), "Lore list cannot be modified directly"); item = item.withAmount(5); assertEquals(item.amount(), 5, "Items with different amount should not be equals"); @@ -33,10 +44,20 @@ public class ItemTest { var item = ItemStack.builder(Material.DIAMOND_SWORD).build(); assertEquals(item.material(), Material.DIAMOND_SWORD, "Material must be the same"); assertEquals(item.amount(), 1, "Default item amount must be 1"); - assertNull(item.getDisplayName(), "Default item display name must be null"); - assertTrue(item.getLore().isEmpty(), "Default item lore must be empty"); + + // Should have the exact same components as the material prototype + var prototype = Material.DIAMOND_SWORD.registry().prototype(); + for (ItemComponent component : ItemComponent.values()) { + var proto = prototype.get(component); + if (proto == null) { + assertFalse(item.has(component), "Item should not have component " + component); + } else { + assertEquals(proto, item.get(component), "Item should have the same component as the prototype"); + } + } + ItemStack finalItem = item; - assertThrows(Exception.class, () -> finalItem.getLore().add(Component.text("Hey!")), "Lore list cannot be modified directly"); + assertThrows(UnsupportedOperationException.class, () -> finalItem.get(ItemComponent.LORE).add(Component.text("Hey!")), "Lore list cannot be modified directly"); item = item.withAmount(5); assertEquals(item.amount(), 5, "Items with different amount should not be equals"); @@ -52,17 +73,7 @@ public class ItemTest { assertTrue(item1.isSimilar(item2)); assertTrue(item1.withAmount(5).isSimilar(item2.withAmount(2))); - assertFalse(item1.isSimilar(item2.withDisplayName(Component.text("Hey!")))); - } - - @Test - public void testItemNbt() { - var itemNbt = createItem().toItemNBT(); - assertEquals(itemNbt.getString("id"), createItem().material().name(), "id string should be the material name"); - assertEquals(itemNbt.getByte("Count"), (byte) createItem().amount(), "Count byte should be the item amount"); - var metaNbt = itemNbt.getCompound("tag"); - var metaNbt2 = createItem().meta().toNBT(); - assertEquals(metaNbt, metaNbt2, "tag compound should be equal to the meta nbt"); + assertFalse(item1.isSimilar(item2.with(ItemComponent.CUSTOM_NAME, Component.text("Hey!")))); } @Test @@ -71,33 +82,31 @@ public class ItemTest { var item = ItemStack.fromItemNBT(itemNbt); assertEquals(createItem(), item, "Items must be equal if created from the same item nbt"); assertEquals(itemNbt, item.toItemNBT(), "Item nbt must be equal back"); - - var metaNbt = createItem().meta().toNBT(); - item = ItemStack.fromNBT(createItem().material(), metaNbt, createItem().amount()); - assertEquals(createItem(), item, "Items must be equal if created from the same meta nbt"); } @Test public void testBuilderReuse() { var builder = ItemStack.builder(Material.DIAMOND); var item1 = builder.build(); - var item2 = builder.displayName(Component.text("Name")).build(); - assertNull(item1.getDisplayName()); - assertNotNull(item2.getDisplayName()); + var item2 = builder.set(ItemComponent.CUSTOM_NAME, Component.text("Name")).build(); + assertNull(item1.get(ItemComponent.CUSTOM_NAME)); + assertNotNull(item2.get(ItemComponent.CUSTOM_NAME)); assertNotEquals(item1, item2, "Item builder should be reusable"); } @Test public void materialUpdate() { - var nbt = NBT.Compound(Map.of("key", NBT.String("value"))); - var item1 = ItemStack.fromNBT(Material.DIAMOND, nbt, 5); + var item1 = ItemStack.builder(Material.DIAMOND) + .amount(5).set(ItemComponent.CUSTOM_NAME, Component.text("Name")) + .build(); var item2 = item1.withMaterial(Material.GOLD_INGOT); assertEquals(Material.DIAMOND, item1.material()); assertEquals(Material.GOLD_INGOT, item2.material()); - assertEquals(nbt, item1.meta().toNBT()); - assertEquals(nbt, item2.meta().toNBT()); + var nbt1 = item1.toItemNBT().remove("id"); + var nbt2 = item2.toItemNBT().remove("id"); + assertEquals(nbt1, nbt2); assertEquals(5, item1.amount()); assertEquals(5, item2.amount()); @@ -121,11 +130,9 @@ public class ItemTest { static ItemStack createItem() { return ItemStack.builder(Material.STONE) - .displayName(Component.text("Display name!", NamedTextColor.GREEN)) - .lore(Component.text("Line 1"), Component.text("Line 2")) - .meta(metaBuilder -> - metaBuilder.enchantment(Enchantment.EFFICIENCY, (short) 10) - .hideFlag(ItemHideFlag.HIDE_ENCHANTS)) + .set(ItemComponent.CUSTOM_NAME, Component.text("Display name!", NamedTextColor.GREEN)) + .set(ItemComponent.LORE, List.of(Component.text("Line 1"), Component.text("Line 2"))) + .set(ItemComponent.ENCHANTMENTS, new EnchantmentList(Map.of(Enchantment.EFFICIENCY, 10), false)) .build(); } } diff --git a/src/test/java/net/minestom/server/network/NetworkBufferTest.java b/src/test/java/net/minestom/server/network/NetworkBufferTest.java index f6b5d18dc..ea02bdedd 100644 --- a/src/test/java/net/minestom/server/network/NetworkBufferTest.java +++ b/src/test/java/net/minestom/server/network/NetworkBufferTest.java @@ -1,6 +1,8 @@ package net.minestom.server.network; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; +import net.minestom.server.item.ItemComponent; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import org.jetbrains.annotations.NotNull; @@ -12,6 +14,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.*; +import static net.kyori.adventure.nbt.IntBinaryTag.intBinaryTag; import static net.minestom.server.network.NetworkBuffer.*; import static org.junit.jupiter.api.Assertions.*; @@ -237,8 +240,8 @@ public class NetworkBufferTest { @Test public void nbt() { - assertBufferType(NetworkBuffer.NBT, org.jglrxavpok.hephaistos.nbt.NBT.Int(5)); - assertBufferType(NetworkBuffer.NBT, org.jglrxavpok.hephaistos.nbt.NBT.Compound(Map.of("key", org.jglrxavpok.hephaistos.nbt.NBT.Int(5)))); + assertBufferType(NetworkBuffer.NBT, intBinaryTag(5)); + assertBufferType(NetworkBuffer.NBT, CompoundBinaryTag.from(Map.of("key", intBinaryTag(5)))); } @Test @@ -254,9 +257,9 @@ public class NetworkBufferTest { @Test public void item() { - assertBufferType(ITEM, ItemStack.AIR); - assertBufferType(ITEM, ItemStack.of(Material.STONE, 1)); - assertBufferType(ITEM, ItemStack.of(Material.DIAMOND_AXE, 1).withMeta(builder -> builder.damage(1))); + assertBufferType(ItemStack.NETWORK_TYPE, ItemStack.AIR); + assertBufferType(ItemStack.NETWORK_TYPE, ItemStack.of(Material.STONE, 1)); + assertBufferType(ItemStack.NETWORK_TYPE, ItemStack.of(Material.DIAMOND_AXE, 1).with(ItemComponent.DAMAGE, 1)); } @Test diff --git a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java index 4d4df24c6..e67cf2079 100644 --- a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java +++ b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java @@ -2,6 +2,7 @@ package net.minestom.server.network; import com.google.gson.JsonObject; import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.EquipmentSlot; @@ -22,7 +23,6 @@ import net.minestom.server.network.packet.server.play.*; import net.minestom.server.network.packet.server.play.DeclareRecipesPacket.Ingredient; import net.minestom.server.network.packet.server.status.ResponsePacket; import net.minestom.server.recipe.RecipeCategory; -import org.jglrxavpok.hephaistos.nbt.NBT; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -65,7 +65,7 @@ public class PacketWriteReadTest { SERVER_PACKETS.add(new BlockActionPacket(VEC, (byte) 5, (byte) 5, 5)); SERVER_PACKETS.add(new BlockBreakAnimationPacket(5, VEC, (byte) 5)); SERVER_PACKETS.add(new BlockChangePacket(VEC, 0)); - SERVER_PACKETS.add(new BlockEntityDataPacket(VEC, 5, NBT.Compound(Map.of("key", NBT.String("value"))))); + SERVER_PACKETS.add(new BlockEntityDataPacket(VEC, 5, CompoundBinaryTag.builder().putString("key", "value").build())); SERVER_PACKETS.add(new BossBarPacket(UUID.randomUUID(), new BossBarPacket.AddAction(COMPONENT, 5f, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS, (byte) 2))); SERVER_PACKETS.add(new BossBarPacket(UUID.randomUUID(), new BossBarPacket.RemoveAction())); SERVER_PACKETS.add(new BossBarPacket(UUID.randomUUID(), new BossBarPacket.UpdateHealthAction(5f))); @@ -157,7 +157,7 @@ public class PacketWriteReadTest { @BeforeAll public static void setupClient() { - CLIENT_PACKETS.add(new ClientHandshakePacket(755, "localhost", 25565, 2)); + CLIENT_PACKETS.add(new ClientHandshakePacket(755, "localhost", 25565, ClientHandshakePacket.Intent.LOGIN)); } @Test diff --git a/src/test/java/net/minestom/server/particle/ParticleDataTest.java b/src/test/java/net/minestom/server/particle/ParticleDataTest.java index 6eea521a9..ecabfadfb 100644 --- a/src/test/java/net/minestom/server/particle/ParticleDataTest.java +++ b/src/test/java/net/minestom/server/particle/ParticleDataTest.java @@ -41,14 +41,14 @@ public class ParticleDataTest { @Test public void testParticleValid() { - var particle = Particle.AMBIENT_ENTITY_EFFECT; + var particle = Particle.ENTITY_EFFECT; ParticlePacket packet = new ParticlePacket(particle, true, 0, 0, 0, 0, 0, 0, 0, 0); assertDoesNotThrow(() -> packet.write(new NetworkBuffer())); } @Test public void testParticleData() { - var particle = Particle.AMBIENT_ENTITY_EFFECT; + var particle = Particle.ENTITY_EFFECT; ParticlePacket packet = new ParticlePacket(particle, true, 0, 0, 0, 0, 0, 0, 0, 0); assertDoesNotThrow(() -> packet.write(new NetworkBuffer())); } diff --git a/src/test/java/net/minestom/server/permission/TestPermissions.java b/src/test/java/net/minestom/server/permission/TestPermissions.java index c5604540d..f6bcde9c6 100644 --- a/src/test/java/net/minestom/server/permission/TestPermissions.java +++ b/src/test/java/net/minestom/server/permission/TestPermissions.java @@ -1,8 +1,8 @@ package net.minestom.server.permission; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; -import org.jglrxavpok.hephaistos.nbt.NBT; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,10 +35,10 @@ public class TestPermissions { }; permission1 = new Permission("perm.name", - NBT.Compound(nbt -> { - nbt.setString("name", "Minestom"); - nbt.setInt("amount", 5); - }) + CompoundBinaryTag.builder() + .putString("name", "Minestom") + .putInt("amount", 5) + .build() ); permission2 = new Permission("perm.name2"); diff --git a/src/test/java/net/minestom/server/tag/TagItemTest.java b/src/test/java/net/minestom/server/tag/TagItemTest.java index d3ab11a63..688a271ef 100644 --- a/src/test/java/net/minestom/server/tag/TagItemTest.java +++ b/src/test/java/net/minestom/server/tag/TagItemTest.java @@ -103,7 +103,7 @@ public class TagItemTest { { "item": { "id":"minecraft:diamond", - "Count":1B + "count":1 } } """, handler.asCompound()); diff --git a/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java b/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java index 4e9f46c41..17ff99ad5 100644 --- a/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java +++ b/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java @@ -1,12 +1,10 @@ package net.minestom.server.tag; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTType; +import net.kyori.adventure.nbt.*; import org.junit.jupiter.api.Test; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -16,49 +14,49 @@ public class TagNbtSeparatorTest { @Test public void primitives() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Byte("key"), (byte) 1), - "key", NBT.Byte(1)); + "key", ByteBinaryTag.byteBinaryTag((byte) 1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Short("key"), (short) 1), - "key", NBT.Short(1)); + "key", ShortBinaryTag.shortBinaryTag((short) 1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Integer("key"), 1), - "key", NBT.Int(1)); + "key", IntBinaryTag.intBinaryTag(1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Long("key"), 1L), - "key", NBT.Long(1)); + "key", LongBinaryTag.longBinaryTag(1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Float("key"), 1f), - "key", NBT.Float(1)); + "key", FloatBinaryTag.floatBinaryTag(1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Double("key"), 1d), - "key", NBT.Double(1)); + "key", DoubleBinaryTag.doubleBinaryTag(1)); } @Test public void compound() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Byte("key").path("path"), (byte) 1), - "path", NBT.Compound(Map.of("key", NBT.Byte(1)))); + "path", CompoundBinaryTag.builder().putByte("key", (byte) 1).build()); } @Test public void compoundMultiple() { assertSeparation(Set.of(new TagNbtSeparator.Entry<>(Tag.Byte("key").path("path"), (byte) 1), new TagNbtSeparator.Entry<>(Tag.Integer("key2").path("path"), 2)), - "path", NBT.Compound(Map.of("key", NBT.Byte(1), "key2", NBT.Int(2)))); + "path", CompoundBinaryTag.builder().putByte("key", (byte) 1).putInt("key2", 2).build()); } @Test public void list() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Integer("key").list(), List.of(1)), - "key", NBT.List(NBTType.TAG_Int, NBT.Int(1))); + "key", ListBinaryTag.listBinaryTag(BinaryTagTypes.INT, List.of(IntBinaryTag.intBinaryTag(1)))); } - void assertSeparation(Set> expected, String key, NBT nbt) { + void assertSeparation(Set> expected, String key, BinaryTag nbt) { assertEquals(expected, retrieve(key, nbt)); } - void assertSeparation(TagNbtSeparator.Entry expected, String key, NBT nbt) { + void assertSeparation(TagNbtSeparator.Entry expected, String key, BinaryTag nbt) { var entries = retrieve(key, nbt); assertEquals(1, entries.size()); assertEquals(expected, entries.iterator().next()); } - Set> retrieve(String key, NBT nbt) { + Set> retrieve(String key, BinaryTag nbt) { Set> entries = new HashSet<>(); TagNbtSeparator.separate(key, nbt, entries::add); return Set.copyOf(entries); diff --git a/src/test/java/net/minestom/server/tag/TagNbtTest.java b/src/test/java/net/minestom/server/tag/TagNbtTest.java index 81fa51a86..a1101f6a6 100644 --- a/src/test/java/net/minestom/server/tag/TagNbtTest.java +++ b/src/test/java/net/minestom/server/tag/TagNbtTest.java @@ -1,13 +1,17 @@ package net.minestom.server.tag; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTInt; -import org.jglrxavpok.hephaistos.nbt.NBTType; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; import org.junit.jupiter.api.Test; import java.util.List; import java.util.Map; +import static net.kyori.adventure.nbt.IntArrayBinaryTag.intArrayBinaryTag; +import static net.kyori.adventure.nbt.IntBinaryTag.intBinaryTag; +import static net.kyori.adventure.nbt.ListBinaryTag.listBinaryTag; import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; @@ -21,7 +25,7 @@ public class TagNbtTest { public void list() { var handler = TagHandler.newHandler(); var tag = Tag.NBT("nbt").list(); - List list = List.of(NBT.Int(1), NBT.Int(2), NBT.Int(3)); + List list = List.of(intBinaryTag(1), intBinaryTag(2), intBinaryTag(3)); handler.setTag(tag, list); assertEquals(list, handler.getTag(tag)); assertEqualsSNBT(""" @@ -37,7 +41,7 @@ public class TagNbtTest { @Test public void map() { var handler = TagHandler.newHandler(); - var tag = Tag.NBT("nbt").map(nbt -> ((NBTInt) nbt).getValue(), NBT::Int); + var tag = Tag.NBT("nbt").map(nbt -> ((IntBinaryTag) nbt).value(), IntBinaryTag::intBinaryTag); handler.setTag(tag, 5); assertEquals(5, handler.getTag(tag)); assertEqualsSNBT(""" @@ -52,7 +56,7 @@ public class TagNbtTest { @Test public void fromCompoundModify() { - var compound = NBT.Compound(Map.of("key", NBT.Int(5))); + var compound = CompoundBinaryTag.builder().putInt("key", 5).build(); var handler = TagHandler.fromCompound(compound); assertEquals(compound, handler.asCompound()); assertEqualsSNBT(""" @@ -72,7 +76,7 @@ public class TagNbtTest { @Test public void fromCompoundModifyPath() { - var compound = NBT.Compound(Map.of("path", NBT.Compound(Map.of("key", NBT.Int(5))))); + var compound = CompoundBinaryTag.builder().put("path", CompoundBinaryTag.builder().putInt("key", 5).build()).build(); var handler = TagHandler.fromCompound(compound); var tag = Tag.Integer("key").path("path"); @@ -89,8 +93,8 @@ public class TagNbtTest { @Test public void fromCompoundModifyDoublePath() { - var compound = NBT.Compound(Map.of("path", NBT.Compound(Map.of("path2", - NBT.Compound(Map.of("key", NBT.Int(5))))))); + var compound = CompoundBinaryTag.builder().put("path", CompoundBinaryTag.builder() + .put("path2", CompoundBinaryTag.builder().putInt("key", 5).build()).build()).build(); var handler = TagHandler.fromCompound(compound); var tag = Tag.Integer("key").path("path", "path2"); @@ -110,8 +114,8 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("path1"); - var nbt1 = NBT.Compound(Map.of("key", NBT.Int(5))); - var nbt2 = NBT.Compound(Map.of("other-key", NBT.Int(5))); + var nbt1 = CompoundBinaryTag.from(Map.of("key", intBinaryTag(5))); + var nbt2 = CompoundBinaryTag.from(Map.of("other-key", intBinaryTag(5))); handler.setTag(nbtTag, nbt1); assertEquals(nbt1, handler.getTag(nbtTag)); @@ -124,7 +128,7 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("path1"); - var nbt = NBT.Compound(Map.of("key", NBT.Int(5))); + var nbt = CompoundBinaryTag.from(Map.of("key", intBinaryTag(5))); handler.setTag(nbtTag, nbt); assertEquals(nbt, handler.getTag(nbtTag)); @@ -137,7 +141,7 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("compound").path("path"); - var nbt = NBT.Compound(Map.of("key", NBT.Int(5))); + var nbt = CompoundBinaryTag.from(Map.of("key", intBinaryTag(5))); handler.setTag(nbtTag, nbt); assertEquals(nbt, handler.getTag(nbtTag)); @@ -150,7 +154,7 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("path1"); - var nbt = NBT.Compound(Map.of("path2", NBT.Compound(Map.of("key", NBT.Int(5))))); + var nbt = CompoundBinaryTag.from(Map.of("path2", CompoundBinaryTag.from(Map.of("key", intBinaryTag(5))))); handler.setTag(nbtTag, nbt); assertEquals(nbt, handler.getTag(nbtTag)); @@ -163,21 +167,21 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("path1"); - var nbt = NBT.Compound(Map.of("key", NBT.Int(5))); + var nbt = CompoundBinaryTag.from(Map.of("key", intBinaryTag(5))); handler.setTag(nbtTag, nbt); assertEquals(nbt, handler.getTag(nbtTag)); var path = Tag.Integer("key").path("path1"); handler.setTag(path, 10); assertEquals(10, handler.getTag(path)); - assertEquals(NBT.Compound(Map.of("key", NBT.Int(10))), handler.getTag(nbtTag)); + assertEquals(CompoundBinaryTag.from(Map.of("key", intBinaryTag(10))), handler.getTag(nbtTag)); } @Test public void rawList() { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("list"); - var list = NBT.List(NBTType.TAG_Int, NBT.Int(1)); + var list = listBinaryTag(BinaryTagTypes.INT, List.of(intBinaryTag(1))); handler.setTag(nbtTag, list); assertEquals(list, handler.getTag(nbtTag)); } @@ -187,7 +191,7 @@ public class TagNbtTest { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("list"); var listTag = Tag.Integer("list").list(); - var list = NBT.List(NBTType.TAG_Int, NBT.Int(1)); + var list = listBinaryTag(BinaryTagTypes.INT, List.of(intBinaryTag(1))); handler.setTag(nbtTag, list); assertEquals(list, handler.getTag(nbtTag)); @@ -199,7 +203,7 @@ public class TagNbtTest { public void rawArray() { var handler = TagHandler.newHandler(); var nbtTag = Tag.NBT("array"); - var array = NBT.IntArray(1, 2, 3); + var array = intArrayBinaryTag(1, 2, 3); handler.setTag(nbtTag, array); assertEquals(array, handler.getTag(nbtTag)); } diff --git a/src/test/java/net/minestom/server/tag/TagRecordTest.java b/src/test/java/net/minestom/server/tag/TagRecordTest.java index 1dfed907b..7e3a71991 100644 --- a/src/test/java/net/minestom/server/tag/TagRecordTest.java +++ b/src/test/java/net/minestom/server/tag/TagRecordTest.java @@ -1,10 +1,10 @@ package net.minestom.server.tag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; import net.minestom.server.item.ItemStack; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; import java.util.List; @@ -27,21 +27,23 @@ public class TagRecordTest { @Test public void fromNBT() { - var vecCompound = NBT.Compound(Map.of( - "x", NBT.Double(1), - "y", NBT.Double(2), - "z", NBT.Double(3))); - var handler = TagHandler.fromCompound(NBT.Compound(Map.of("vec", vecCompound))); + var vecCompound = CompoundBinaryTag.builder() + .putDouble("x", 1) + .putDouble("y", 2) + .putDouble("z", 3) + .build(); + var handler = TagHandler.fromCompound(CompoundBinaryTag.from(Map.of("vec", vecCompound))); var tag = Tag.Structure("vec", Vec.class); assertEquals(new Vec(1, 2, 3), handler.getTag(tag)); } @Test public void fromNBTView() { - var handler = TagHandler.fromCompound(NBT.Compound(Map.of( - "x", NBT.Double(1), - "y", NBT.Double(2), - "z", NBT.Double(3)))); + var handler = TagHandler.fromCompound(CompoundBinaryTag.builder() + .putDouble("x", 1) + .putDouble("y", 2) + .putDouble("z", 3) + .build()); var tag = Tag.View(Vec.class); assertEquals(new Vec(1, 2, 3), handler.getTag(tag)); } @@ -75,9 +77,9 @@ public class TagRecordTest { @Test public void nbtSerializer() { - record CompoundRecord(NBTCompound compound) { + record CompoundRecord(CompoundBinaryTag compound) { } - var test = new CompoundRecord(NBT.Compound(Map.of("key", NBT.String("value")))); + var test = new CompoundRecord(CompoundBinaryTag.from(Map.of("key", StringBinaryTag.stringBinaryTag("value")))); var handler = TagHandler.newHandler(); var serializer = TagRecord.serializer(CompoundRecord.class); serializer.write(handler, test); diff --git a/src/test/java/net/minestom/server/tag/TagSerializerTest.java b/src/test/java/net/minestom/server/tag/TagSerializerTest.java index 2f7c6e91e..6279372ad 100644 --- a/src/test/java/net/minestom/server/tag/TagSerializerTest.java +++ b/src/test/java/net/minestom/server/tag/TagSerializerTest.java @@ -1,7 +1,7 @@ package net.minestom.server.tag; -import net.minestom.server.item.firework.FireworkEffect; -import net.minestom.server.item.firework.FireworkEffectType; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.item.component.FireworkExplosion; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -10,8 +10,8 @@ import java.util.List; public class TagSerializerTest { @Test public void fromCompound(){ - var serializer = TagSerializer.fromCompound(FireworkEffect::fromCompound, FireworkEffect::asCompound); - var effect = new FireworkEffect(false, false, FireworkEffectType.BURST, List.of(), List.of()); + var serializer = TagSerializer.fromCompound(FireworkExplosion.NBT_TYPE::read, explosion -> (CompoundBinaryTag) FireworkExplosion.NBT_TYPE.write(explosion)); + var effect = new FireworkExplosion(FireworkExplosion.Shape.BURST, List.of(), List.of(), false, false); TagHandler handler = TagHandler.newHandler(); serializer.write(handler, effect); Assertions.assertEquals(effect, serializer.read(handler)); diff --git a/src/test/java/net/minestom/server/tag/TagTest.java b/src/test/java/net/minestom/server/tag/TagTest.java index d1376f66c..3256308f3 100644 --- a/src/test/java/net/minestom/server/tag/TagTest.java +++ b/src/test/java/net/minestom/server/tag/TagTest.java @@ -1,71 +1,68 @@ package net.minestom.server.tag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.TagStringIOExt; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import org.jglrxavpok.hephaistos.nbt.mutable.MutableNBTCompound; import org.junit.jupiter.api.Test; -import java.util.Map; - import static org.junit.jupiter.api.Assertions.*; public class TagTest { @Test public void intGet() { - var mutable = new MutableNBTCompound().setInt("key", 5); + var mutable = CompoundBinaryTag.builder().putInt("key", 5); var tag = Tag.Integer("key"); - var handler = TagHandler.fromCompound(new MutableNBTCompound()); + var handler = TagHandler.fromCompound(CompoundBinaryTag.empty()); handler.setTag(tag, 5); assertEquals(5, handler.getTag(tag)); - assertEquals(mutable.toCompound(), handler.asCompound(), "NBT is not the same"); + assertEquals(mutable.build(), handler.asCompound(), "NBT is not the same"); // Removal handler.setTag(tag, null); - assertEquals(new NBTCompound(), handler.asCompound(), "Tag must be removed when set to null"); + assertEquals(CompoundBinaryTag.empty(), handler.asCompound(), "Tag must be removed when set to null"); } @Test public void intNull() { - var handler = TagHandler.fromCompound(new MutableNBTCompound().set("key", NBT.Int(5))); + var handler = TagHandler.fromCompound(CompoundBinaryTag.builder().putInt("key", 5).build()); // Removal var tag = Tag.Integer("key"); handler.setTag(tag, null); assertFalse(handler.hasTag(tag)); - assertEquals(NBTCompound.EMPTY, handler.asCompound(), "Tag must be removed when set to null"); + assertEquals(CompoundBinaryTag.empty(), handler.asCompound(), "Tag must be removed when set to null"); } @Test public void intRemove() { - var handler = TagHandler.fromCompound(new MutableNBTCompound().set("key", NBT.Int(5))); + var handler = TagHandler.fromCompound(CompoundBinaryTag.builder().putInt("key", 5).build()); // Removal var tag = Tag.Integer("key"); handler.removeTag(tag); assertFalse(handler.hasTag(tag)); - assertEquals(NBTCompound.EMPTY, handler.asCompound(), "Tag must be removed when set to null"); + assertEquals(CompoundBinaryTag.empty(), handler.asCompound(), "Tag must be removed when set to null"); } @Test public void snbt() { - var mutable = new MutableNBTCompound().setInt("key", 5); - var reader = TagHandler.fromCompound(mutable); - assertEquals(reader.asCompound().toSNBT(), mutable.toCompound().toSNBT(), "SNBT is not the same"); + var compound = CompoundBinaryTag.builder().putInt("key", 5).build(); + var reader = TagHandler.fromCompound(compound); + assertEquals(TagStringIOExt.writeTag(reader.asCompound()), TagStringIOExt.writeTag(compound), "SNBT is not the same"); } @Test public void fromNbt() { - var mutable = new MutableNBTCompound().setInt("key", 5); - var handler = TagHandler.fromCompound(mutable); + var compound = CompoundBinaryTag.builder().putInt("key", 5).build(); + var handler = TagHandler.fromCompound(compound); assertEquals(5, handler.getTag(Tag.Integer("key"))); - assertEquals(mutable.toCompound(), handler.asCompound(), "NBT is not the same"); + assertEquals(compound, handler.asCompound(), "NBT is not the same"); } @Test public void fromNbtCache() { // Ensure that TagHandler#asCompound reuse the same compound used for construction - var compound = NBT.Compound(Map.of("key", NBT.Int(5))); + var compound = CompoundBinaryTag.builder().putInt("key", 5).build(); var handler = TagHandler.fromCompound(compound); assertSame(compound, handler.asCompound(), "NBT is not the same"); } @@ -122,9 +119,10 @@ public class TagTest { @Test public void nbtResizing() { - var handler = TagHandler.fromCompound(NBT.Compound(Map.of( - "tag1", NBT.Int(5), - "tag2", NBT.Int(1)))); + var handler = TagHandler.fromCompound(CompoundBinaryTag.builder() + .putInt("tag1", 5) + .putInt("tag2", 1) + .build()); assertEquals(5, handler.getTag(Tag.Integer("tag1"))); assertEquals(1, handler.getTag(Tag.Integer("tag2"))); diff --git a/src/test/java/net/minestom/server/tag/TagUuidTest.java b/src/test/java/net/minestom/server/tag/TagUuidTest.java index 7867639d8..0e8d1acde 100644 --- a/src/test/java/net/minestom/server/tag/TagUuidTest.java +++ b/src/test/java/net/minestom/server/tag/TagUuidTest.java @@ -1,7 +1,6 @@ package net.minestom.server.tag; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTIntArray; +import net.kyori.adventure.nbt.IntArrayBinaryTag; import org.junit.jupiter.api.Test; import java.util.UUID; @@ -40,16 +39,15 @@ public class TagUuidTest { var handler = TagHandler.newHandler(); handler.setTag(tag, UUID.fromString("9ab8ca63-3d7b-43ba-b805-a20a352dae9c")); var nbt = handler.asCompound(); - NBTIntArray array = (NBTIntArray) nbt.get("uuid"); - assertArrayEquals(new int[]{-1699165597, 1031488442, -1207590390, 892186268}, - array.getValue().copyArray()); + IntArrayBinaryTag array = (IntArrayBinaryTag) nbt.get("uuid"); + assertArrayEquals(new int[]{-1699165597, 1031488442, -1207590390, 892186268}, array.value()); } @Test public void fromNbt() { var tag = Tag.UUID("uuid"); var handler = TagHandler.newHandler(); - handler.setTag(Tag.NBT("uuid"), NBT.IntArray(-1699165597, 1031488442, -1207590390, 892186268)); + handler.setTag(Tag.NBT("uuid"), IntArrayBinaryTag.intArrayBinaryTag(-1699165597, 1031488442, -1207590390, 892186268)); assertEquals(UUID.fromString("9ab8ca63-3d7b-43ba-b805-a20a352dae9c"), handler.getTag(tag)); } } diff --git a/src/test/java/net/minestom/server/tag/TagViewTest.java b/src/test/java/net/minestom/server/tag/TagViewTest.java index 718d84a6b..9e5321877 100644 --- a/src/test/java/net/minestom/server/tag/TagViewTest.java +++ b/src/test/java/net/minestom/server/tag/TagViewTest.java @@ -1,13 +1,10 @@ package net.minestom.server.tag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jglrxavpok.hephaistos.nbt.NBT; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.junit.jupiter.api.Test; -import java.util.Map; - import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; @@ -150,7 +147,7 @@ public class TagViewTest { public void compoundSerializer() { var tag = Tag.View(TagSerializer.COMPOUND); var handler = TagHandler.newHandler(); - handler.setTag(tag, NBT.Compound(Map.of("value", NBT.String("hello")))); + handler.setTag(tag, CompoundBinaryTag.builder().putString("value", "hello").build()); assertEqualsSNBT(""" { "value":"hello" @@ -164,7 +161,7 @@ public class TagViewTest { } """, handler.asCompound()); - handler.setTag(tag, NBTCompound.EMPTY); + handler.setTag(tag, CompoundBinaryTag.empty()); assertEqualsSNBT("{}", handler.asCompound()); handler.setTag(tag, null); diff --git a/testing/src/main/java/net/minestom/testing/TestUtils.java b/testing/src/main/java/net/minestom/testing/TestUtils.java index e7db258fb..26253fcc4 100644 --- a/testing/src/main/java/net/minestom/testing/TestUtils.java +++ b/testing/src/main/java/net/minestom/testing/TestUtils.java @@ -1,10 +1,9 @@ package net.minestom.testing; -import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import org.jglrxavpok.hephaistos.nbt.NBTException; -import org.jglrxavpok.hephaistos.parser.SNBTParser; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.TagStringIOExt; -import java.io.StringReader; +import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Collection; import java.util.Set; @@ -33,11 +32,11 @@ public final class TestUtils { assertEquals(Set.copyOf(expected), Set.copyOf(actual)); } - public static void assertEqualsSNBT(String snbt, NBTCompound compound) { + public static void assertEqualsSNBT(String snbt, CompoundBinaryTag compound) { try { - final var converted = (NBTCompound) new SNBTParser(new StringReader(snbt)).parse(); + final var converted = (CompoundBinaryTag) TagStringIOExt.readTag(snbt); assertEquals(converted, compound); - } catch (NBTException e) { + } catch (IOException e) { fail(e); } }