From 6259f624f309cd9810c148259d8f117d7aaab5b8 Mon Sep 17 00:00:00 2001 From: Eoghanmc22 Date: Wed, 12 Aug 2020 13:08:04 -0400 Subject: [PATCH] starting of 1.16.2 support --- .../net/minestom/server/instance/Biome.java | 115 ------------ .../minestom/server/instance/block/Block.java | 2 +- .../minestom/server/registry/Registries.java | 15 -- .../minestom/codegen/RegistriesGenerator.java | 2 - src/main/java/fr/themode/demo/MainDemo.java | 3 +- src/main/java/fr/themode/demo/PlayerInit.java | 14 +- .../demo/commands/DimensionCommand.java | 8 +- .../demo/generator/ChunkGeneratorDemo.java | 5 +- .../demo/generator/NoiseTestGenerator.java | 5 +- .../net/minestom/server/MinecraftServer.java | 13 +- .../net/minestom/server/instance/Chunk.java | 1 + .../server/instance/ChunkGenerator.java | 1 + .../server/instance/InstanceContainer.java | 3 +- .../client/handler/ClientPacketsHandler.java | 2 +- .../handler/ClientPlayPacketsHandler.java | 34 ++-- .../packet/server/ServerPacketIdentifier.java | 88 ++++----- .../packet/server/login/JoinGamePacket.java | 23 ++- .../packet/server/play/ChunkDataPacket.java | 4 +- .../server/play/MultiBlockChangePacket.java | 5 +- .../minestom/server/reader/ChunkReader.java | 5 +- .../minestom/server/world/DimensionType.java | 171 +++++++++--------- .../server/world/DimensionTypeManager.java | 20 +- .../minestom/server/world/biomes/Biome.java | 98 ++++++++++ .../server/world/biomes/BiomeEffects.java | 127 +++++++++++++ .../server/world/biomes/BiomeManager.java | 82 +++++++++ .../server/world/biomes/BiomeParticles.java | 122 +++++++++++++ 26 files changed, 652 insertions(+), 316 deletions(-) delete mode 100644 src/autogenerated/java/net/minestom/server/instance/Biome.java create mode 100644 src/main/java/net/minestom/server/world/biomes/Biome.java create mode 100644 src/main/java/net/minestom/server/world/biomes/BiomeEffects.java create mode 100644 src/main/java/net/minestom/server/world/biomes/BiomeManager.java create mode 100644 src/main/java/net/minestom/server/world/biomes/BiomeParticles.java diff --git a/src/autogenerated/java/net/minestom/server/instance/Biome.java b/src/autogenerated/java/net/minestom/server/instance/Biome.java deleted file mode 100644 index fe0cb781b..000000000 --- a/src/autogenerated/java/net/minestom/server/instance/Biome.java +++ /dev/null @@ -1,115 +0,0 @@ -//============================== -// AUTOGENERATED BY EnumGenerator -//============================== -package net.minestom.server.instance; -import net.minestom.server.registry.Registries; -import net.minestom.server.utils.NamespaceID; -@SuppressWarnings({"deprecation"}) - -public enum Biome { - OCEAN("minecraft:ocean", 0), - PLAINS("minecraft:plains", 1), - DESERT("minecraft:desert", 2), - MOUNTAINS("minecraft:mountains", 3), - FOREST("minecraft:forest", 4), - TAIGA("minecraft:taiga", 5), - SWAMP("minecraft:swamp", 6), - RIVER("minecraft:river", 7), - NETHER_WASTES("minecraft:nether_wastes", 8), - THE_END("minecraft:the_end", 9), - FROZEN_OCEAN("minecraft:frozen_ocean", 10), - FROZEN_RIVER("minecraft:frozen_river", 11), - SNOWY_TUNDRA("minecraft:snowy_tundra", 12), - SNOWY_MOUNTAINS("minecraft:snowy_mountains", 13), - MUSHROOM_FIELDS("minecraft:mushroom_fields", 14), - MUSHROOM_FIELD_SHORE("minecraft:mushroom_field_shore", 15), - BEACH("minecraft:beach", 16), - DESERT_HILLS("minecraft:desert_hills", 17), - WOODED_HILLS("minecraft:wooded_hills", 18), - TAIGA_HILLS("minecraft:taiga_hills", 19), - MOUNTAIN_EDGE("minecraft:mountain_edge", 20), - JUNGLE("minecraft:jungle", 21), - JUNGLE_HILLS("minecraft:jungle_hills", 22), - JUNGLE_EDGE("minecraft:jungle_edge", 23), - DEEP_OCEAN("minecraft:deep_ocean", 24), - STONE_SHORE("minecraft:stone_shore", 25), - SNOWY_BEACH("minecraft:snowy_beach", 26), - BIRCH_FOREST("minecraft:birch_forest", 27), - BIRCH_FOREST_HILLS("minecraft:birch_forest_hills", 28), - DARK_FOREST("minecraft:dark_forest", 29), - SNOWY_TAIGA("minecraft:snowy_taiga", 30), - SNOWY_TAIGA_HILLS("minecraft:snowy_taiga_hills", 31), - GIANT_TREE_TAIGA("minecraft:giant_tree_taiga", 32), - GIANT_TREE_TAIGA_HILLS("minecraft:giant_tree_taiga_hills", 33), - WOODED_MOUNTAINS("minecraft:wooded_mountains", 34), - SAVANNA("minecraft:savanna", 35), - SAVANNA_PLATEAU("minecraft:savanna_plateau", 36), - BADLANDS("minecraft:badlands", 37), - WOODED_BADLANDS_PLATEAU("minecraft:wooded_badlands_plateau", 38), - BADLANDS_PLATEAU("minecraft:badlands_plateau", 39), - SMALL_END_ISLANDS("minecraft:small_end_islands", 40), - END_MIDLANDS("minecraft:end_midlands", 41), - END_HIGHLANDS("minecraft:end_highlands", 42), - END_BARRENS("minecraft:end_barrens", 43), - WARM_OCEAN("minecraft:warm_ocean", 44), - LUKEWARM_OCEAN("minecraft:lukewarm_ocean", 45), - COLD_OCEAN("minecraft:cold_ocean", 46), - DEEP_WARM_OCEAN("minecraft:deep_warm_ocean", 47), - DEEP_LUKEWARM_OCEAN("minecraft:deep_lukewarm_ocean", 48), - DEEP_COLD_OCEAN("minecraft:deep_cold_ocean", 49), - DEEP_FROZEN_OCEAN("minecraft:deep_frozen_ocean", 50), - THE_VOID("minecraft:the_void", 127), - SUNFLOWER_PLAINS("minecraft:sunflower_plains", 129), - DESERT_LAKES("minecraft:desert_lakes", 130), - GRAVELLY_MOUNTAINS("minecraft:gravelly_mountains", 131), - FLOWER_FOREST("minecraft:flower_forest", 132), - TAIGA_MOUNTAINS("minecraft:taiga_mountains", 133), - SWAMP_HILLS("minecraft:swamp_hills", 134), - ICE_SPIKES("minecraft:ice_spikes", 140), - MODIFIED_JUNGLE("minecraft:modified_jungle", 149), - MODIFIED_JUNGLE_EDGE("minecraft:modified_jungle_edge", 151), - TALL_BIRCH_FOREST("minecraft:tall_birch_forest", 155), - TALL_BIRCH_HILLS("minecraft:tall_birch_hills", 156), - DARK_FOREST_HILLS("minecraft:dark_forest_hills", 157), - SNOWY_TAIGA_MOUNTAINS("minecraft:snowy_taiga_mountains", 158), - GIANT_SPRUCE_TAIGA("minecraft:giant_spruce_taiga", 160), - GIANT_SPRUCE_TAIGA_HILLS("minecraft:giant_spruce_taiga_hills", 161), - MODIFIED_GRAVELLY_MOUNTAINS("minecraft:modified_gravelly_mountains", 162), - SHATTERED_SAVANNA("minecraft:shattered_savanna", 163), - SHATTERED_SAVANNA_PLATEAU("minecraft:shattered_savanna_plateau", 164), - ERODED_BADLANDS("minecraft:eroded_badlands", 165), - MODIFIED_WOODED_BADLANDS_PLATEAU("minecraft:modified_wooded_badlands_plateau", 166), - MODIFIED_BADLANDS_PLATEAU("minecraft:modified_badlands_plateau", 167), - BAMBOO_JUNGLE("minecraft:bamboo_jungle", 168), - BAMBOO_JUNGLE_HILLS("minecraft:bamboo_jungle_hills", 169), - SOUL_SAND_VALLEY("minecraft:soul_sand_valley", 170), - CRIMSON_FOREST("minecraft:crimson_forest", 171), - WARPED_FOREST("minecraft:warped_forest", 172), - BASALT_DELTAS("minecraft:basalt_deltas", 173), -; - private String namespaceID; - private int id; - - Biome(String namespaceID, int id) { - this.namespaceID = namespaceID; - this.id = id; - Registries.biomes.put(NamespaceID.from(namespaceID), this); - } - - public int getId() { - return id; - } - - public String getNamespaceID() { - return namespaceID; - } - - public static Biome fromId(int id) { - for(Biome o : values()) { - if(o.getId() == id) { - return o; - } - } - return null; - } -} diff --git a/src/autogenerated/java/net/minestom/server/instance/block/Block.java b/src/autogenerated/java/net/minestom/server/instance/block/Block.java index cf9b7ca68..35f5ed879 100644 --- a/src/autogenerated/java/net/minestom/server/instance/block/Block.java +++ b/src/autogenerated/java/net/minestom/server/instance/block/Block.java @@ -1259,7 +1259,7 @@ public enum Block { private NamespaceID blockEntity; private boolean singleState; - private List alternatives = new ArrayList(); + private List alternatives = new ArrayList<>(); Block(String namespaceID, short defaultID, double hardness, double resistance, boolean isAir, boolean isSolid, NamespaceID blockEntity, boolean singleState) { this.namespaceID = namespaceID; diff --git a/src/autogenerated/java/net/minestom/server/registry/Registries.java b/src/autogenerated/java/net/minestom/server/registry/Registries.java index a0cc042a7..c22803eff 100644 --- a/src/autogenerated/java/net/minestom/server/registry/Registries.java +++ b/src/autogenerated/java/net/minestom/server/registry/Registries.java @@ -4,7 +4,6 @@ import java.util.HashMap; import net.minestom.server.utils.NamespaceID; import net.minestom.server.instance.block.Block; import net.minestom.server.item.Material; -import net.minestom.server.instance.Biome; import net.minestom.server.item.Enchantment; import net.minestom.server.entity.EntityType; import net.minestom.server.particle.Particle; @@ -23,10 +22,6 @@ public class Registries { @Deprecated public static final HashMap materials = new HashMap<>(); - /** Should only be used for internal code, please use the get* methods. */ - @Deprecated - public static final HashMap biomes = new HashMap<>(); - /** Should only be used for internal code, please use the get* methods. */ @Deprecated public static final HashMap enchantments = new HashMap<>(); @@ -76,16 +71,6 @@ public class Registries { return materials.getOrDefault(id, Material.AIR); } - /** Returns the corresponding Biome matching the given id. Returns null if none match. */ - public static Biome getBiome(String id) { - return getBiome(NamespaceID.from(id)); - } - - /** Returns the corresponding Biome matching the given id. Returns null if none match. */ - public static Biome getBiome(NamespaceID id) { - return biomes.get(id); - } - /** Returns the corresponding Enchantment matching the given id. Returns null if none match. */ public static Enchantment getEnchantment(String id) { return getEnchantment(NamespaceID.from(id)); diff --git a/src/generators/java/net/minestom/codegen/RegistriesGenerator.java b/src/generators/java/net/minestom/codegen/RegistriesGenerator.java index ab96c5967..78a882115 100644 --- a/src/generators/java/net/minestom/codegen/RegistriesGenerator.java +++ b/src/generators/java/net/minestom/codegen/RegistriesGenerator.java @@ -2,7 +2,6 @@ package net.minestom.codegen; import net.minestom.server.entity.EntityType; import net.minestom.server.fluids.Fluid; -import net.minestom.server.instance.Biome; import net.minestom.server.instance.block.Block; import net.minestom.server.item.Enchantment; import net.minestom.server.item.Material; @@ -31,7 +30,6 @@ public class RegistriesGenerator implements CodeGenerator { private static final String[] types = { Block.class.getCanonicalName(), Material.class.getCanonicalName(), - Biome.class.getCanonicalName(), Enchantment.class.getCanonicalName(), EntityType.class.getCanonicalName(), Particle.class.getCanonicalName(), diff --git a/src/main/java/fr/themode/demo/MainDemo.java b/src/main/java/fr/themode/demo/MainDemo.java index 5b4d1b8d5..cb7a61b9e 100644 --- a/src/main/java/fr/themode/demo/MainDemo.java +++ b/src/main/java/fr/themode/demo/MainDemo.java @@ -8,6 +8,7 @@ import net.minestom.server.instance.batch.ChunkBatch; import net.minestom.server.instance.block.Block; import net.minestom.server.network.ConnectionManager; import net.minestom.server.utils.Position; +import net.minestom.server.world.biomes.Biome; import java.util.Arrays; import java.util.List; @@ -59,7 +60,7 @@ public class MainDemo { @Override public void fillBiomes(Biome[] biomes, int chunkX, int chunkZ) { - Arrays.fill(biomes, Biome.PLAINS); + Arrays.fill(biomes, MinecraftServer.getBiomeManager().getById(0)); } @Override diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java index d5d60ed85..67c3933cc 100644 --- a/src/main/java/fr/themode/demo/PlayerInit.java +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -39,7 +39,7 @@ import java.util.UUID; public class PlayerInit { private static volatile InstanceContainer instanceContainer; - private static volatile InstanceContainer netherTest; + //private static volatile InstanceContainer netherTest; private static volatile Inventory inventory; @@ -52,22 +52,22 @@ public class PlayerInit { instanceContainer.enableAutoChunkLoad(true); instanceContainer.setChunkGenerator(noiseTestGenerator); - netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.NETHER); + /*netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.NETHER); netherTest.enableAutoChunkLoad(true); netherTest.setChunkGenerator(noiseTestGenerator); InstanceContainer end = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.END); end.enableAutoChunkLoad(true); - end.setChunkGenerator(noiseTestGenerator); + end.setChunkGenerator(noiseTestGenerator);*/ // Load some chunks beforehand - final int loopStart = -4; - final int loopEnd = 4; + final int loopStart = -10; + final int loopEnd = 10; for (int x = loopStart; x < loopEnd; x++) for (int z = loopStart; z < loopEnd; z++) { instanceContainer.loadChunk(x, z); - netherTest.loadChunk(x, z); - end.loadChunk(x, z); + //netherTest.loadChunk(x, z); + //end.loadChunk(x, z); } inventory = new Inventory(InventoryType.CHEST_1_ROW, "Test inventory"); diff --git a/src/main/java/fr/themode/demo/commands/DimensionCommand.java b/src/main/java/fr/themode/demo/commands/DimensionCommand.java index e2fa7d7a6..d21142756 100644 --- a/src/main/java/fr/themode/demo/commands/DimensionCommand.java +++ b/src/main/java/fr/themode/demo/commands/DimensionCommand.java @@ -29,10 +29,10 @@ public class DimensionCommand implements CommandProcessor { Instance instance = player.getInstance(); - DimensionType targetDimensionType = DimensionType.NETHER; - if (instance.getDimensionType() == targetDimensionType) { - targetDimensionType = DimensionType.OVERWORLD; - } + DimensionType targetDimensionType = DimensionType.OVERWORLD; + //if (instance.getDimensionType() == targetDimensionType) { + // targetDimensionType = DimensionType.OVERWORLD; + //} DimensionType finalTargetDimensionType = targetDimensionType; Optional targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimensionType() == finalTargetDimensionType).findFirst(); diff --git a/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java b/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java index 4beae2907..e8108be1c 100644 --- a/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java +++ b/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java @@ -1,6 +1,7 @@ package fr.themode.demo.generator; -import net.minestom.server.instance.Biome; +import net.minestom.server.MinecraftServer; +import net.minestom.server.world.biomes.Biome; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.ChunkGenerator; import net.minestom.server.instance.ChunkPopulator; @@ -24,7 +25,7 @@ public class ChunkGeneratorDemo extends ChunkGenerator { @Override public void fillBiomes(Biome[] biomes, int chunkX, int chunkZ) { - Arrays.fill(biomes, Biome.PLAINS); + Arrays.fill(biomes, MinecraftServer.getBiomeManager().getById(0)); } @Override diff --git a/src/main/java/fr/themode/demo/generator/NoiseTestGenerator.java b/src/main/java/fr/themode/demo/generator/NoiseTestGenerator.java index 5f27d1e8d..9272f91c5 100644 --- a/src/main/java/fr/themode/demo/generator/NoiseTestGenerator.java +++ b/src/main/java/fr/themode/demo/generator/NoiseTestGenerator.java @@ -2,7 +2,8 @@ package fr.themode.demo.generator; import de.articdive.jnoise.JNoise; import de.articdive.jnoise.interpolation.InterpolationType; -import net.minestom.server.instance.Biome; +import net.minestom.server.MinecraftServer; +import net.minestom.server.world.biomes.Biome; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.ChunkGenerator; import net.minestom.server.instance.ChunkPopulator; @@ -36,7 +37,7 @@ public class NoiseTestGenerator extends ChunkGenerator { @Override public void fillBiomes(Biome[] biomes, int chunkX, int chunkZ) { - Arrays.fill(biomes, Biome.PLAINS); + Arrays.fill(biomes, MinecraftServer.getBiomeManager().getById(0)); } @Override diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 63e1c3a2c..aa7693021 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -16,7 +16,6 @@ import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.fluids.Fluid; import net.minestom.server.gamedata.loottables.LootTableManager; import net.minestom.server.gamedata.tags.TagManager; -import net.minestom.server.instance.Biome; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockManager; @@ -45,6 +44,7 @@ import net.minestom.server.utils.thread.MinestomThread; import net.minestom.server.utils.validate.Check; import net.minestom.server.world.Difficulty; import net.minestom.server.world.DimensionTypeManager; +import net.minestom.server.world.biomes.BiomeManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,7 +56,7 @@ public class MinecraftServer { @Getter private final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class); - public static final int PROTOCOL_VERSION = 736; + public static final int PROTOCOL_VERSION = 751; // Threads public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark"; @@ -81,7 +81,7 @@ public class MinecraftServer { public static final int THREAD_COUNT_PARALLEL_CHUNK_SAVING = 4; // Config - public static final int CHUNK_VIEW_DISTANCE = 10; + public static final int CHUNK_VIEW_DISTANCE = 5; public static final int ENTITY_VIEW_DISTANCE = 5; public static final int COMPRESSION_THRESHOLD = 256; // Can be modified at performance cost when decreased @@ -112,6 +112,7 @@ public class MinecraftServer { private static SchedulerManager schedulerManager; private static BenchmarkManager benchmarkManager; private static DimensionTypeManager dimensionTypeManager; + private static BiomeManager biomeManager; private static AdvancementManager advancementManager; private static PluginManager pluginManager; @@ -149,7 +150,6 @@ public class MinecraftServer { Sound.values(); Particle.values(); StatisticType.values(); - Biome.values(); Fluid.values(); connectionManager = new ConnectionManager(); @@ -167,6 +167,7 @@ public class MinecraftServer { schedulerManager = new SchedulerManager(); benchmarkManager = new BenchmarkManager(); dimensionTypeManager = new DimensionTypeManager(); + biomeManager = new BiomeManager(); advancementManager = new AdvancementManager(); updateManager = new UpdateManager(); @@ -290,6 +291,10 @@ public class MinecraftServer { return dimensionTypeManager; } + public static BiomeManager getBiomeManager() { + return biomeManager; + } + public static AdvancementManager getAdvancementManager() { return advancementManager; } diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index ee368b5cb..e7b0dbe29 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -25,6 +25,7 @@ import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.time.CooldownUtils; import net.minestom.server.utils.time.UpdateOption; import net.minestom.server.utils.validate.Check; +import net.minestom.server.world.biomes.Biome; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; diff --git a/src/main/java/net/minestom/server/instance/ChunkGenerator.java b/src/main/java/net/minestom/server/instance/ChunkGenerator.java index a2be94412..d92944885 100644 --- a/src/main/java/net/minestom/server/instance/ChunkGenerator.java +++ b/src/main/java/net/minestom/server/instance/ChunkGenerator.java @@ -1,6 +1,7 @@ package net.minestom.server.instance; import net.minestom.server.instance.batch.ChunkBatch; +import net.minestom.server.world.biomes.Biome; import java.util.List; diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 0bf10a310..a0d32397a 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -29,6 +29,7 @@ import net.minestom.server.utils.thread.MinestomThread; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.validate.Check; import net.minestom.server.world.DimensionType; +import net.minestom.server.world.biomes.Biome; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -425,7 +426,7 @@ public class InstanceContainer extends Instance { protected void createChunk(int chunkX, int chunkZ, Consumer callback) { Biome[] biomes = new Biome[Chunk.BIOME_COUNT]; if (chunkGenerator == null) { - Arrays.fill(biomes, Biome.THE_VOID); + Arrays.fill(biomes, MinecraftServer.getBiomeManager().getById(0)); } else { chunkGenerator.fillBiomes(biomes, chunkX, chunkZ); } diff --git a/src/main/java/net/minestom/server/network/packet/client/handler/ClientPacketsHandler.java b/src/main/java/net/minestom/server/network/packet/client/handler/ClientPacketsHandler.java index a59803685..02ae57eee 100644 --- a/src/main/java/net/minestom/server/network/packet/client/handler/ClientPacketsHandler.java +++ b/src/main/java/net/minestom/server/network/packet/client/handler/ClientPacketsHandler.java @@ -7,7 +7,7 @@ import java.util.function.Supplier; public class ClientPacketsHandler { // Max packet id - private static final int SIZE = 0x2F; + private static final int SIZE = 0x30; private final Supplier[] supplierAccesses = new Supplier[SIZE]; diff --git a/src/main/java/net/minestom/server/network/packet/client/handler/ClientPlayPacketsHandler.java b/src/main/java/net/minestom/server/network/packet/client/handler/ClientPlayPacketsHandler.java index 3c4b4ea30..cf06317b0 100644 --- a/src/main/java/net/minestom/server/network/packet/client/handler/ClientPlayPacketsHandler.java +++ b/src/main/java/net/minestom/server/network/packet/client/handler/ClientPlayPacketsHandler.java @@ -33,23 +33,31 @@ public class ClientPlayPacketsHandler extends ClientPacketsHandler { register(0x1B, ClientPlayerDiggingPacket::new); register(0x1C, ClientEntityActionPacket::new); register(0x1D, ClientSteerVehiclePacket::new); - register(0x1E, ClientRecipeBookData::new); - register(0x1F, ClientNameItemPacket::new); - register(0x20, ClientResourcePackStatusPacket::new); - register(0x21, ClientAdvancementTabPacket::new); - register(0x22, ClientSelectTradePacket::new); + + + register(0x1E, ClientRecipeBookData::new); + register(0x1F, ClientRecipeBookData::new); + + + + + register(0x20, ClientNameItemPacket::new); + register(0x21, ClientResourcePackStatusPacket::new); + + register(0x22, ClientAdvancementTabPacket::new); + register(0x23, ClientSelectTradePacket::new); // Set Beacon Effect?? - register(0x24, ClientHeldItemChangePacket::new); - register(0x25, ClientUpdateCommandBlockPacket::new); - register(0x26, ClientUpdateCommandBlockMinecartPacket::new); - register(0x27, ClientCreativeInventoryActionPacket::new); + register(0x25, ClientHeldItemChangePacket::new); + register(0x26, ClientUpdateCommandBlockPacket::new); + register(0x27, ClientUpdateCommandBlockMinecartPacket::new); + register(0x28, ClientCreativeInventoryActionPacket::new); //Update Jigsaw Block?? //Update Structure Block?? - register(0x2A, ClientUpdateSignPacket::new); - register(0x2B, ClientAnimationPacket::new); + register(0x2B, ClientUpdateSignPacket::new); + register(0x2C, ClientAnimationPacket::new); //Spectate?? - register(0x2D, ClientPlayerBlockPlacementPacket::new); - register(0x2E, ClientUseItemPacket::new); + register(0x2E, ClientPlayerBlockPlacementPacket::new); + register(0x2F, ClientUseItemPacket::new); } } diff --git a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java index 9242f4f2a..708ff78af 100644 --- a/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java +++ b/src/main/java/net/minestom/server/network/packet/server/ServerPacketIdentifier.java @@ -17,51 +17,51 @@ public class ServerPacketIdentifier { public static final int BOSS_BAR = 0x0C; public static final int SERVER_DIFFICULTY = 0x0D; public static final int CHAT_MESSAGE = 0x0E; - public static final int MULTI_BLOCK_CHANGE = 0x0F; - public static final int TAB_COMPLETE = 0x10; - public static final int DECLARE_COMMANDS = 0x11; - public static final int WINDOW_CONFIRMATION = 0x12; - public static final int CLOSE_WINDOW = 0x13; - public static final int WINDOW_ITEMS = 0x14; - public static final int WINDOW_PROPERTY = 0x15; - public static final int SET_SLOT = 0x16; - public static final int SET_COOLDOWN = 0x17; - public static final int PLUGIN_MESSAGE = 0x18; - public static final int NAMED_SOUND_EFFECT = 0x19; - public static final int DISCONNECT = 0x1A; - public static final int ENTITY_STATUS = 0x1B; - public static final int EXPLOSION = 0x1C; - public static final int UNLOAD_CHUNK = 0x1D; - public static final int CHANGE_GAME_STATE = 0x1E; - public static final int OPEN_HORSE_WINDOW = 0x1F; - public static final int KEEP_ALIVE = 0x20; - public static final int CHUNK_DATA = 0x21; - public static final int EFFECT = 0x22; - public static final int PARTICLE = 0x23; - public static final int UPDATE_LIGHT = 0x24; - public static final int JOIN_GAME = 0x25; + public static final int TAB_COMPLETE = 0x0F; + public static final int DECLARE_COMMANDS = 0x10; + public static final int WINDOW_CONFIRMATION = 0x11; + public static final int CLOSE_WINDOW = 0x12; + public static final int WINDOW_ITEMS = 0x13; + public static final int WINDOW_PROPERTY = 0x14; + public static final int SET_SLOT = 0x15; + public static final int SET_COOLDOWN = 0x16; + public static final int PLUGIN_MESSAGE = 0x17; + public static final int NAMED_SOUND_EFFECT = 0x18; + public static final int DISCONNECT = 0x19; + public static final int ENTITY_STATUS = 0x1A; + public static final int EXPLOSION = 0x1B; + public static final int UNLOAD_CHUNK = 0x1C; + public static final int CHANGE_GAME_STATE = 0x1D; + public static final int OPEN_HORSE_WINDOW = 0x1E; + public static final int KEEP_ALIVE = 0x1F; + public static final int CHUNK_DATA = 0x20; + public static final int EFFECT = 0x21; + public static final int PARTICLE = 0x22; + public static final int UPDATE_LIGHT = 0x23; + public static final int JOIN_GAME = 0x24; public static final int MAP_DATA = 0x26; - public static final int TRADE_LIST = 0x27; - public static final int ENTITY_POSITION = 0x28; - public static final int ENTITY_POSITION_AND_ROTATION = 0x29; - public static final int ENTITY_ROTATION = 0x2A; - public static final int ENTITY_MOVEMENT = 0x2B; - public static final int VEHICLE_MOVE = 0x2C; - public static final int OPEN_BOOK = 0x2D; - public static final int OPEN_WINDOW = 0x2E; - public static final int OPEN_SIGN_EDITOR = 0x2F; - public static final int CRAFT_RECIPE_RESPONSE = 0x30; - public static final int PLAYER_ABILITIES = 0x31; - public static final int COMBAT_EVENT = 0x32; - public static final int PLAYER_INFO = 0x33; - public static final int FACE_PLAYER = 0x34; - public static final int PLAYER_POSITION_AND_LOOK = 0x35; - public static final int UNLOCK_RECIPES = 0x36; - public static final int DESTROY_ENTITIES = 0x37; - public static final int REMOVE_ENTITY_EFFECT = 0x38; - public static final int RESOURCE_PACK_SEND = 0x39; - public static final int RESPAWN = 0x3A; - public static final int ENTITY_HEAD_LOOK = 0x3B; + public static final int TRADE_LIST = 0x26; + public static final int ENTITY_POSITION = 0x27; + public static final int ENTITY_POSITION_AND_ROTATION = 0x28; + public static final int ENTITY_ROTATION = 0x29; + public static final int ENTITY_MOVEMENT = 0x2A; + public static final int VEHICLE_MOVE = 0x2B; + public static final int OPEN_BOOK = 0x2C; + public static final int OPEN_WINDOW = 0x2D; + public static final int OPEN_SIGN_EDITOR = 0x2E; + public static final int CRAFT_RECIPE_RESPONSE = 0x2F; + public static final int PLAYER_ABILITIES = 0x30; + public static final int COMBAT_EVENT = 0x31; + public static final int PLAYER_INFO = 0x32; + public static final int FACE_PLAYER = 0x33; + public static final int PLAYER_POSITION_AND_LOOK = 0x34; + public static final int UNLOCK_RECIPES = 0x35; + public static final int DESTROY_ENTITIES = 0x36; + public static final int REMOVE_ENTITY_EFFECT = 0x37; + public static final int RESOURCE_PACK_SEND = 0x38; + public static final int RESPAWN = 0x39; + public static final int ENTITY_HEAD_LOOK = 0x3A; + public static final int MULTI_BLOCK_CHANGE = 0x3B; public static final int SELECT_ADVANCEMENT_TAB = 0x3C; public static final int WORLD_BORDER = 0x3D; public static final int CAMERA = 0x3E; diff --git a/src/main/java/net/minestom/server/network/packet/server/login/JoinGamePacket.java b/src/main/java/net/minestom/server/network/packet/server/login/JoinGamePacket.java index 3885f5899..874f02b7f 100644 --- a/src/main/java/net/minestom/server/network/packet/server/login/JoinGamePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/login/JoinGamePacket.java @@ -8,13 +8,12 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.world.DimensionType; import net.minestom.server.world.LevelType; import org.jglrxavpok.hephaistos.nbt.NBTCompound; -import org.jglrxavpok.hephaistos.nbt.NBTList; -import org.jglrxavpok.hephaistos.nbt.NBTTypes; public class JoinGamePacket implements ServerPacket { public int entityId; public GameMode gameMode = GameMode.SURVIVAL; + //Todo implement public DimensionType dimensionType = DimensionType.OVERWORLD; public long hashedSeed; public byte maxPlayers = 0; // Unused @@ -33,24 +32,28 @@ public class JoinGamePacket implements ServerPacket { gameModeId |= 8; writer.writeInt(entityId); + //hardcore + writer.writeBoolean(false); writer.writeByte((byte) gameModeId); //Previous Gamemode writer.writeByte((byte) gameModeId); //array of worlds writer.writeVarInt(1); - writer.writeSizedString("test:spawn_name"); + writer.writeSizedString("minestom:world"); + NBTCompound nbt = new NBTCompound(); + NBTCompound dimensions = MinecraftServer.getDimensionTypeManager().toNBT(); + NBTCompound biomes = MinecraftServer.getBiomeManager().toNBT(); - NBTList dimensionList = new NBTList<>(NBTTypes.TAG_Compound); - for(DimensionType type : MinecraftServer.getDimensionTypeManager().unmodifiableList()) { - dimensionList.add(type.toNBT()); - } - writer.writeNBT("", new NBTCompound().set("dimension", dimensionList)); + nbt.set("minecraft:dimension_type", dimensions); + nbt.set("minecraft:worldgen/biome", biomes); + + writer.writeNBT("", nbt); + writer.writeNBT("", dimensionType.toNBT2()); writer.writeSizedString(dimensionType.getName().toString()); - writer.writeSizedString(identifier+"_"+ dimensionType.getName().getPath()); writer.writeLong(hashedSeed); - writer.writeByte(maxPlayers); + writer.writeVarInt(maxPlayers); writer.writeVarInt(viewDistance); writer.writeBoolean(reducedDebugInfo); writer.writeBoolean(enableRespawnScreen); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java index 774713213..96fa905cb 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ChunkDataPacket.java @@ -3,7 +3,7 @@ package net.minestom.server.network.packet.server.play; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; -import net.minestom.server.instance.Biome; +import net.minestom.server.world.biomes.Biome; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.block.BlockManager; import net.minestom.server.instance.block.CustomBlock; @@ -89,7 +89,7 @@ public class ChunkDataPacket implements ServerPacket { // Biome data if (fullChunk) { for (int i = 0; i < biomes.length; i++) { - writer.writeInt(biomes[i].getId()); + writer.writeVarInt(biomes[i].getId()); } } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/MultiBlockChangePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/MultiBlockChangePacket.java index ce934510a..0c3f6e854 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/MultiBlockChangePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/MultiBlockChangePacket.java @@ -3,7 +3,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.PacketWriter; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.utils.chunk.ChunkUtils; +//todo public class MultiBlockChangePacket implements ServerPacket { public int chunkX; @@ -12,8 +14,7 @@ public class MultiBlockChangePacket implements ServerPacket { @Override public void write(PacketWriter writer) { - writer.writeInt(chunkX); - writer.writeInt(chunkZ); + writer.writeLong(ChunkUtils.getChunkIndex(chunkX, chunkZ)); if (blockChanges != null) { int length = blockChanges.length; diff --git a/src/main/java/net/minestom/server/reader/ChunkReader.java b/src/main/java/net/minestom/server/reader/ChunkReader.java index 38d10cd5b..7a6888687 100644 --- a/src/main/java/net/minestom/server/reader/ChunkReader.java +++ b/src/main/java/net/minestom/server/reader/ChunkReader.java @@ -1,8 +1,9 @@ package net.minestom.server.reader; import io.netty.buffer.Unpooled; +import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; -import net.minestom.server.instance.Biome; +import net.minestom.server.world.biomes.Biome; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.batch.ChunkBatch; @@ -23,7 +24,7 @@ public class ChunkReader { Biome[] biomes = new Biome[Chunk.BIOME_COUNT]; for (int i = 0; i < biomes.length; i++) { - biomes[i] = Biome.fromId(stream.readByte()); + biomes[i] = MinecraftServer.getBiomeManager().getById(stream.readByte()); } final Chunk chunk = new Chunk(biomes, chunkX, chunkZ); diff --git a/src/main/java/net/minestom/server/world/DimensionType.java b/src/main/java/net/minestom/server/world/DimensionType.java index 62639aef4..37e198a93 100644 --- a/src/main/java/net/minestom/server/world/DimensionType.java +++ b/src/main/java/net/minestom/server/world/DimensionType.java @@ -7,6 +7,7 @@ import net.minestom.server.utils.NamespaceID; import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; /** * https://minecraft.gamepedia.com/Custom_dimension @@ -15,96 +16,96 @@ import java.util.Optional; @Builder(builderMethodName = "hiddenBuilder", access = AccessLevel.PRIVATE) public class DimensionType { - public static final DimensionType OVERWORLD = DimensionType.builder(NamespaceID.from("minecraft:overworld")) - .ultrawarm(false) - .natural(true) - .shrunk(false) - .piglinSafe(false) - .respawnAnchorSafe(false) - .bedSafe(true) - .raidCapable(true) - .skylightEnabled(true) - .ceilingEnabled(false) - .fixedTime(Optional.empty()) - .ambientLight(0.0f) - .logicalHeight(256) - .infiniburn(NamespaceID.from("minecraft:infiniburn_overworld")) - .build(); + private static final AtomicInteger idCounter = new AtomicInteger(0); - public static final DimensionType NETHER = DimensionType.builder(NamespaceID.from("minecraft:the_nether")) - .ultrawarm(true) - .natural(false) - .shrunk(true) - .piglinSafe(true) - .respawnAnchorSafe(true) - .bedSafe(false) - .raidCapable(false) - .skylightEnabled(false) - .ceilingEnabled(true) - .fixedTime(Optional.of(18000L)) - .ambientLight(0.1f) - .logicalHeight(128) - .infiniburn(NamespaceID.from("minecraft:infiniburn_nether")) - .build(); + public static final DimensionType OVERWORLD = DimensionType.builder(NamespaceID.from("minecraft:overworld")) + .ultrawarm(false) + .natural(true) + .shrunk(false) + .piglinSafe(false) + .respawnAnchorSafe(false) + .bedSafe(true) + .raidCapable(true) + .skylightEnabled(true) + .ceilingEnabled(false) + .fixedTime(Optional.empty()) + .ambientLight(0.0f) + .logicalHeight(256) + .infiniburn(NamespaceID.from("minecraft:infiniburn_overworld")) + .build(); - public static final DimensionType END = DimensionType.builder(NamespaceID.from("minecraft:the_end")) - .ultrawarm(false) - .natural(false) - .shrunk(false) - .piglinSafe(false) - .respawnAnchorSafe(false) - .bedSafe(false) - .raidCapable(true) - .skylightEnabled(false) - .ceilingEnabled(false) - .fixedTime(Optional.of(6000L)) - .ambientLight(0.0f) - .logicalHeight(256) - .infiniburn(NamespaceID.from("minecraft:infiniburn_end")) - .build(); + private final int id = idCounter.getAndIncrement(); + private final NamespaceID name; + private final boolean natural; + private final float ambientLight; + private final boolean ceilingEnabled; + private final boolean skylightEnabled; + @Builder.Default + private final Optional fixedTime = Optional.empty(); + private final boolean shrunk; + private final boolean raidCapable; + private final boolean respawnAnchorSafe; + private final boolean ultrawarm; + @Builder.Default + private final boolean bedSafe = true; + private final boolean piglinSafe; + @Builder.Default + private final int logicalHeight = 256; + @Builder.Default + private final int coordinateScale = 1; + @Builder.Default + private final NamespaceID infiniburn = NamespaceID.from("minecraft:infiniburn_overworld"); - private final NamespaceID name; - private final boolean natural; - private final float ambientLight; - private final boolean ceilingEnabled; - private final boolean skylightEnabled; - @Builder.Default private final Optional fixedTime = Optional.empty(); - private final boolean shrunk; - private final boolean raidCapable; - private final boolean respawnAnchorSafe; - private final boolean ultrawarm; - @Builder.Default private final boolean bedSafe = true; - private final boolean piglinSafe; - @Builder.Default private final int logicalHeight = 256; - @Builder.Default private final NamespaceID infiniburn = NamespaceID.from("minecraft:infiniburn_overworld"); + public static DimensionTypeBuilder builder(NamespaceID name) { + return hiddenBuilder().name(name); + } - public NBTCompound toNBT() { - NBTCompound nbt = new NBTCompound() - .setString("name", name.toString()) - .setFloat("ambient_light", ambientLight) - .setString("infiniburn", infiniburn.toString()) - .setByte("natural", (byte) (natural ? 0x01 : 0x00)) - .setByte("has_ceiling", (byte) (ceilingEnabled ? 0x01 : 0x00)) - .setByte("has_skylight", (byte) (skylightEnabled ? 0x01 : 0x00)) - .setByte("shrunk", (byte) (shrunk ? 0x01 : 0x00)) - .setByte("ultrawarm", (byte) (ultrawarm ? 0x01 : 0x00)) - .setByte("has_raids", (byte) (raidCapable ? 0x01 : 0x00)) - .setByte("respawn_anchor_works", (byte) (respawnAnchorSafe ? 0x01 : 0x00)) - .setByte("bed_works", (byte) (bedSafe ? 0x01 : 0x00)) - .setByte("piglin_safe", (byte) (piglinSafe ? 0x01 : 0x00)) - .setInt("logical_height", logicalHeight) - ; - fixedTime.ifPresent(time -> nbt.setLong("fixed_time", time)); - return nbt; - } + public NBTCompound toNBT() { + NBTCompound nbt = new NBTCompound(); + NBTCompound element = new NBTCompound() + .setFloat("ambient_light", ambientLight) + .setString("infiniburn", infiniburn.toString()) + .setByte("natural", (byte) (natural ? 0x01 : 0x00)) + .setByte("has_ceiling", (byte) (ceilingEnabled ? 0x01 : 0x00)) + .setByte("has_skylight", (byte) (skylightEnabled ? 0x01 : 0x00)) + .setByte("shrunk", (byte) (shrunk ? 0x01 : 0x00)) + .setByte("ultrawarm", (byte) (ultrawarm ? 0x01 : 0x00)) + .setByte("has_raids", (byte) (raidCapable ? 0x01 : 0x00)) + .setByte("respawn_anchor_works", (byte) (respawnAnchorSafe ? 0x01 : 0x00)) + .setByte("bed_works", (byte) (bedSafe ? 0x01 : 0x00)) + .setByte("piglin_safe", (byte) (piglinSafe ? 0x01 : 0x00)) + .setInt("logical_height", logicalHeight) + .setInt("coordinate_scale", coordinateScale); + fixedTime.ifPresent(time -> element.setLong("fixed_time", time)); + nbt.setString("name", name.toString()); + nbt.setInt("id", id); + nbt.set("element", element); + return nbt; + } - @Override - public String toString() { - return name.toString(); - } + public NBTCompound toNBT2() { + NBTCompound nbt = new NBTCompound() + .setFloat("ambient_light", ambientLight) + .setString("infiniburn", infiniburn.toString()) + .setByte("natural", (byte) (natural ? 0x01 : 0x00)) + .setByte("has_ceiling", (byte) (ceilingEnabled ? 0x01 : 0x00)) + .setByte("has_skylight", (byte) (skylightEnabled ? 0x01 : 0x00)) + .setByte("shrunk", (byte) (shrunk ? 0x01 : 0x00)) + .setByte("ultrawarm", (byte) (ultrawarm ? 0x01 : 0x00)) + .setByte("has_raids", (byte) (raidCapable ? 0x01 : 0x00)) + .setByte("respawn_anchor_works", (byte) (respawnAnchorSafe ? 0x01 : 0x00)) + .setByte("bed_works", (byte) (bedSafe ? 0x01 : 0x00)) + .setByte("piglin_safe", (byte) (piglinSafe ? 0x01 : 0x00)) + .setInt("logical_height", logicalHeight) + .setInt("coordinate_scale", coordinateScale) + .setString("name", name.toString()); + fixedTime.ifPresent(time -> nbt.setLong("fixed_time", time)); + return nbt; + } - public static DimensionTypeBuilder builder(NamespaceID name) { - return hiddenBuilder().name(name); - } + @Override + public String toString() { + return name.toString(); + } } diff --git a/src/main/java/net/minestom/server/world/DimensionTypeManager.java b/src/main/java/net/minestom/server/world/DimensionTypeManager.java index 746ecfc8e..768a68db8 100644 --- a/src/main/java/net/minestom/server/world/DimensionTypeManager.java +++ b/src/main/java/net/minestom/server/world/DimensionTypeManager.java @@ -1,5 +1,9 @@ package net.minestom.server.world; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTList; +import org.jglrxavpok.hephaistos.nbt.NBTTypes; + import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -7,7 +11,7 @@ import java.util.List; /** * Allows servers to register custom dimensions. Also used during player joining to send the list of all existing dimensions. * - * Contains {@link DimensionType#OVERWORLD}, {@link DimensionType#NETHER}, {@link DimensionType#END} by default but can be removed. + * Contains {@link DimensionType#OVERWORLD} by default but can be removed. */ public class DimensionTypeManager { @@ -15,8 +19,6 @@ public class DimensionTypeManager { public DimensionTypeManager() { addDimension(DimensionType.OVERWORLD); - addDimension(DimensionType.NETHER); - addDimension(DimensionType.END); } /** @@ -44,4 +46,16 @@ public class DimensionTypeManager { return Collections.unmodifiableList(dimensionTypes); } + + + public NBTCompound toNBT() { + NBTCompound dimensions = new NBTCompound(); + dimensions.setString("type", "minecraft:dimension_type"); + NBTList dimensionList = new NBTList<>(NBTTypes.TAG_Compound); + for (DimensionType dimensionType : dimensionTypes) { + dimensionList.add(dimensionType.toNBT()); + } + dimensions.set("value", dimensionList); + return dimensions; + } } diff --git a/src/main/java/net/minestom/server/world/biomes/Biome.java b/src/main/java/net/minestom/server/world/biomes/Biome.java new file mode 100644 index 000000000..d043d7fd5 --- /dev/null +++ b/src/main/java/net/minestom/server/world/biomes/Biome.java @@ -0,0 +1,98 @@ +package net.minestom.server.world.biomes; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import net.minestom.server.utils.NamespaceID; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.concurrent.atomic.AtomicInteger; + +@Getter +@Builder +@ToString +@EqualsAndHashCode +public class Biome { + + private static final AtomicInteger idCounter = new AtomicInteger(0); + + public static final Biome EXAMPLE = Biome.builder() + .category(Biome.Category.NONE) + .name(NamespaceID.from("minecraft:plains")) + .effects(BiomeEffects.builder() + .fog_color(0x34e38c) + .sky_color(0xdae334) + .water_color(0x349ae3) + .water_fog_color(0x3460e3) + .build()) + .build(); + + private final int id = idCounter.getAndIncrement(); + + private final NamespaceID name; + @Builder.Default private final float depth = 0.2F; + @Builder.Default private final float temperature = 0.25F; + @Builder.Default private final float scale = 0.2F; + @Builder.Default private final float downfall = 0.8F; + @Builder.Default private final Category category = Category.NONE; + private final BiomeEffects effects; + @Builder.Default private final Precipitation precipitation = Precipitation.RAIN; + @Builder.Default + private TemperatureModifier temperature_modifier = TemperatureModifier.NONE; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setString("name", name.toString()); + nbt.setInt("id", id); + + NBTCompound element = new NBTCompound(); + element.setFloat("depth", depth); + element.setFloat("temperature", temperature); + element.setFloat("scale", scale); + element.setFloat("downfall", downfall); + element.setString("category", category.getType()); + element.setString("precipitation", precipitation.getType()); + if (temperature_modifier != TemperatureModifier.NONE) + element.setString("temperature_modifier", temperature_modifier.getType()); + element.set("effects", effects.toNbt()); + nbt.set("element", element); + return nbt; + } + + public enum Precipitation { + RAIN("rain"), NONE("none"), SNOW("snow"); + + @Getter + String type; + + Precipitation(String type) { + this.type = type; + } + } + + public enum Category { + NONE("none"), TAIGA("taiga"), EXTREME_HILLS("extreme_hills"), JUNGLE("jungle"), MESA("mesa"), PLAINS("plains"), + SAVANNA("savanna"), ICY("icy"), THE_END("the_end"), BEACH("beach"), FOREST("forest"), OCEAN("ocean"), + DESERT("desert"), RIVER("river"), SWAMP("swamp"), MUSHROOM("mushroom"), NETHER("nether"); + + @Getter + String type; + + Category(String type) { + this.type = type; + } + } + + public enum TemperatureModifier { + NONE("none"), FROZEN("frozen"); + + @Getter + String type; + + TemperatureModifier(String type) { + this.type = type; + } + } + +} diff --git a/src/main/java/net/minestom/server/world/biomes/BiomeEffects.java b/src/main/java/net/minestom/server/world/biomes/BiomeEffects.java new file mode 100644 index 000000000..46796c92c --- /dev/null +++ b/src/main/java/net/minestom/server/world/biomes/BiomeEffects.java @@ -0,0 +1,127 @@ +package net.minestom.server.world.biomes; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import net.minestom.server.utils.NamespaceID; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +@Getter +@Builder +@ToString +@EqualsAndHashCode +public class BiomeEffects { + + private final int fog_color; + private final int sky_color; + private final int water_color; + private final int water_fog_color; + @Builder.Default private int foliage_color = -1; + @Builder.Default private int grass_color = -1; + @Builder.Default private GrassColorModifier grass_color_modifier = null; + @Builder.Default private BiomeParticles biomeParticles = null; + @Builder.Default private NamespaceID ambient_sound = null; + @Builder.Default private MoodSound mood_sound = null; + @Builder.Default private AdditionsSound additions_sound = null; + @Builder.Default private Music music = null; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setInt("fog_color", fog_color); + if (foliage_color != -1) + nbt.setInt("foliage_color", foliage_color); + if (grass_color != -1) + nbt.setInt("grass_color", grass_color); + nbt.setInt("sky_color", sky_color); + nbt.setInt("water_color", water_color); + nbt.setInt("water_fog_color", water_fog_color); + if (grass_color_modifier != null) + nbt.setString("grass_color_modifier", grass_color_modifier.getType()); + if (biomeParticles != null) + nbt.set("particle", biomeParticles.toNbt()); + if (ambient_sound != null) + nbt.setString("ambient_sound", ambient_sound.toString()); + if (mood_sound != null) + nbt.set("mood_sound", mood_sound.toNbt()); + if (additions_sound != null) + nbt.set("additions_sound", additions_sound.toNbt()); + if (music != null) + nbt.set("music", music.toNbt()); + return nbt; + } + + public enum GrassColorModifier { + NONE("none"), DARK_FOREST("dark_forest"), SWAMP("swamp"); + + @Getter + String type; + + GrassColorModifier(String type) { + this.type = type; + } + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class MoodSound { + + private final NamespaceID sound; + private final int tick_delay; + private final int block_search_extent; + private final double offset; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setString("sound", sound.toString()); + nbt.setInt("tick_delay", tick_delay); + nbt.setInt("block_search_extent", block_search_extent); + nbt.setDouble("offset", offset); + return nbt; + } + + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class AdditionsSound { + + private final NamespaceID sound; + private final double tick_chance; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setString("sound", sound.toString()); + nbt.setDouble("tick_chance", tick_chance); + return nbt; + } + + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class Music { + + private final NamespaceID sound; + private final int min_delay; + private final int max_delay; + private final boolean replace_current_music; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setString("sound", sound.toString()); + nbt.setInt("min_delay", min_delay); + nbt.setInt("max_delay", max_delay); + nbt.setByte("replace_current_music", replace_current_music ? (byte) 1 : (byte) 0); + return nbt; + } + + } + +} diff --git a/src/main/java/net/minestom/server/world/biomes/BiomeManager.java b/src/main/java/net/minestom/server/world/biomes/BiomeManager.java new file mode 100644 index 000000000..dfa392ec5 --- /dev/null +++ b/src/main/java/net/minestom/server/world/biomes/BiomeManager.java @@ -0,0 +1,82 @@ +package net.minestom.server.world.biomes; + +import net.minestom.server.utils.NamespaceID; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTList; +import org.jglrxavpok.hephaistos.nbt.NBTTypes; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Allows servers to register custom dimensions. Also used during player joining to send the list of all existing dimensions. + * + * Contains {@link Biome#EXAMPLE} by default but can be removed. + */ +public class BiomeManager { + + private List biomes = new LinkedList<>(); + + public BiomeManager() { + addBiome(Biome.EXAMPLE); + } + + /** + * Add a new biome. This does NOT send the new list to players. + * @param biome + */ + public void addBiome(Biome biome) { + biomes.add(biome); + } + + /** + * Removes a biome. This does NOT send the new list to players. + * @param biome + * @return if the biome type was removed, false if it was not present before + */ + public boolean removeBiome(Biome biome) { + return biomes.remove(biome); + } + + /** + * Returns an immutable copy of the biomes already registered + * @return + */ + public List unmodifiableList() { + return Collections.unmodifiableList(biomes); + } + + public Biome getById(int id) { + Biome biome = null; + for (final Biome biomeT : biomes) { + if (biomeT.getId() == id) { + biome = biomeT; + break; + } + } + return biome; + } + + public Biome getByName(NamespaceID namespaceID) { + Biome biome = null; + for (final Biome biomeT : biomes) { + if (biomeT.getName().equals(namespaceID)) { + biome = biomeT; + break; + } + } + return biome; + } + + public NBTCompound toNBT() { + NBTCompound biomes = new NBTCompound(); + biomes.setString("type", "minecraft:worldgen/biome"); + NBTList biomesList = new NBTList<>(NBTTypes.TAG_Compound); + for (Biome biome : this.biomes) { + biomesList.add(biome.toNbt()); + } + biomes.set("value", biomesList); + return biomes; + } +} diff --git a/src/main/java/net/minestom/server/world/biomes/BiomeParticles.java b/src/main/java/net/minestom/server/world/biomes/BiomeParticles.java new file mode 100644 index 000000000..a08de2f64 --- /dev/null +++ b/src/main/java/net/minestom/server/world/biomes/BiomeParticles.java @@ -0,0 +1,122 @@ +package net.minestom.server.world.biomes; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockAlternative; +import net.minestom.server.item.ItemStack; +import net.minestom.server.utils.NamespaceID; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; + +import java.util.Map; + +@Getter +@Builder +@ToString +@EqualsAndHashCode +public class BiomeParticles { + + private final float probability; + private final ParticleOptions options; + + public NBTCompound toNbt() { + NBTCompound nbt = new NBTCompound(); + nbt.setFloat("probability", probability); + nbt.set("options", options.toNbt()); + return nbt; + } + + public interface ParticleOptions { + NBTCompound toNbt(); + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class BlockParticle implements ParticleOptions { + + //TODO also can be falling_dust + private static final String type = "block"; + private final BlockAlternative block; + + @Override + public NBTCompound toNbt() { + NBTCompound nbtCompound = new NBTCompound(); + Block block1 = Block.fromStateId(block.getId()); + nbtCompound.setString("type", type); + nbtCompound.setString("Name", block1.getName()); + Map propertiesMap = block.createPropertiesMap(); + if (propertiesMap.size() != 0) { + NBTCompound properties = new NBTCompound(); + propertiesMap.forEach(properties::setString); + nbtCompound.set("Properties", properties); + } + return nbtCompound; + } + + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class DustParticle implements ParticleOptions { + + private static final String type = "dust"; + private final float red; + private final float green; + private final float blue; + private final float scale; + + @Override + public NBTCompound toNbt() { + NBTCompound nbtCompound = new NBTCompound(); + nbtCompound.setString("type", type); + nbtCompound.setFloat("r", red); + nbtCompound.setFloat("g", green); + nbtCompound.setFloat("b", blue); + nbtCompound.setFloat("scale", scale); + return nbtCompound; + } + + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class ItemParticle implements ParticleOptions { + + private static final String type = "item"; + private final ItemStack item; + + @Override + public NBTCompound toNbt() { + //todo test count might be wrong type + NBTCompound nbtCompound = item.toNBT(); + nbtCompound.setString("type", type); + return nbtCompound; + } + + } + + @Getter + @Builder + @ToString + @EqualsAndHashCode + public static class NormalParticle implements ParticleOptions { + + private final NamespaceID type; + + @Override + public NBTCompound toNbt() { + NBTCompound nbtCompound = new NBTCompound(); + nbtCompound.setString("type", type.toString()); + return nbtCompound; + } + + } +}