Removed the reader classes, deplaced them into SerializableData and Chunk respectively. It allows for developers to make their own deserialization AND serialization implementation

This commit is contained in:
themode 2020-09-23 21:08:36 +02:00
parent 81db2dbdf9
commit 890cfe4622
13 changed files with 242 additions and 262 deletions

View File

@ -1,13 +1,13 @@
package net.minestom.server.data;
import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import net.minestom.server.MinecraftServer;
import net.minestom.server.reader.DataReader;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
/**
* Represent a {@link Data} object which can be serialized and read back by the {@link DataReader}
* Represent a {@link Data} object which can be serialized and read back
*/
public interface SerializableData extends Data {
@ -16,8 +16,8 @@ public interface SerializableData extends Data {
/**
* Serialize the data into an array of bytes
* <p>
* Use {@link DataReader#readIndexedData(BinaryReader)} if {@code indexed} is true,
* {@link DataReader#readData(Object2ShortMap, BinaryReader)} otherwise with the index map
* Use {@link #readIndexedSerializedData(BinaryReader)} if {@code indexed} is true,
* {@link #readSerializedData(BinaryReader, Object2ShortMap)} otherwise with the index map
* to convert it back to a {@link SerializableData}
*
* @param typeToIndexMap the type to index map, will create entries if new types are discovered.
@ -30,7 +30,7 @@ public interface SerializableData extends Data {
/**
* Serialize the data into an array of bytes
* <p>
* Use {@link net.minestom.server.reader.DataReader#readIndexedData(BinaryReader)}
* Use {@link #readIndexedSerializedData(BinaryReader)}
* to convert it back to a {@link SerializableData}
* <p>
* This will create a type index map which will be present in the header
@ -40,7 +40,23 @@ public interface SerializableData extends Data {
byte[] getIndexedSerializedData();
/**
* Get the index info (class name -&gt; class index)
* Read the data of a {@link SerializableData} when you already have the index map
*
* @param reader the binary reader
* @param typeToIndexMap the index map
*/
void readSerializedData(BinaryReader reader, Object2ShortMap<String> typeToIndexMap);
/**
* Read the index map and the data of a serialized {@link SerializableData}
* Got from {@link #getIndexedSerializedData()}
*
* @param reader the binary reader
*/
void readIndexedSerializedData(BinaryReader reader);
/**
* Get the index info (class name -> class index)
* <p>
* Sized by a var-int
*
@ -61,4 +77,23 @@ public interface SerializableData extends Data {
}
}
/**
* Get a map containing the indexes of your data (type name -&gt; type index)
*
* @param binaryReader the reader
* @return a map containing the indexes of your data
*/
static Object2ShortMap<String> readDataIndexes(BinaryReader binaryReader) {
Object2ShortMap<String> typeToIndexMap = new Object2ShortOpenHashMap<>();
{
final int dataIndexSize = binaryReader.readVarInt();
for (int i = 0; i < dataIndexSize; i++) {
final String className = binaryReader.readSizedString();
final short classIndex = binaryReader.readShort();
typeToIndexMap.put(className, classIndex);
}
}
return typeToIndexMap;
}
}

View File

@ -2,7 +2,10 @@ package net.minestom.server.data;
import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import net.minestom.server.utils.PrimitiveConversion;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import java.util.Map;
@ -15,6 +18,12 @@ public class SerializableDataImpl extends DataImpl implements SerializableData {
private ConcurrentHashMap<String, Class> dataType = new ConcurrentHashMap<>();
/**
* Class name -> Class
* Used to cache data so we don't load class by name each time
*/
private static ConcurrentHashMap<String, Class> nameToClassMap = new ConcurrentHashMap<>();
/**
* Set a value to a specific key
* <p>
@ -104,4 +113,79 @@ public class SerializableDataImpl extends DataImpl implements SerializableData {
return getSerializedData(new Object2ShortOpenHashMap<>(), true);
}
@Override
public void readSerializedData(BinaryReader reader, Object2ShortMap<String> typeToIndexMap) {
readIndexedData(this, typeToIndexMap, reader);
}
@Override
public void readIndexedSerializedData(BinaryReader reader) {
readData(this, reader);
}
/**
* Read the indexes of the data + the data
*
* @param data the object to append the data
* @param reader the reader
* @return the deserialized {@link SerializableData}
*/
private static void readData(SerializableData data, BinaryReader reader) {
final Object2ShortMap<String> typeToIndexMap = SerializableData.readDataIndexes(reader);
readIndexedData(data, typeToIndexMap, reader);
}
/**
* Convert a buffer into a {@link SerializableData}, this will not read the data index header.
* Use {@link #readData(SerializableData, BinaryReader)} to read the whole data object (if your data contains the indexes)
* <p>
* WARNING: the {@link DataManager} needs to have all the required types as the {@link SerializableData} has
*
* @param data the object to append the data
* @param typeToIndexMap the map which index all the type contained in the data (className->classIndex)
* @param reader the reader
*/
private static void readIndexedData(SerializableData data, Object2ShortMap<String> typeToIndexMap, BinaryReader reader) {
final Short2ObjectMap<String> indexToTypeMap = new Short2ObjectOpenHashMap<>(typeToIndexMap.size());
{
// Fill the indexToType map
for (Object2ShortMap.Entry<String> entry : typeToIndexMap.object2ShortEntrySet()) {
final String type = entry.getKey();
final short index = entry.getShortValue();
indexToTypeMap.put(index, type);
}
}
while (true) {
// Get the class index
final short typeIndex = reader.readShort();
if (typeIndex == 0) {
// End of data
break;
}
final Class type;
{
final String className = indexToTypeMap.get(typeIndex);
type = nameToClassMap.computeIfAbsent(className, s -> {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
});
}
// Get the key
final String name = reader.readSizedString();
// Get the data
final Object value = DATA_MANAGER.getDataType(type).decode(reader);
// Set the data
data.set(name, value, type);
}
}
}

View File

@ -2,7 +2,7 @@ package net.minestom.server.data.type;
import net.minestom.server.data.DataType;
import net.minestom.server.data.SerializableData;
import net.minestom.server.reader.DataReader;
import net.minestom.server.data.SerializableDataImpl;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
@ -16,6 +16,8 @@ public class SerializableDataData extends DataType<SerializableData> {
@Override
public SerializableData decode(BinaryReader reader) {
return DataReader.readIndexedData(reader);
SerializableData serializableData = new SerializableDataImpl();
serializableData.readIndexedSerializedData(reader);
return serializableData;
}
}

View File

@ -20,12 +20,15 @@ import net.minestom.server.network.packet.server.play.UpdateLightPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.player.PlayerUtils;
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 net.minestom.server.world.biomes.BiomeManager;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
@ -35,6 +38,7 @@ import java.util.function.Consumer;
public abstract class Chunk implements Viewable {
protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
public static final int CHUNK_SIZE_X = 16;
public static final int CHUNK_SIZE_Y = 256;
@ -45,6 +49,7 @@ public abstract class Chunk implements Viewable {
public static final int BIOME_COUNT = 1024; // 4x4x4 blocks
protected final Instance instance;
protected Biome[] biomes;
protected int chunkX, chunkZ;
@ -70,10 +75,16 @@ public abstract class Chunk implements Viewable {
protected Set<Player> viewers = new CopyOnWriteArraySet<>();
protected ByteBuf fullDataPacket;
public Chunk(Biome[] biomes, int chunkX, int chunkZ) {
this.biomes = biomes;
public Chunk(Instance instance, Biome[] biomes, int chunkX, int chunkZ) {
this.instance = instance;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
if (biomes != null && biomes.length == BIOME_COUNT) {
this.biomes = biomes;
} else {
this.biomes = new Biome[BIOME_COUNT];
}
}
/**
@ -314,12 +325,23 @@ public abstract class Chunk implements Viewable {
}
/**
* Serialize the chunk
* Serialize the chunk into bytes
*
* @return the serialized chunk, can potentially be null if this chunk cannot be serialized
*/
public abstract byte[] getSerializedData();
/**
* Read the chunk from binary
* <p>
* Used if the chunk is loaded from file
*
* @param reader the data reader
* @param callback the callback to execute once the chunk is done reading
* WARNING: this need to be called to notify the instance
*/
public abstract void readChunk(BinaryReader reader, ChunkCallback callback);
/**
* Get a {@link ChunkDataPacket} which should contain the full chunk
*

View File

@ -6,16 +6,18 @@ import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import net.minestom.server.data.Data;
import net.minestom.server.data.SerializableData;
import net.minestom.server.data.SerializableDataImpl;
import net.minestom.server.entity.pathfinding.PFBlockDescription;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.reader.ChunkReader;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.world.biomes.Biome;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
public class DynamicChunk extends Chunk {
@ -25,8 +27,8 @@ public class DynamicChunk extends Chunk {
protected final short[] blocksStateId = new short[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
protected final short[] customBlocksId = new short[CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z];
public DynamicChunk(Biome[] biomes, int chunkX, int chunkZ) {
super(biomes, chunkX, chunkZ);
public DynamicChunk(Instance instance, Biome[] biomes, int chunkX, int chunkZ) {
super(instance, biomes, chunkX, chunkZ);
}
@Override
@ -130,7 +132,7 @@ public class DynamicChunk extends Chunk {
}
/**
* Serialize this {@link Chunk} based on {@link ChunkReader#readChunk(byte[], Instance, int, int, ChunkCallback)}
* Serialize this {@link Chunk} based on {@link #readChunk(BinaryReader, ChunkCallback)}
* <p>
* It is also used by the default {@link IChunkLoader} which is {@link MinestomBasicChunkLoader}
*
@ -197,6 +199,63 @@ public class DynamicChunk extends Chunk {
return binaryWriter.toByteArray();
}
@Override
public void readChunk(BinaryReader reader, ChunkCallback callback) {
// Used for blocks data
Object2ShortMap<String> typeToIndexMap = null;
ChunkBatch chunkBatch = instance.createChunkBatch(this);
try {
// Get if the chunk has data indexes (used for blocks data)
final boolean hasIndex = reader.readBoolean();
if (hasIndex) {
// Get the data indexes which will be used to read all the individual data
typeToIndexMap = SerializableData.readDataIndexes(reader);
}
for (int i = 0; i < BIOME_COUNT; i++) {
final byte id = reader.readByte();
this.biomes[i] = BIOME_MANAGER.getById(id);
}
while (true) {
// Position
final short index = reader.readShort();
final byte x = ChunkUtils.blockIndexToChunkPositionX(index);
final short y = ChunkUtils.blockIndexToChunkPositionY(index);
final byte z = ChunkUtils.blockIndexToChunkPositionZ(index);
// Block type
final short blockStateId = reader.readShort();
final short customBlockId = reader.readShort();
// Data
SerializableData data = null;
{
final boolean hasData = reader.readBoolean();
// Data deserializer
if (hasData) {
// Read the data with the deserialized index map
data = new SerializableDataImpl();
data.readSerializedData(reader, typeToIndexMap);
}
}
if (customBlockId != 0) {
chunkBatch.setSeparateBlocks(x, y, z, blockStateId, customBlockId, data);
} else {
chunkBatch.setBlockStateId(x, y, z, blockStateId, data);
}
}
} catch (IndexOutOfBoundsException e) {
// Finished reading
}
// Place all the blocks from the batch
chunkBatch.unsafeFlush(callback); // Success, null if file isn't properly encoded
}
@Override
protected ChunkDataPacket getFreshPacket() {
ChunkDataPacket fullDataPacket = new ChunkDataPacket();

View File

@ -103,7 +103,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param callback the task to execute during the next instance tick
*/
public void scheduleNextTick(Consumer<Instance> callback) {
nextTick.add(callback);
this.nextTick.add(callback);
}
/**
@ -375,7 +375,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
/**
* Get a {@link TimeUpdatePacket} with the current age and time of this instance
*
* @return the {@link TimeUpdatePacket} with this instance datal
* @return the {@link TimeUpdatePacket} with this instance data
*/
private TimeUpdatePacket getTimePacket() {
TimeUpdatePacket timeUpdatePacket = new TimeUpdatePacket();

View File

@ -491,10 +491,10 @@ public class InstanceContainer extends Instance {
final BlockProvider blockProvider = chunkDecider != null ? chunkDecider.apply(chunkX, chunkZ) : null;
if (blockProvider != null) {
// Use static chunk
chunk = new StaticChunk(biomes, chunkX, chunkZ, blockProvider);
chunk = new StaticChunk(this, biomes, chunkX, chunkZ, blockProvider);
} else {
// Use dynamic chunk
chunk = new DynamicChunk(biomes, chunkX, chunkZ);
chunk = new DynamicChunk(this, biomes, chunkX, chunkZ);
}
cacheChunk(chunk);

View File

@ -1,7 +1,7 @@
package net.minestom.server.instance;
import net.minestom.server.reader.ChunkReader;
import net.minestom.server.storage.StorageLocation;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.chunk.ChunkCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,7 +48,9 @@ public class MinestomBasicChunkLoader implements IChunkLoader {
return false;
} else {
// Found, load from result bytes
ChunkReader.readChunk(bytes, instance, chunkX, chunkZ, callback);
BinaryReader reader = new BinaryReader(bytes);
Chunk chunk = new DynamicChunk(instance, null, chunkX, chunkZ);
chunk.readChunk(reader, callback);
return true;
}
}

View File

@ -4,6 +4,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.data.Data;
import net.minestom.server.instance.block.BlockProvider;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.world.biomes.Biome;
@ -13,8 +15,8 @@ public class StaticChunk extends Chunk {
protected final BlockProvider blockProvider;
public StaticChunk(Biome[] biomes, int chunkX, int chunkZ, BlockProvider blockProvider) {
super(biomes, chunkX, chunkZ);
public StaticChunk(Instance instance, Biome[] biomes, int chunkX, int chunkZ, BlockProvider blockProvider) {
super(instance, biomes, chunkX, chunkZ);
this.blockProvider = blockProvider;
}
@ -49,6 +51,11 @@ public class StaticChunk extends Chunk {
return null;
}
@Override
public void readChunk(BinaryReader reader, ChunkCallback callback) {
callback.accept(this);
}
@Override
protected ChunkDataPacket getFreshPacket() {
ChunkDataPacket fullDataPacket = new ChunkDataPacket();

View File

@ -22,7 +22,7 @@ public class ChunkBatch implements InstanceBatch {
private final Chunk chunk;
// Give it the max capacity by default (avoid resizing)
private List<BlockData> dataList =
private final List<BlockData> dataList =
Collections.synchronizedList(new ArrayList<>(
Chunk.CHUNK_SIZE_X * Chunk.CHUNK_SIZE_Y * Chunk.CHUNK_SIZE_Z));
@ -88,9 +88,7 @@ public class ChunkBatch implements InstanceBatch {
* @param callback the callback to execute once the blocks are placed
*/
public void flush(ChunkCallback callback) {
batchesPool.execute(() -> {
singleThreadFlush(callback, true);
});
batchesPool.execute(() -> singleThreadFlush(callback, true));
}
/**
@ -99,9 +97,7 @@ public class ChunkBatch implements InstanceBatch {
* @param callback the callback to execute once the blocks are placed
*/
public void unsafeFlush(ChunkCallback callback) {
batchesPool.execute(() -> {
singleThreadFlush(callback, false);
});
batchesPool.execute(() -> singleThreadFlush(callback, false));
}
public void clearData() {
@ -129,9 +125,7 @@ public class ChunkBatch implements InstanceBatch {
if (callback != null) {
if (safeCallback) {
instance.scheduleNextTick(inst -> {
callback.accept(chunk);
});
instance.scheduleNextTick(inst -> callback.accept(chunk));
} else {
callback.accept(chunk);
}

View File

@ -1,93 +0,0 @@
package net.minestom.server.reader;
import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import net.minestom.server.MinecraftServer;
import net.minestom.server.data.Data;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.DynamicChunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.world.biomes.Biome;
import net.minestom.server.world.biomes.BiomeManager;
public class ChunkReader {
private static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
/**
* Read a chunk from a byte array, the array should contain the whole chunk and only it
* <p>
* By default you can retrieve this byte array using {@link DynamicChunk#getSerializedData()}
*
* @param b the byte array containing the chunk
* @param instance the instance of the chunk
* @param chunkX the chunk X
* @param chunkZ the chunk Z
* @param callback the consumer called once the chunk has been read
*/
public static void readChunk(byte[] b, Instance instance, int chunkX, int chunkZ, ChunkCallback callback) {
BinaryReader binaryReader = new BinaryReader(b);
// Used for blocks data
Object2ShortMap<String> typeToIndexMap = null;
ChunkBatch chunkBatch = null;
try {
// Get if the chunk has data indexes (used for blocks data)
final boolean hasIndex = binaryReader.readBoolean();
if (hasIndex) {
// Get the data indexes which will be used to read all the individual data
typeToIndexMap = DataReader.readDataIndexes(binaryReader);
}
Biome[] biomes = new Biome[Chunk.BIOME_COUNT];
for (int i = 0; i < biomes.length; i++) {
final byte id = binaryReader.readByte();
biomes[i] = BIOME_MANAGER.getById(id);
}
final Chunk chunk = new DynamicChunk(biomes, chunkX, chunkZ);
chunkBatch = instance.createChunkBatch(chunk);
while (true) {
// Position
final short index = binaryReader.readShort();
final byte x = ChunkUtils.blockIndexToChunkPositionX(index);
final short y = ChunkUtils.blockIndexToChunkPositionY(index);
final byte z = ChunkUtils.blockIndexToChunkPositionZ(index);
// Block type
final short blockStateId = binaryReader.readShort();
final short customBlockId = binaryReader.readShort();
// Data
Data data = null;
{
final boolean hasData = binaryReader.readBoolean();
// Data deserializer
if (hasData) {
// Read the data with the deserialized index map
data = DataReader.readData(typeToIndexMap, binaryReader);
}
}
if (customBlockId != 0) {
chunkBatch.setSeparateBlocks(x, y, z, blockStateId, customBlockId, data);
} else {
chunkBatch.setBlockStateId(x, y, z, blockStateId, data);
}
}
} catch (IndexOutOfBoundsException e) {
// Finished reading
}
// Place all the blocks from the batch
chunkBatch.flush(c -> callback.accept(c)); // Success, null if file isn't properly encoded
}
}

View File

@ -1,113 +0,0 @@
package net.minestom.server.reader;
import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import net.minestom.server.MinecraftServer;
import net.minestom.server.data.DataManager;
import net.minestom.server.data.SerializableData;
import net.minestom.server.data.SerializableDataImpl;
import net.minestom.server.utils.binary.BinaryReader;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class used to convert an array of bytes to a {@link SerializableData}
* <p>
* WARNING: the {@link DataManager} needs to have all the required types as the {@link SerializableData} has
*/
public class DataReader {
private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager();
private static ConcurrentHashMap<String, Class> nameToClassMap = new ConcurrentHashMap<>();
/**
* Convert a buffer into a {@link SerializableData}, this will not read the data index header.
* Use {@link #readIndexedData(BinaryReader)} to read the whole data object (if your data contains the indexes)
* <p>
* WARNING: the {@link DataManager} needs to have all the required types as the {@link SerializableData} has
*
* @param typeToIndexMap the map which index all the type contained in the data (className-&gt;classIndex)
* @param reader the reader
* @return a {@link SerializableData} based on the data input
*/
public static SerializableData readData(Object2ShortMap<String> typeToIndexMap, BinaryReader reader) {
final Short2ObjectMap<String> indexToTypeMap = new Short2ObjectOpenHashMap<>(typeToIndexMap.size());
{
// Fill the indexToType map
for (Object2ShortMap.Entry<String> entry : typeToIndexMap.object2ShortEntrySet()) {
final String type = entry.getKey();
final short index = entry.getShortValue();
indexToTypeMap.put(index, type);
}
}
SerializableData data = new SerializableDataImpl();
while (true) {
// Get the class index
final short typeIndex = reader.readShort();
if (typeIndex == 0) {
// End of data
break;
}
final Class type;
{
final String className = indexToTypeMap.get(typeIndex);
type = nameToClassMap.computeIfAbsent(className, s -> {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
});
}
// Get the key
final String name = reader.readSizedString();
// Get the data
final Object value = DATA_MANAGER.getDataType(type).decode(reader);
// Set the data
data.set(name, value, type);
}
return data;
}
/**
* Read the indexes of the data + the data
*
* @param reader the reader
* @return the deserialized {@link SerializableData}
*/
public static SerializableData readIndexedData(BinaryReader reader) {
final Object2ShortMap<String> typeToIndexMap = readDataIndexes(reader);
return readData(typeToIndexMap, reader);
}
/**
* Get a map containing the indexes of your data (type name -&gt; type index)
*
* @param binaryReader the reader
* @return a map containing the indexes of your data
*/
public static Object2ShortMap<String> readDataIndexes(BinaryReader binaryReader) {
Object2ShortMap<String> typeToIndexMap = new Object2ShortOpenHashMap<>();
{
final int dataIndexSize = binaryReader.readVarInt();
for (int i = 0; i < dataIndexSize; i++) {
final String className = binaryReader.readSizedString();
final short classIndex = binaryReader.readShort();
typeToIndexMap.put(className, classIndex);
}
}
return typeToIndexMap;
}
}

View File

@ -1,12 +1,7 @@
package net.minestom.server.storage;
import net.minestom.server.MinecraftServer;
import net.minestom.server.data.DataContainer;
import net.minestom.server.data.DataManager;
import net.minestom.server.data.DataType;
import net.minestom.server.data.SerializableData;
import net.minestom.server.data.SerializableDataImpl;
import net.minestom.server.reader.DataReader;
import net.minestom.server.data.*;
import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.validate.Check;
@ -147,14 +142,7 @@ public class StorageLocation {
}
// Load it from the storage system
final byte[] bytes = get(key);
SerializableData data;
if (bytes != null) {
data = DataReader.readIndexedData(new BinaryReader(bytes));
} else {
data = new SerializableDataImpl();
}
SerializableData data = getOrDefault(key, SerializableData.class, new SerializableDataImpl());
dataContainer.setData(data);
@ -178,14 +166,7 @@ public class StorageLocation {
}
// Load it from the storage system and cache it
final byte[] bytes = get(key);
SerializableData data;
if (bytes != null) {
data = DataReader.readIndexedData(new BinaryReader(bytes));
} else {
data = new SerializableDataImpl();
}
SerializableData data = getOrDefault(key, SerializableData.class, new SerializableDataImpl());
dataContainer.setData(data);