Customizable dimension list in JoinGamePacket + Dimension->DimensionType

This commit is contained in:
jglrxavpok 2020-07-13 14:12:21 +02:00
parent f12ab40a6e
commit 30019ebe9a
13 changed files with 119 additions and 65 deletions

@ -1 +1 @@
Subproject commit 6e5241db3b4546242d2056b27691e9f7c11dc2d5
Subproject commit a637148b634ee3f1ae839f93eadc90b4274b8c5b

View File

@ -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);

View File

@ -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<Instance> targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimension() == finalTargetDimension).findFirst();
DimensionType finalTargetDimensionType = targetDimensionType;
Optional<Instance> 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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}
/**

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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<NBTCompound> 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);

View File

@ -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());

View File

@ -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);
}

View File

@ -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<DimensionType> 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<DimensionType> unmodifiableList() {
return Collections.unmodifiableList(dimensionTypes);
}
}