use of org.spongepowered.api.data.persistence.DataView in project SpongeCommon by SpongePowered.
the class DataUtil method setSpongeData.
public static void setSpongeData(final DataView allData, final DataQuery dataStoreKey, final DataView pluginData, final int version) {
final DataQuery dataStoreDataQuery = Constants.Sponge.Data.V3.SPONGE_DATA_ROOT.then(dataStoreKey);
final DataView dataStoreDataView = allData.getView(dataStoreDataQuery).orElseGet(() -> allData.createView(dataStoreDataQuery));
dataStoreDataView.set(Constants.Sponge.Data.V3.CONTENT_VERSION, version);
dataStoreDataView.set(Constants.Sponge.Data.V3.CONTENT, pluginData);
}
use of org.spongepowered.api.data.persistence.DataView in project SpongeCommon by SpongePowered.
the class MemoryDataView method remove.
@Override
public DataView remove(final DataQuery path) {
Objects.requireNonNull(path, "path");
final List<String> parts = path.parts();
if (parts.size() > 1) {
final String subKey = parts.get(0);
final DataQuery subQuery = DataQuery.of(subKey);
final Optional<DataView> subViewOptional = this.getUnsafeView(subQuery);
if (!subViewOptional.isPresent()) {
return this;
}
final DataView subView = subViewOptional.get();
subView.remove(path.popFirst());
} else {
this.map.remove(parts.get(0));
}
return this;
}
use of org.spongepowered.api.data.persistence.DataView in project SpongeCommon by SpongePowered.
the class SchematicTranslator method translate.
@Override
public Schematic translate(final DataView unprocessed) throws InvalidDataException {
if (SchematicTranslator.VANILLA_FIXER == null) {
SchematicTranslator.VANILLA_FIXER = SpongeCommon.server().getFixerUpper();
}
final DataView schematicView = unprocessed.getView(Constants.Sponge.Schematic.SCHEMATIC).orElse(unprocessed);
final int version = schematicView.getInt(Constants.Sponge.Schematic.VERSION).get();
if (version > Constants.Sponge.Schematic.CURRENT_VERSION) {
throw new InvalidDataException(String.format("Unknown schematic version %d (current version is %d)", version, Constants.Sponge.Schematic.CURRENT_VERSION));
} else if (version == 1) {
SchematicTranslator.V2_TO_3.update(SchematicTranslator.V1_TO_2.update(schematicView));
} else if (version == 2) {
SchematicTranslator.V2_TO_3.update(schematicView);
}
final int dataVersion = schematicView.getInt(Constants.Sponge.Schematic.DATA_VERSION).get();
// DataFixer will be able to upgrade entity and tile entity data if and only if we're running a valid server and
// the data version is outdated.
final boolean needsFixers = dataVersion < SharedConstants.getCurrentVersion().getWorldVersion() && SchematicTranslator.VANILLA_FIXER != null;
final DataView updatedView;
if (needsFixers) {
final CompoundTag compound = NBTTranslator.INSTANCE.translate(schematicView);
final CompoundTag updated = NbtUtils.update(SchematicTranslator.VANILLA_FIXER, DataFixTypes.CHUNK, compound, dataVersion);
updatedView = NBTTranslator.INSTANCE.translate(updated);
} else {
updatedView = schematicView;
}
final SpongeSchematicBuilder builder = new SpongeSchematicBuilder();
final Optional<DataView> metadataView = updatedView.getView(Constants.Sponge.Schematic.METADATA);
metadataView.ifPresent(metadata -> {
metadata.getView(DataQuery.of(".")).ifPresent(data -> {
for (final DataQuery key : data.keys(false)) {
if (!metadata.contains(key)) {
metadata.set(key, data.get(key).get());
}
}
});
final String schematicName = metadata.getString(Constants.Sponge.Schematic.NAME).orElse("unknown");
metadata.getStringList(Constants.Sponge.Schematic.REQUIRED_MODS).ifPresent(mods -> {
for (final String modId : mods) {
if (!Sponge.pluginManager().plugin(modId).isPresent()) {
if (SchematicTranslator.MISSING_MOD_IDS.add(modId)) {
SpongeCommon.logger().warn("When attempting to load the Schematic: {} there is a missing modid {} some blocks/tiles/entities may not load correctly.", schematicName, modId);
}
}
}
});
final DataContainer meta = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
for (final DataQuery key : metadata.keys(false)) {
meta.set(key, metadata.get(key).get());
}
builder.metadata(meta);
});
final int width = updatedView.getShort(Constants.Sponge.Schematic.WIDTH).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.WIDTH));
final int height = updatedView.getShort(Constants.Sponge.Schematic.HEIGHT).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.HEIGHT));
final int length = updatedView.getShort(Constants.Sponge.Schematic.LENGTH).orElseThrow(() -> new InvalidDataException("Missing value for: " + Constants.Sponge.Schematic.LENGTH));
if (width <= 0 || height <= 0 || length <= 0) {
throw new InvalidDataException(String.format("Schematic is larger than maximum allowable size (found: (%d, %d, %d) max: (%d, %<d, %<d)", width, height, length, Constants.Sponge.Schematic.MAX_SIZE));
}
final int[] offsetArray = (int[]) updatedView.get(Constants.Sponge.Schematic.OFFSET).orElse(new int[3]);
if (offsetArray.length != 3) {
throw new InvalidDataException("Schematic offset was not of length 3");
}
final Vector3i offset = new Vector3i(offsetArray[0], offsetArray[1], offsetArray[2]);
final SpongeArchetypeVolume archetypeVolume = new SpongeArchetypeVolume(offset, new Vector3i(width, height, length), Sponge.server());
updatedView.getView(Constants.Sponge.Schematic.BLOCK_CONTAINER).ifPresent(blocks -> SchematicTranslator.deserializeBlockContainer(blocks, archetypeVolume, width, length, offset, needsFixers));
updatedView.getView(Constants.Sponge.Schematic.BIOME_CONTAINER).ifPresent(biomes -> SchematicTranslator.deserializeBiomeContainer(biomes, archetypeVolume, width, length, offset));
updatedView.getViewList(Constants.Sponge.Schematic.ENTITIES).map(List::stream).orElse(Stream.of()).filter(entity -> entity.contains(Constants.Sponge.Schematic.ENTITIES_POS, Constants.Sponge.Schematic.ENTITIES_ID)).map(SchematicTranslator.deserializeEntityArchetype()).filter(Optional::isPresent).map(Optional::get).forEach(archetypeVolume::addEntity);
builder.volume(archetypeVolume);
return builder.build();
}
use of org.spongepowered.api.data.persistence.DataView in project SpongeCommon by SpongePowered.
the class SchematicTranslator method deserializeBiomeContainer.
private static void deserializeBiomeContainer(final DataView view, final SpongeArchetypeVolume archetypeVolume, final int width, final int length, final Vector3i offset) {
final MutableBimapPalette<Biome, Biome> biomePalette;
final DataView biomeMap = view.getView(Constants.Sponge.Schematic.BIOME_PALETTE).orElseThrow(() -> new InvalidDataException("Missing BiomePalette as required by the schematic spec"));
final Set<DataQuery> biomeKeys = biomeMap.keys(false);
final Registry<Biome> biomeRegistry = VolumeStreamUtils.nativeToSpongeRegistry(BuiltinRegistries.BIOME);
biomePalette = new MutableBimapPalette<>(PaletteTypes.BIOME_PALETTE.get(), biomeRegistry, RegistryTypes.BIOME, biomeKeys.size());
for (final DataQuery biomeKey : biomeKeys) {
final ResourceKey key = ResourceKey.resolve(biomeKey.parts().get(0));
final Biome biome = biomeRegistry.findValue(key).get();
biomePalette.assign(biome, biomeMap.getInt(biomeKey).get());
}
final byte[] biomeData = (byte[]) view.get(Constants.Sponge.Schematic.BIOME_DATA).orElseThrow(() -> new InvalidDataException("Missing BlockData for Schematic"));
SchematicTranslator.readByteArrayData(width, (width * length), offset, biomePalette, biomeData, archetypeVolume, BiomeVolume.Modifiable::setBiome);
}
use of org.spongepowered.api.data.persistence.DataView in project SpongeCommon by SpongePowered.
the class SchematicTranslator method addTo.
@Override
public DataView addTo(final Schematic schematic, final DataView data) {
final int xMin = schematic.min().x();
final int yMin = schematic.min().y();
final int zMin = schematic.min().z();
final int width = schematic.size().x();
final int height = schematic.size().y();
final int length = schematic.size().z();
if (width > Constants.Sponge.Schematic.MAX_SIZE || height > Constants.Sponge.Schematic.MAX_SIZE || length > Constants.Sponge.Schematic.MAX_SIZE) {
throw new IllegalArgumentException(String.format("Schematic is larger than maximum allowable size (found: (%d, %d, %d) max: (%d, %<d, %<d)", width, height, length, Constants.Sponge.Schematic.MAX_SIZE));
}
data.set(Constants.Sponge.Schematic.WIDTH, (short) width);
data.set(Constants.Sponge.Schematic.HEIGHT, (short) height);
data.set(Constants.Sponge.Schematic.LENGTH, (short) length);
data.set(Constants.Sponge.Schematic.VERSION, Constants.Sponge.Schematic.CURRENT_VERSION);
data.set(Constants.Sponge.Schematic.DATA_VERSION, SharedConstants.getCurrentVersion().getWorldVersion());
for (final DataQuery metaKey : schematic.metadata().keys(false)) {
data.set(Constants.Sponge.Schematic.METADATA.then(metaKey), schematic.metadata().get(metaKey).get());
}
final Set<String> requiredMods = new HashSet<>();
final int[] offset = new int[] { xMin, yMin, zMin };
data.set(Constants.Sponge.Schematic.OFFSET, offset);
// Check if we have blocks to store
if (schematic.blockPalette().highestId() != 0) {
final DataView blockData = data.createView(Constants.Sponge.Schematic.BLOCK_CONTAINER);
final Palette.Mutable<BlockState, BlockType> palette = schematic.blockPalette().asMutable(Sponge.server());
try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length)) {
for (int y = 0; y < height; y++) {
final int y0 = yMin + y;
for (int z = 0; z < length; z++) {
final int z0 = zMin + z;
for (int x = 0; x < width; x++) {
final int x0 = xMin + x;
final BlockState state = schematic.block(x0, y0, z0);
SchematicTranslator.writeIdToBuffer(buffer, palette.orAssign(state));
}
}
}
blockData.set(Constants.Sponge.Schematic.BLOCK_DATA, buffer.toByteArray());
} catch (final IOException e) {
// should never reach here
}
final Registry<BlockType> blockRegistry = VolumeStreamUtils.nativeToSpongeRegistry(net.minecraft.core.Registry.BLOCK);
SchematicTranslator.writePaletteToView(blockData, palette, blockRegistry, Constants.Sponge.Schematic.BLOCK_PALETTE, BlockState::type, requiredMods);
final List<DataView> blockEntities = schematic.blockEntityArchetypes().entrySet().stream().map(entry -> {
final DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
final Vector3i pos = entry.getKey();
final BlockEntityArchetype archetype = entry.getValue();
final DataContainer entityData = archetype.blockEntityData();
final int[] apos = new int[] { pos.x() - xMin, pos.y() - yMin, pos.z() - zMin };
container.set(Constants.Sponge.Schematic.BLOCKENTITY_POS, apos);
container.set(Constants.Sponge.Schematic.BLOCKENTITY_DATA, entityData);
final ResourceKey key = archetype.blockEntityType().key(RegistryTypes.BLOCK_ENTITY_TYPE);
container.set(Constants.Sponge.Schematic.ENTITIES_ID, key.asString());
final String namespace = key.namespace();
if (!ResourceKey.MINECRAFT_NAMESPACE.equals(namespace)) {
requiredMods.add(namespace);
}
return container;
}).collect(Collectors.toList());
blockData.set(Constants.Sponge.Schematic.BLOCKENTITY_CONTAINER, blockEntities);
}
if (schematic.biomePalette().highestId() != 0) {
final DataView biomeContainer = data.createView(Constants.Sponge.Schematic.BIOME_CONTAINER);
final Palette.Mutable<Biome, Biome> biomePalette = schematic.biomePalette().asMutable(Sponge.game());
try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length)) {
for (int y = 0; y < height; y++) {
final int y0 = yMin + y;
for (int z = 0; z < length; z++) {
final int z0 = zMin + z;
for (int x = 0; x < width; x++) {
final int x0 = xMin + x;
final Biome state = schematic.biome(x0, y0, z0);
SchematicTranslator.writeIdToBuffer(buffer, biomePalette.orAssign(state));
}
}
}
biomeContainer.set(Constants.Sponge.Schematic.BIOME_DATA, buffer.toByteArray());
} catch (final IOException e) {
// Should never reach here.
}
final Registry<Biome> biomeRegistry = VolumeStreamUtils.nativeToSpongeRegistry(BuiltinRegistries.BIOME);
SchematicTranslator.writePaletteToView(biomeContainer, biomePalette, biomeRegistry, Constants.Sponge.Schematic.BIOME_PALETTE, Function.identity(), requiredMods);
}
final List<DataView> entities = schematic.entityArchetypesByPosition().stream().map(entry -> {
final DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
final List<Double> entityPosition = new ArrayList<>();
entityPosition.add(entry.position().x());
entityPosition.add(entry.position().y());
entityPosition.add(entry.position().z());
container.set(Constants.Sponge.Schematic.ENTITIES_POS, entityPosition);
final ResourceKey key = entry.archetype().type().key(RegistryTypes.ENTITY_TYPE);
if (!ResourceKey.MINECRAFT_NAMESPACE.equals(key.namespace())) {
requiredMods.add(key.namespace());
}
container.set(Constants.Sponge.Schematic.ENTITIES_ID, key.toString());
final DataContainer entityData = entry.archetype().entityData();
container.set(Constants.Sponge.Schematic.BLOCKENTITY_DATA, entityData);
return container;
}).collect(Collectors.toList());
data.set(Constants.Sponge.Schematic.ENTITIES, entities);
if (!requiredMods.isEmpty()) {
data.set(Constants.Sponge.Schematic.METADATA.then(Constants.Sponge.Schematic.REQUIRED_MODS), requiredMods);
}
return data;
}
Aggregations