use of org.spongepowered.api.data.DataView in project LanternServer by LanternPowered.
the class MemoryDataView method createView.
@Override
public DataView createView(DataQuery path, Map<?, ?> map) {
checkNotNull(path, "path");
final DataView section = createView(path);
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (entry.getValue() instanceof Map) {
section.createView(of('.', entry.getKey().toString()), (Map<?, ?>) entry.getValue());
} else {
section.set(of('.', entry.getKey().toString()), entry.getValue());
}
}
return section;
}
use of org.spongepowered.api.data.DataView in project LanternServer by LanternPowered.
the class MemoryDataView method createView.
@Override
public DataView createView(DataQuery path) {
checkNotNull(path, "path");
final List<String> queryParts = path.getParts();
final int sz = queryParts.size();
checkArgument(sz != 0, "The size of the query must be at least 1");
final String key = queryParts.get(0);
final DataQuery keyQuery = of(key);
if (sz == 1) {
final DataView result = new MemoryDataView(this, keyQuery, this.safety);
this.map.put(key, result);
return result;
}
final DataQuery subQuery = path.popFirst();
final DataView subView = (DataView) this.map.computeIfAbsent(key, key1 -> new MemoryDataView(this.parent, keyQuery, this.safety));
return subView.createView(subQuery);
}
use of org.spongepowered.api.data.DataView in project LanternServer by LanternPowered.
the class MemoryDataView method set.
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public DataView set(DataQuery path, Object value) {
checkNotNull(path, "path");
checkNotNull(value, "value");
final LanternDataManager manager = getDataManager();
final List<String> parts = path.getParts();
final String key = parts.get(0);
if (parts.size() > 1) {
final DataQuery subQuery = of(key);
final Optional<DataView> subViewOptional = getUnsafeView(subQuery);
final DataView subView;
if (!subViewOptional.isPresent()) {
createView(subQuery);
subView = (DataView) this.map.get(key);
} else {
subView = subViewOptional.get();
}
subView.set(path.popFirst(), value);
return this;
}
Optional<DataTypeSerializer> optDataTypeSerializer;
TypeToken typeToken;
if (value instanceof DataView) {
checkArgument(value != this, "Cannot set a DataView to itself.");
// always have to copy a data view to avoid overwriting existing
// views and to set the interior path correctly.
copyDataView(path, (DataView) value);
} else if (value instanceof DataSerializable) {
final DataContainer valueContainer = ((DataSerializable) value).toContainer();
checkArgument(!(valueContainer).equals(this), "Cannot insert self-referencing DataSerializable");
// see above for why this is copied
copyDataView(path, valueContainer);
} else if (value instanceof CatalogType) {
return set(path, ((CatalogType) value).getId());
} else if (value instanceof Integer || value instanceof Byte || value instanceof Short || value instanceof Float || value instanceof Double || value instanceof Long || value instanceof String || value instanceof Character || value instanceof Boolean) {
this.map.put(key, value);
return this;
} else if (manager != null && (optDataTypeSerializer = manager.getTypeSerializer(typeToken = TypeToken.of(value.getClass()))).isPresent()) {
final DataTypeSerializer serializer = optDataTypeSerializer.get();
final Object serialized = serializer.serialize(typeToken, manager.getTypeSerializerContext(), value);
if (serialized instanceof DataContainer) {
final DataContainer container = (DataContainer) serialized;
checkArgument(!container.equals(this), "Cannot insert self-referencing Objects!");
// see above for why this is copied
copyDataView(path, container);
} else {
this.map.put(key, serialized);
}
} else if (value instanceof Collection) {
setCollection(key, (Collection) value);
} else if (value instanceof Map) {
setMap(key, (Map) value);
} else if (value.getClass().isArray()) {
if (this.safety == SafetyMode.ALL_DATA_CLONED || this.safety == SafetyMode.CLONED_ON_SET) {
if (value instanceof byte[]) {
this.map.put(key, ArrayUtils.clone((byte[]) value));
} else if (value instanceof short[]) {
this.map.put(key, ArrayUtils.clone((short[]) value));
} else if (value instanceof int[]) {
this.map.put(key, ArrayUtils.clone((int[]) value));
} else if (value instanceof long[]) {
this.map.put(key, ArrayUtils.clone((long[]) value));
} else if (value instanceof float[]) {
this.map.put(key, ArrayUtils.clone((float[]) value));
} else if (value instanceof double[]) {
this.map.put(key, ArrayUtils.clone((double[]) value));
} else if (value instanceof boolean[]) {
this.map.put(key, ArrayUtils.clone((boolean[]) value));
} else {
this.map.put(key, ArrayUtils.clone((Object[]) value));
}
} else {
this.map.put(key, value);
}
} else {
this.map.put(key, value);
}
return this;
}
use of org.spongepowered.api.data.DataView in project LanternServer by LanternPowered.
the class AnvilChunkIOService method read.
@Override
public boolean read(LanternChunk chunk) throws IOException {
final int x = chunk.getX();
final int z = chunk.getZ();
final RegionFile region = this.cache.getRegionFileByChunk(x, z);
final int regionX = x & REGION_MASK;
final int regionZ = z & REGION_MASK;
final DataInputStream is = region.getChunkDataInputStream(regionX, regionZ);
if (is == null) {
return false;
}
final DataView levelDataView;
try (NbtDataContainerInputStream nbt = new NbtDataContainerInputStream(is)) {
levelDataView = nbt.read().getView(LEVEL).get();
}
// read the vertical sections
final List<DataView> sectionList = levelDataView.getViewList(SECTIONS).get();
final ChunkSection[] sections = new ChunkSection[16];
// noinspection unchecked
final Short2ObjectOpenHashMap<LanternTileEntity>[] tileEntitySections = new Short2ObjectOpenHashMap[sections.length];
for (DataView sectionTag : sectionList) {
final int y = sectionTag.getInt(Y).get();
final byte[] rawTypes = (byte[]) sectionTag.get(BLOCKS).get();
final byte[] extTypes = sectionTag.contains(BLOCKS_EXTRA) ? (byte[]) sectionTag.get(BLOCKS_EXTRA).get() : null;
final byte[] data = (byte[]) sectionTag.get(DATA).get();
final byte[] blockLight = (byte[]) sectionTag.get(BLOCK_LIGHT).get();
final byte[] skyLight = (byte[]) sectionTag.get(SKY_LIGHT).get();
final NibbleArray dataArray = new NibbleArray(rawTypes.length, data, true);
final NibbleArray extTypesArray = extTypes == null ? null : new NibbleArray(rawTypes.length, extTypes, true);
final short[] types = new short[rawTypes.length];
for (int i = 0; i < rawTypes.length; i++) {
types[i] = (short) ((extTypesArray == null ? 0 : extTypesArray.get(i)) << 12 | ((rawTypes[i] & 0xff) << 4) | dataArray.get(i));
}
tileEntitySections[y] = new Short2ObjectOpenHashMap<>();
sections[y] = new ChunkSection(types, new NibbleArray(rawTypes.length, skyLight, true), new NibbleArray(rawTypes.length, blockLight, true), tileEntitySections[y]);
}
levelDataView.getViewList(TILE_ENTITIES).ifPresent(tileEntityViews -> {
final ObjectSerializer<LanternTileEntity> tileEntitySerializer = ObjectSerializerRegistry.get().get(LanternTileEntity.class).get();
for (DataView tileEntityView : tileEntityViews) {
final int tileY = tileEntityView.getInt(TILE_ENTITY_Y).get();
final int section = tileY >> 4;
if (tileEntitySections[section] == null) {
continue;
}
final int tileZ = tileEntityView.getInt(TILE_ENTITY_Z).get();
final int tileX = tileEntityView.getInt(TILE_ENTITY_X).get();
try {
final LanternTileEntity tileEntity = tileEntitySerializer.deserialize(tileEntityView);
tileEntity.setLocation(new Location<>(this.world, tileX, tileY, tileZ));
tileEntity.setValid(true);
tileEntitySections[section].put((short) ChunkSection.index(tileX & 0xf, tileY & 0xf, tileZ & 0xf), tileEntity);
} catch (InvalidDataException e) {
this.logger.warn("Error loading tile entity at ({};{};{}) in the chunk ({},{}) in the world {}", tileX & 0xf, tileY & 0xf, tileZ & 0xf, x, z, getWorldProperties().getWorldName(), e);
}
}
});
final DataView spongeDataView = levelDataView.getView(DataQueries.SPONGE_DATA).orElse(null);
final List<DataView> trackerDataViews = spongeDataView == null ? null : levelDataView.getViewList(TRACKER_DATA_TABLE).orElse(null);
// noinspection unchecked
final Short2ObjectMap<LanternChunk.TrackerData>[] trackerData = chunk.getTrackerData().getRawObjects();
if (trackerDataViews != null) {
for (DataView dataView : trackerDataViews) {
final Optional<Short> optIndex = dataView.getShort(TRACKER_BLOCK_POS);
if (!optIndex.isPresent()) {
continue;
}
final int creatorId = dataView.getInt(TRACKER_ENTRY_CREATOR).orElse(-1);
final int notifierId = dataView.getInt(TRACKER_ENTRY_NOTIFIER).orElse(-1);
// index = z << 12 | y << 4 | x
int index = optIndex.get() & 0xffff;
final int section = (index >> 8) & 0xf;
// Convert the index to the section based system
// index = y << 8 | z << 4 | x
index = ChunkSection.index(index & 0xf, (index >> 4) & 0xf, index >> 12);
trackerData[section].put((short) index, new LanternChunk.TrackerData(creatorId, notifierId));
}
}
// initialize the chunk
chunk.initializeSections(sections);
chunk.setPopulated(levelDataView.getInt(TERRAIN_POPULATED).orElse(0) > 0);
if (levelDataView.contains(BIOMES)) {
final byte[] biomes = (byte[]) levelDataView.get(BIOMES).get();
final byte[] biomesExtra = (byte[]) (levelDataView.contains(BIOMES_EXTRA) ? levelDataView.get(BIOMES_EXTRA).get() : null);
final short[] newBiomes = new short[biomes.length];
for (int i = 0; i < biomes.length; i++) {
newBiomes[i] = (short) ((biomesExtra == null ? 0 : biomesExtra[i]) << 8 | biomes[i]);
}
chunk.initializeBiomes(newBiomes);
}
final Object heightMap;
if (levelDataView.contains(HEIGHT_MAP) && (heightMap = levelDataView.get(HEIGHT_MAP).get()) instanceof int[]) {
chunk.initializeHeightMap((int[]) heightMap);
} else {
chunk.initializeHeightMap(null);
}
levelDataView.getLong(INHABITED_TIME).ifPresent(time -> chunk.setInhabitedTime(time.intValue()));
chunk.setLightPopulated(levelDataView.getInt(LIGHT_POPULATED).orElse(0) > 0);
chunk.initializeLight();
levelDataView.getViewList(ENTITIES).ifPresent(entityViews -> {
final ObjectSerializer<LanternEntity> entitySerializer = ObjectSerializerRegistry.get().get(LanternEntity.class).get();
for (DataView entityView : entityViews) {
try {
final LanternEntity entity = entitySerializer.deserialize(entityView);
final int ySection = fixEntityYSection(entity.getPosition().getFloorY() >> 4);
chunk.addEntity(entity, ySection);
} catch (InvalidDataException e) {
this.logger.warn("Error loading entity in the chunk ({},{}) in the world {}", x, z, getWorldProperties().getWorldName(), e);
}
}
});
return true;
}
use of org.spongepowered.api.data.DataView in project LanternServer by LanternPowered.
the class IdentifiableObjectSerializer method serialize.
@Override
public DataView serialize(T object) {
final DataView dataView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
if (this.objectStore instanceof IdentifiableObjectStore) {
((IdentifiableObjectStore) this.objectStore).serializeUniqueId(dataView, object.getUniqueId());
}
this.objectStore.serialize(object, dataView);
return dataView;
}
Aggregations