From 30019ebe9a4adeb629303652cdff6b163463e66a Mon Sep 17 00:00:00 2001 From: jglrxavpok Date: Mon, 13 Jul 2020 14:12:21 +0200 Subject: [PATCH] Customizable dimension list in JoinGamePacket + Dimension->DimensionType --- prismarine-minecraft-data | 2 +- src/main/java/fr/themode/demo/PlayerInit.java | 8 ++-- .../demo/commands/DimensionCommand.java | 18 +++---- .../net/minestom/server/MinecraftServer.java | 7 +++ .../net/minestom/server/entity/Player.java | 34 +++++++------- .../minestom/server/instance/Instance.java | 12 ++--- .../server/instance/InstanceContainer.java | 6 +-- .../server/instance/InstanceManager.java | 14 +++--- .../server/instance/SharedInstance.java | 2 +- .../packet/server/login/JoinGamePacket.java | 16 +++---- .../packet/server/play/RespawnPacket.java | 8 ++-- .../{Dimension.java => DimensionType.java} | 10 ++-- .../server/world/DimensionTypeManager.java | 47 +++++++++++++++++++ 13 files changed, 119 insertions(+), 65 deletions(-) rename src/main/java/net/minestom/server/world/{Dimension.java => DimensionType.java} (89%) create mode 100644 src/main/java/net/minestom/server/world/DimensionTypeManager.java diff --git a/prismarine-minecraft-data b/prismarine-minecraft-data index 6e5241db3..a637148b6 160000 --- a/prismarine-minecraft-data +++ b/prismarine-minecraft-data @@ -1 +1 @@ -Subproject commit 6e5241db3b4546242d2056b27691e9f7c11dc2d5 +Subproject commit a637148b634ee3f1ae839f93eadc90b4274b8c5b diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java index 673fd8772..90239e3da 100644 --- a/src/main/java/fr/themode/demo/PlayerInit.java +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -38,7 +38,7 @@ import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.UpdateOption; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import java.util.Map; import java.util.UUID; @@ -54,15 +54,15 @@ public class PlayerInit { ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator(); //instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder); - instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(Dimension.OVERWORLD); + instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD); instanceContainer.enableAutoChunkLoad(true); instanceContainer.setChunkGenerator(noiseTestGenerator); - netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(Dimension.NETHER); + netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.NETHER); netherTest.enableAutoChunkLoad(true); netherTest.setChunkGenerator(noiseTestGenerator); - InstanceContainer end = MinecraftServer.getInstanceManager().createInstanceContainer(Dimension.END); + InstanceContainer end = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.END); end.enableAutoChunkLoad(true); end.setChunkGenerator(noiseTestGenerator); diff --git a/src/main/java/fr/themode/demo/commands/DimensionCommand.java b/src/main/java/fr/themode/demo/commands/DimensionCommand.java index ec179c58a..e2fa7d7a6 100644 --- a/src/main/java/fr/themode/demo/commands/DimensionCommand.java +++ b/src/main/java/fr/themode/demo/commands/DimensionCommand.java @@ -5,7 +5,7 @@ import net.minestom.server.command.CommandProcessor; import net.minestom.server.command.CommandSender; import net.minestom.server.entity.Player; import net.minestom.server.instance.Instance; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import java.util.Optional; @@ -29,19 +29,19 @@ public class DimensionCommand implements CommandProcessor { Instance instance = player.getInstance(); - Dimension targetDimension = Dimension.NETHER; - if (instance.getDimension() == targetDimension) { - targetDimension = Dimension.OVERWORLD; + DimensionType targetDimensionType = DimensionType.NETHER; + if (instance.getDimensionType() == targetDimensionType) { + targetDimensionType = DimensionType.OVERWORLD; } - Dimension finalTargetDimension = targetDimension; - Optional targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimension() == finalTargetDimension).findFirst(); + DimensionType finalTargetDimensionType = targetDimensionType; + Optional targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimensionType() == finalTargetDimensionType).findFirst(); if (targetInstance.isPresent()) { - player.sendMessage("You were in " + instance.getDimension()); + player.sendMessage("You were in " + instance.getDimensionType()); player.setInstance(targetInstance.get()); - player.sendMessage("You are now in " + targetDimension); + player.sendMessage("You are now in " + targetDimensionType); } else { - player.sendMessage("Could not find instance with dimension " + targetDimension); + player.sendMessage("Could not find instance with dimension " + targetDimensionType); } return true; diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index f4cbd9ec3..9f7507a2e 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -42,6 +42,7 @@ import net.minestom.server.timer.SchedulerManager; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,6 +109,7 @@ public class MinecraftServer { private static TeamManager teamManager; private static SchedulerManager schedulerManager; private static BenchmarkManager benchmarkManager; + private static DimensionTypeManager dimensionTypeManager; private static UpdateManager updateManager; private static MinecraftServer minecraftServer; @@ -157,6 +159,7 @@ public class MinecraftServer { teamManager = new TeamManager(); schedulerManager = new SchedulerManager(); benchmarkManager = new BenchmarkManager(); + dimensionTypeManager = new DimensionTypeManager(); updateManager = new UpdateManager(); @@ -273,6 +276,10 @@ public class MinecraftServer { return lootTableManager; } + public static DimensionTypeManager getDimensionTypeManager() { + return dimensionTypeManager; + } + public static TagManager getTagManager() { return tagManager; } diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 21cb1f126..9d4f25b21 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -45,7 +45,7 @@ import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.Position; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.validate.Check; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import net.minestom.server.world.LevelType; import java.util.*; @@ -67,7 +67,7 @@ public class Player extends LivingEntity implements CommandSender { private ColoredText displayName; private PlayerSkin skin; - private Dimension dimension; + private DimensionType dimensionType; private GameMode gameMode; private LevelType levelType; private int teleportId = 0; @@ -157,7 +157,7 @@ public class Player extends LivingEntity implements CommandSender { refreshAnswerKeepAlive(true); this.gameMode = GameMode.SURVIVAL; - this.dimension = Dimension.OVERWORLD; + this.dimensionType = DimensionType.OVERWORLD; this.levelType = LevelType.FLAT; refreshPosition(0, 0, 0); @@ -175,7 +175,7 @@ public class Player extends LivingEntity implements CommandSender { JoinGamePacket joinGamePacket = new JoinGamePacket(); joinGamePacket.entityId = getEntityId(); joinGamePacket.gameMode = gameMode; - joinGamePacket.dimension = dimension; + joinGamePacket.dimensionType = dimensionType; joinGamePacket.maxPlayers = 0; // Unused joinGamePacket.levelType = levelType; joinGamePacket.viewDistance = MinecraftServer.CHUNK_VIEW_DISTANCE; @@ -464,7 +464,7 @@ public class Player extends LivingEntity implements CommandSender { setOnFire(false); refreshHealth(); RespawnPacket respawnPacket = new RespawnPacket(); - respawnPacket.dimension = getDimension(); + respawnPacket.dimensionType = getDimensionType(); respawnPacket.gameMode = getGameMode(); respawnPacket.levelType = getLevelType(); getPlayerConnection().sendPacket(respawnPacket); @@ -544,9 +544,9 @@ public class Player extends LivingEntity implements CommandSender { viewableChunks.clear(); if (this.instance != null) { - Dimension instanceDimension = instance.getDimension(); - if (dimension != instanceDimension) - sendDimension(instanceDimension); + DimensionType instanceDimensionType = instance.getDimensionType(); + if (dimensionType != instanceDimensionType) + sendDimension(instanceDimensionType); } long[] visibleChunks = ChunkUtils.getChunksInRange(position, getChunkRange()); @@ -912,7 +912,7 @@ public class Player extends LivingEntity implements CommandSender { PlayerInfoPacket addPlayerPacket = getAddPlayerToList(); RespawnPacket respawnPacket = new RespawnPacket(); - respawnPacket.dimension = getDimension(); + respawnPacket.dimensionType = getDimensionType(); respawnPacket.gameMode = getGameMode(); respawnPacket.levelType = getLevelType(); @@ -1242,8 +1242,8 @@ public class Player extends LivingEntity implements CommandSender { * * @return the player current dimension */ - public Dimension getDimension() { - return dimension; + public DimensionType getDimensionType() { + return dimensionType; } public PlayerInventory getInventory() { @@ -1297,15 +1297,15 @@ public class Player extends LivingEntity implements CommandSender { * Change the dimension of the player * Mostly unsafe since it requires sending chunks after * - * @param dimension the new player dimension + * @param dimensionType the new player dimension */ - public void sendDimension(Dimension dimension) { - Check.notNull(dimension, "Dimension cannot be null!"); - Check.argCondition(dimension.equals(getDimension()), "The dimension need to be different than the current one!"); + public void sendDimension(DimensionType dimensionType) { + Check.notNull(dimensionType, "Dimension cannot be null!"); + Check.argCondition(dimensionType.equals(getDimensionType()), "The dimension need to be different than the current one!"); - this.dimension = dimension; + this.dimensionType = dimensionType; RespawnPacket respawnPacket = new RespawnPacket(); - respawnPacket.dimension = dimension; + respawnPacket.dimensionType = dimensionType; respawnPacket.gameMode = gameMode; respawnPacket.levelType = levelType; playerConnection.sendPacket(respawnPacket); diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index ba5c4bc2f..e9aa211e8 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -25,7 +25,7 @@ import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.player.PlayerUtils; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.validate.Check; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -37,7 +37,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); - private Dimension dimension; + private DimensionType dimensionType; private WorldBorder worldBorder; @@ -57,9 +57,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta private Data data; private ExplosionSupplier explosionSupplier; - public Instance(UUID uniqueId, Dimension dimension) { + public Instance(UUID uniqueId, DimensionType dimensionType) { this.uniqueId = uniqueId; - this.dimension = dimension; + this.dimensionType = dimensionType; this.worldBorder = new WorldBorder(this); } @@ -265,8 +265,8 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta * * @return the dimension of the instance */ - public Dimension getDimension() { - return dimension; + public DimensionType getDimensionType() { + return dimensionType; } /** diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 3cdd77c08..c25358848 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -30,7 +30,7 @@ import net.minestom.server.utils.thread.MinestomThread; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.time.UpdateOption; import net.minestom.server.utils.validate.Check; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -62,8 +62,8 @@ public class InstanceContainer extends Instance { private boolean autoChunkLoad; - public InstanceContainer(UUID uniqueId, Dimension dimension, StorageFolder storageFolder) { - super(uniqueId, dimension); + public InstanceContainer(UUID uniqueId, DimensionType dimensionType, StorageFolder storageFolder) { + super(uniqueId, dimensionType); this.storageFolder = storageFolder; chunkLoader = new MinestomBasicChunkLoader(storageFolder); diff --git a/src/main/java/net/minestom/server/instance/InstanceManager.java b/src/main/java/net/minestom/server/instance/InstanceManager.java index c2d8ee596..4bfe12450 100644 --- a/src/main/java/net/minestom/server/instance/InstanceManager.java +++ b/src/main/java/net/minestom/server/instance/InstanceManager.java @@ -2,7 +2,7 @@ package net.minestom.server.instance; import net.minestom.server.storage.StorageFolder; import net.minestom.server.utils.validate.Check; -import net.minestom.server.world.Dimension; +import net.minestom.server.world.DimensionType; import java.util.Collections; import java.util.HashSet; @@ -18,21 +18,21 @@ public final class InstanceManager { return instanceContainer; } - public InstanceContainer createInstanceContainer(Dimension dimension, StorageFolder storageFolder) { - InstanceContainer instance = new InstanceContainer(UUID.randomUUID(), dimension, storageFolder); + public InstanceContainer createInstanceContainer(DimensionType dimensionType, StorageFolder storageFolder) { + InstanceContainer instance = new InstanceContainer(UUID.randomUUID(), dimensionType, storageFolder); return createInstanceContainer(instance); } public InstanceContainer createInstanceContainer(StorageFolder storageFolder) { - return createInstanceContainer(Dimension.OVERWORLD, storageFolder); + return createInstanceContainer(DimensionType.OVERWORLD, storageFolder); } - public InstanceContainer createInstanceContainer(Dimension dimension) { - return createInstanceContainer(dimension, null); + public InstanceContainer createInstanceContainer(DimensionType dimensionType) { + return createInstanceContainer(dimensionType, null); } public InstanceContainer createInstanceContainer() { - return createInstanceContainer(Dimension.OVERWORLD); + return createInstanceContainer(DimensionType.OVERWORLD); } public SharedInstance createSharedInstance(SharedInstance sharedInstance) { diff --git a/src/main/java/net/minestom/server/instance/SharedInstance.java b/src/main/java/net/minestom/server/instance/SharedInstance.java index 85f4b9376..85b730a55 100644 --- a/src/main/java/net/minestom/server/instance/SharedInstance.java +++ b/src/main/java/net/minestom/server/instance/SharedInstance.java @@ -21,7 +21,7 @@ public class SharedInstance extends Instance { private InstanceContainer instanceContainer; public SharedInstance(UUID uniqueId, InstanceContainer instanceContainer) { - super(uniqueId, instanceContainer.getDimension()); + super(uniqueId, instanceContainer.getDimensionType()); this.instanceContainer = instanceContainer; } 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 bdad708d0..3885f5899 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 @@ -1,10 +1,11 @@ package net.minestom.server.network.packet.server.login; +import net.minestom.server.MinecraftServer; import net.minestom.server.entity.GameMode; 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.world.Dimension; +import net.minestom.server.world.DimensionType; import net.minestom.server.world.LevelType; import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.jglrxavpok.hephaistos.nbt.NBTList; @@ -14,7 +15,7 @@ public class JoinGamePacket implements ServerPacket { public int entityId; public GameMode gameMode = GameMode.SURVIVAL; - public Dimension dimension = Dimension.OVERWORLD; + public DimensionType dimensionType = DimensionType.OVERWORLD; public long hashedSeed; public byte maxPlayers = 0; // Unused //TODO remove @@ -41,14 +42,13 @@ public class JoinGamePacket implements ServerPacket { writer.writeSizedString("test:spawn_name"); NBTList dimensionList = new NBTList<>(NBTTypes.TAG_Compound); - // TODO: custom list - dimensionList.add(Dimension.OVERWORLD.toNBT()); - dimensionList.add(Dimension.NETHER.toNBT()); - dimensionList.add(Dimension.END.toNBT()); + for(DimensionType type : MinecraftServer.getDimensionTypeManager().unmodifiableList()) { + dimensionList.add(type.toNBT()); + } writer.writeNBT("", new NBTCompound().set("dimension", dimensionList)); - writer.writeSizedString(dimension.getName().toString()); - writer.writeSizedString(identifier+"_"+dimension.getName().getPath()); + writer.writeSizedString(dimensionType.getName().toString()); + writer.writeSizedString(identifier+"_"+ dimensionType.getName().getPath()); writer.writeLong(hashedSeed); writer.writeByte(maxPlayers); writer.writeVarInt(viewDistance); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java index 479897b18..4eed81405 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/RespawnPacket.java @@ -4,12 +4,12 @@ import net.minestom.server.entity.GameMode; 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.world.Dimension; +import net.minestom.server.world.DimensionType; import net.minestom.server.world.LevelType; public class RespawnPacket implements ServerPacket { - public Dimension dimension; + public DimensionType dimensionType; public long hashedSeed; public GameMode gameMode; public LevelType levelType; @@ -17,10 +17,10 @@ public class RespawnPacket implements ServerPacket { @Override public void write(PacketWriter writer) { //TODO add api - writer.writeSizedString(dimension.getName().toString()); + writer.writeSizedString(dimensionType.getName().toString()); // Warning: must be different for each dimension type! Otherwise the client seems to cache the world name - writer.writeSizedString("test:spawn_"+dimension.getName().getPath()); // TODO: replace by instance name? + writer.writeSizedString("test:spawn_"+ dimensionType.getName().getPath()); // TODO: replace by instance name? writer.writeLong(hashedSeed); writer.writeByte(gameMode.getId()); diff --git a/src/main/java/net/minestom/server/world/Dimension.java b/src/main/java/net/minestom/server/world/DimensionType.java similarity index 89% rename from src/main/java/net/minestom/server/world/Dimension.java rename to src/main/java/net/minestom/server/world/DimensionType.java index d9c78ec06..62639aef4 100644 --- a/src/main/java/net/minestom/server/world/Dimension.java +++ b/src/main/java/net/minestom/server/world/DimensionType.java @@ -13,9 +13,9 @@ import java.util.Optional; */ @Data @Builder(builderMethodName = "hiddenBuilder", access = AccessLevel.PRIVATE) -public class Dimension { +public class DimensionType { - public static final Dimension OVERWORLD = Dimension.builder(NamespaceID.from("minecraft:overworld")) + public static final DimensionType OVERWORLD = DimensionType.builder(NamespaceID.from("minecraft:overworld")) .ultrawarm(false) .natural(true) .shrunk(false) @@ -31,7 +31,7 @@ public class Dimension { .infiniburn(NamespaceID.from("minecraft:infiniburn_overworld")) .build(); - public static final Dimension NETHER = Dimension.builder(NamespaceID.from("minecraft:the_nether")) + public static final DimensionType NETHER = DimensionType.builder(NamespaceID.from("minecraft:the_nether")) .ultrawarm(true) .natural(false) .shrunk(true) @@ -47,7 +47,7 @@ public class Dimension { .infiniburn(NamespaceID.from("minecraft:infiniburn_nether")) .build(); - public static final Dimension END = Dimension.builder(NamespaceID.from("minecraft:the_end")) + public static final DimensionType END = DimensionType.builder(NamespaceID.from("minecraft:the_end")) .ultrawarm(false) .natural(false) .shrunk(false) @@ -103,7 +103,7 @@ public class Dimension { return name.toString(); } - public static DimensionBuilder builder(NamespaceID name) { + public static DimensionTypeBuilder builder(NamespaceID name) { return hiddenBuilder().name(name); } diff --git a/src/main/java/net/minestom/server/world/DimensionTypeManager.java b/src/main/java/net/minestom/server/world/DimensionTypeManager.java new file mode 100644 index 000000000..746ecfc8e --- /dev/null +++ b/src/main/java/net/minestom/server/world/DimensionTypeManager.java @@ -0,0 +1,47 @@ +package net.minestom.server.world; + +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 DimensionType#OVERWORLD}, {@link DimensionType#NETHER}, {@link DimensionType#END} by default but can be removed. + */ +public class DimensionTypeManager { + + private List dimensionTypes = new LinkedList<>(); + + public DimensionTypeManager() { + addDimension(DimensionType.OVERWORLD); + addDimension(DimensionType.NETHER); + addDimension(DimensionType.END); + } + + /** + * Add a new dimension type. This does NOT send the new list to players. + * @param dimensionType + */ + public void addDimension(DimensionType dimensionType) { + dimensionTypes.add(dimensionType); + } + + /** + * Removes a dimension type. This does NOT send the new list to players. + * @param dimensionType + * @return if the dimension type was removed, false if it was not present before + */ + public boolean removeDimension(DimensionType dimensionType) { + return dimensionTypes.remove(dimensionType); + } + + /** + * Returns an immutable copy of the dimension types already registered + * @return + */ + public List unmodifiableList() { + return Collections.unmodifiableList(dimensionTypes); + } + +}