mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 19:18:12 +01:00
Added SerializableData
This commit is contained in:
parent
754821f447
commit
f544f090ae
@ -1,28 +1,20 @@
|
|||||||
package net.minestom.server.data;
|
package net.minestom.server.data;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.utils.PrimitiveConversion;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class Data {
|
public class Data {
|
||||||
|
|
||||||
private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager();
|
protected static final DataManager DATA_MANAGER = MinecraftServer.getDataManager();
|
||||||
|
|
||||||
// TODO replace maps to something more memory-friendly
|
protected ConcurrentHashMap<String, Object> data = new ConcurrentHashMap();
|
||||||
private ConcurrentHashMap<String, Object> data = new ConcurrentHashMap();
|
|
||||||
private ConcurrentHashMap<String, Class> dataType = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public <T> void set(String key, T value, Class<T> type) {
|
public <T> void set(String key, T value, Class<T> type) {
|
||||||
if (DATA_MANAGER.getDataType(type) == null) {
|
if (DATA_MANAGER.getDataType(type) == null) {
|
||||||
throw new UnsupportedOperationException("Type " + type.getName() + " hasn't been registered in DataManager#registerType");
|
throw new UnsupportedOperationException("Type " + type.getName() + " hasn't been registered in DataManager#registerType");
|
||||||
}
|
}
|
||||||
this.data.put(key, value);
|
this.data.put(key, value);
|
||||||
this.dataType.put(key, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T get(String key) {
|
public <T> T get(String key) {
|
||||||
@ -36,36 +28,7 @@ public class Data {
|
|||||||
public Data clone() {
|
public Data clone() {
|
||||||
Data data = new Data();
|
Data data = new Data();
|
||||||
data.data = new ConcurrentHashMap<>(this.data);
|
data.data = new ConcurrentHashMap<>(this.data);
|
||||||
data.dataType = new ConcurrentHashMap<>(dataType);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getSerializedData() throws IOException {
|
|
||||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
DataOutputStream dos = new DataOutputStream(output);
|
|
||||||
|
|
||||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
|
||||||
String key = entry.getKey();
|
|
||||||
Class type = dataType.get(key);
|
|
||||||
Object value = entry.getValue();
|
|
||||||
DataType dataType = DATA_MANAGER.getDataType(type);
|
|
||||||
|
|
||||||
byte[] encodedType = PrimitiveConversion.getObjectClassString(type.getName()).getBytes(); // Data type (fix for primitives)
|
|
||||||
dos.writeShort(encodedType.length);
|
|
||||||
dos.write(encodedType);
|
|
||||||
|
|
||||||
byte[] encodedName = key.getBytes(); // Data name
|
|
||||||
dos.writeShort(encodedName.length);
|
|
||||||
dos.write(encodedName);
|
|
||||||
|
|
||||||
byte[] encodedValue = dataType.encode(value); // Data
|
|
||||||
dos.writeInt(encodedValue.length);
|
|
||||||
dos.write(encodedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
dos.writeShort(0xff); // End of data object
|
|
||||||
|
|
||||||
return output.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,12 @@ public interface DataContainer {
|
|||||||
Data data = getData();
|
Data data = getData();
|
||||||
if (data == null)
|
if (data == null)
|
||||||
throw new NullPointerException("You cannot save null data!");
|
throw new NullPointerException("You cannot save null data!");
|
||||||
|
if (!(data instanceof SerializableData))
|
||||||
|
throw new IllegalArgumentException("Only SerializableData can be serialized");
|
||||||
|
SerializableData serializableData = (SerializableData) data;
|
||||||
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
byte[] serializedData = data.getSerializedData();
|
byte[] serializedData = serializableData.getSerializedData();
|
||||||
fos.write(CompressionUtils.getCompressedData(serializedData));
|
fos.write(CompressionUtils.getCompressedData(serializedData));
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -59,7 +62,7 @@ public interface DataContainer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data data = DataReader.readData(array, true);
|
SerializableData data = DataReader.readData(array, true);
|
||||||
|
|
||||||
setData(data);
|
setData(data);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
|
@ -23,7 +23,7 @@ public class DataManager {
|
|||||||
|
|
||||||
registerType(String.class, new StringData());
|
registerType(String.class, new StringData());
|
||||||
|
|
||||||
registerType(Data.class, new DataData());
|
registerType(SerializableData.class, new SerializableDataData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void registerType(Class<T> clazz, DataType<T> dataType) {
|
public <T> void registerType(Class<T> clazz, DataType<T> dataType) {
|
||||||
|
56
src/main/java/net/minestom/server/data/SerializableData.java
Normal file
56
src/main/java/net/minestom/server/data/SerializableData.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package net.minestom.server.data;
|
||||||
|
|
||||||
|
import net.minestom.server.utils.PrimitiveConversion;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class SerializableData extends Data {
|
||||||
|
|
||||||
|
private ConcurrentHashMap<String, Class> dataType = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void set(String key, T value, Class<T> type) {
|
||||||
|
super.set(key, value, type);
|
||||||
|
this.dataType.put(key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data clone() {
|
||||||
|
SerializableData cloned = (SerializableData) super.clone();
|
||||||
|
cloned.dataType = new ConcurrentHashMap<>(dataType);
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSerializedData() throws IOException {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(output);
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
Class type = dataType.get(key);
|
||||||
|
Object value = entry.getValue();
|
||||||
|
DataType dataType = DATA_MANAGER.getDataType(type);
|
||||||
|
|
||||||
|
byte[] encodedType = PrimitiveConversion.getObjectClassString(type.getName()).getBytes(); // Data type (fix for primitives)
|
||||||
|
dos.writeShort(encodedType.length);
|
||||||
|
dos.write(encodedType);
|
||||||
|
|
||||||
|
byte[] encodedName = key.getBytes(); // Data name
|
||||||
|
dos.writeShort(encodedName.length);
|
||||||
|
dos.write(encodedName);
|
||||||
|
|
||||||
|
byte[] encodedValue = dataType.encode(value); // Data
|
||||||
|
dos.writeInt(encodedValue.length);
|
||||||
|
dos.write(encodedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
dos.writeShort(0xff); // End of data object
|
||||||
|
|
||||||
|
return output.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +1,16 @@
|
|||||||
package net.minestom.server.data.type;
|
package net.minestom.server.data.type;
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.data.DataType;
|
import net.minestom.server.data.DataType;
|
||||||
|
import net.minestom.server.data.SerializableData;
|
||||||
import net.minestom.server.io.DataReader;
|
import net.minestom.server.io.DataReader;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
// Pretty weird name huh?
|
// Pretty weird name huh?
|
||||||
public class DataData extends DataType<Data> {
|
public class SerializableDataData extends DataType<SerializableData> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encode(Data value) {
|
public byte[] encode(SerializableData value) {
|
||||||
try {
|
try {
|
||||||
return value.getSerializedData();
|
return value.getSerializedData();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -19,7 +20,7 @@ public class DataData extends DataType<Data> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Data decode(byte[] value) {
|
public SerializableData decode(byte[] value) {
|
||||||
return DataReader.readData(value, false);
|
return DataReader.readData(value, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.ints.*;
|
|||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.data.Data;
|
import net.minestom.server.data.Data;
|
||||||
|
import net.minestom.server.data.SerializableData;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.instance.block.BlockManager;
|
import net.minestom.server.instance.block.BlockManager;
|
||||||
@ -287,15 +288,17 @@ public class Chunk implements Viewable {
|
|||||||
dos.writeBoolean(isCustomBlock); // Determine the type of the ID
|
dos.writeBoolean(isCustomBlock); // Determine the type of the ID
|
||||||
dos.writeShort(id);
|
dos.writeShort(id);
|
||||||
|
|
||||||
|
if (data instanceof SerializableData) {
|
||||||
dos.writeBoolean(hasData);
|
dos.writeBoolean(hasData);
|
||||||
if (hasData) {
|
if (hasData) {
|
||||||
byte[] d = data.getSerializedData();
|
byte[] d = ((SerializableData) data).getSerializedData();
|
||||||
dos.writeInt(d.length);
|
dos.writeInt(d.length);
|
||||||
dos.write(d);
|
dos.write(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
byte[] result = output.toByteArray();
|
byte[] result = output.toByteArray();
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.minestom.server.io;
|
package net.minestom.server.io;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.data.DataManager;
|
import net.minestom.server.data.DataManager;
|
||||||
|
import net.minestom.server.data.SerializableData;
|
||||||
import net.minestom.server.utils.CompressionUtils;
|
import net.minestom.server.utils.CompressionUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -13,12 +13,12 @@ public class DataReader {
|
|||||||
|
|
||||||
private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager();
|
private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager();
|
||||||
|
|
||||||
public static Data readData(byte[] b, boolean shouldDecompress) {
|
public static SerializableData readData(byte[] b, boolean shouldDecompress) {
|
||||||
b = shouldDecompress ? CompressionUtils.getDecompressedData(b) : b;
|
b = shouldDecompress ? CompressionUtils.getDecompressedData(b) : b;
|
||||||
|
|
||||||
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(b));
|
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(b));
|
||||||
|
|
||||||
Data data = new Data();
|
SerializableData data = new SerializableData();
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
short typeLength = stream.readShort();
|
short typeLength = stream.readShort();
|
||||||
|
Loading…
Reference in New Issue
Block a user