diff --git a/src/main/java/net/minestom/server/data/DataManager.java b/src/main/java/net/minestom/server/data/DataManager.java index 828ba12a2..c0c5c8c32 100644 --- a/src/main/java/net/minestom/server/data/DataManager.java +++ b/src/main/java/net/minestom/server/data/DataManager.java @@ -10,6 +10,7 @@ import net.minestom.server.utils.validate.Check; import java.util.HashMap; import java.util.Map; +import java.util.UUID; public class DataManager { @@ -43,6 +44,8 @@ public class DataManager { registerType(String.class, new StringData()); registerType(String[].class, new StringArrayData()); + registerType(UUID.class, new UuidType()); + registerType(SerializableData.class, new SerializableDataData()); registerType(ItemStack.class, new ItemStackData()); diff --git a/src/main/java/net/minestom/server/data/type/UuidType.java b/src/main/java/net/minestom/server/data/type/UuidType.java new file mode 100644 index 000000000..d037f8524 --- /dev/null +++ b/src/main/java/net/minestom/server/data/type/UuidType.java @@ -0,0 +1,19 @@ +package net.minestom.server.data.type; + +import net.minestom.server.data.DataType; +import net.minestom.server.network.packet.PacketReader; +import net.minestom.server.network.packet.PacketWriter; + +import java.util.UUID; + +public class UuidType extends DataType { + @Override + public void encode(PacketWriter packetWriter, UUID value) { + packetWriter.writeUuid(value); + } + + @Override + public UUID decode(PacketReader packetReader) { + return packetReader.readUuid(); + } +} diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index d1c0b8ec8..310d926da 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -51,7 +51,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta protected Set experienceOrbs = new CopyOnWriteArraySet<>(); // Entities per chunk protected Map> chunkEntities = new ConcurrentHashMap<>(); - private UUID uniqueId; + protected UUID uniqueId; private Data data; private ExplosionSupplier explosionSupplier; diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index a96cee37c..2e3975609 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -3,6 +3,7 @@ package net.minestom.server.instance; import io.netty.buffer.ByteBuf; import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; +import net.minestom.server.data.SerializableData; import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.instance.batch.BlockBatch; @@ -38,8 +39,12 @@ import java.util.function.Consumer; /** * InstanceContainer is an instance that contains chunks in contrary to SharedInstance. */ +// TODO save data + other things such as UUID public class InstanceContainer extends Instance { + private static final String UUID_KEY = "uuid"; + private static final String DATA_KEY = "data"; + private StorageFolder storageFolder; private List sharedInstances = new CopyOnWriteArrayList<>(); @@ -54,7 +59,16 @@ public class InstanceContainer extends Instance { public InstanceContainer(UUID uniqueId, Dimension dimension, StorageFolder storageFolder) { super(uniqueId, dimension); + this.storageFolder = storageFolder; + + if (storageFolder == null) + return; + // Retrieve instance data + this.uniqueId = storageFolder.getOrDefault(UUID_KEY, UUID.class, uniqueId); + + Data data = storageFolder.getOrDefault(DATA_KEY, SerializableData.class, null); + setData(data); } @Override @@ -309,6 +323,27 @@ public class InstanceContainer extends Instance { return ChunkUtils.isChunkUnloaded(chunk) ? null : chunk; } + /** + * Save the instance ({@link #getUniqueId()} {@link #getData()}) and call {@link #saveChunksToStorageFolder(Runnable)} + *

+ * WARNING: {@link #getData()} needs to be a {@link SerializableData} in order to be saved + * + * @param callback the callback + */ + public void saveInstance(Runnable callback) { + Check.notNull(getStorageFolder(), "You cannot save the instance if no StorageFolder has been defined"); + + this.storageFolder.set(UUID_KEY, getUniqueId(), UUID.class); + Data data = getData(); + if (data != null) { + Check.stateCondition(!(data instanceof SerializableData), + "Instance#getData needs to be a SerializableData in order to be saved"); + this.storageFolder.set(DATA_KEY, (SerializableData) getData(), SerializableData.class); + } + + saveChunksToStorageFolder(callback); + } + @Override public void saveChunkToStorageFolder(Chunk chunk, Runnable callback) { Check.notNull(getStorageFolder(), "You cannot save the chunk if no StorageFolder has been defined"); diff --git a/src/main/java/net/minestom/server/network/packet/PacketReader.java b/src/main/java/net/minestom/server/network/packet/PacketReader.java index 0604c2e04..0c1b516dc 100644 --- a/src/main/java/net/minestom/server/network/packet/PacketReader.java +++ b/src/main/java/net/minestom/server/network/packet/PacketReader.java @@ -7,6 +7,8 @@ import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.SerializerUtils; import net.minestom.server.utils.Utils; +import java.util.UUID; + public class PacketReader { private ByteBuf buffer; @@ -90,6 +92,12 @@ public class PacketReader { return SerializerUtils.longToBlockPosition(value); } + public UUID readUuid() { + long most = readLong(); + long least = readLong(); + return new UUID(most, least); + } + public ItemStack readSlot() { return Utils.readItemStack(this); } diff --git a/src/main/java/net/minestom/server/storage/StorageFolder.java b/src/main/java/net/minestom/server/storage/StorageFolder.java index 710588007..a3360becc 100644 --- a/src/main/java/net/minestom/server/storage/StorageFolder.java +++ b/src/main/java/net/minestom/server/storage/StorageFolder.java @@ -32,7 +32,7 @@ public class StorageFolder { this.storageSystem.open(folderPath); } - + public byte[] get(String key) { return storageSystem.get(key); }