mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-05 20:36:42 +00:00
Reorder BuildInClipboardFormat and document changed JNBT classes (#807)
* Get rid of FastSchematicReader/Writer and document changed JNBT classes This commit includes changes from upstream to the schematic classes (`com.sk89q.worldedit.extent.clipboard.io`). It also documents the JNBT classes, specifying what has been changed in FAWE. This was done in preparation for the upcoming move to adventure-nbt. The PlotSquared schematic handler classes will now use SpongeSchematicReader/Writer rather than FastSchematicReader/Writer. This is yet untested and the entire branch is a W.I.P. * Fix JNBT mutability misuse in FAWE FAWE previously had mutable compound and list tags. The previous commit changed that, and this commit will fix misuse of the tag API. I've tried to identify the places where mutability was assumed, but I might have missed something. This needs quite extensive testing. This is yet another change which increases upstream compatibility in FAWE. * Fix FAWE_Spigot_<..>#getEntity * Fix JNBT usage in the AsyncBlockState code * Readd FastSchematicReader/Writer and add a new schematic format (`FAST`) * Update dead repository * Implement missing AsyncChunk#getTileEntities * handle entities properly and add "brokenentity" format * Fix fast schematic reader lazily reading means it's read in order of appearance in the inputstream so we need to read schematic version first (skip past everything) and then reset the stream * Fix p2 FAWE * Go back to fast schematics in P2/CompressedSchematicTag (#819) * Fix compile Co-authored-by: N0tMyFaultOG <mc.cache@web.de> Co-authored-by: Alexander Söderberg <Sauilitired@users.noreply.github.com> Co-authored-by: dordsor21 <dordsor21@gmail.com> Co-authored-by: Aurora <aurora@relanet.eu>
This commit is contained in:
committed by
GitHub
parent
efcca5b66f
commit
3f0b9a2a92
@ -86,40 +86,6 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The Schematic format used by MCEdit.
|
||||
*/
|
||||
MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") {
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schematic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
SchematicReader input = new SchematicReader(nbtStream);
|
||||
input.setUnderlyingStream(inputStream);
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new IOException("This format does not support saving, use `schem` or `sponge` as format"); // Is more helpful
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
String name = file.getName().toLowerCase(Locale.ROOT);
|
||||
return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce");
|
||||
}
|
||||
},
|
||||
|
||||
SPONGE_SCHEMATIC("sponge", "schem") {
|
||||
|
||||
@Override
|
||||
@ -160,6 +126,48 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The Schematic format used by MCEdit.
|
||||
*/
|
||||
MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") {
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schematic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream));
|
||||
return new MCEditSchematicReader(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new IOException("This format does not support saving");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Materials")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") {
|
||||
|
||||
@Override
|
||||
|
@ -58,6 +58,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -350,7 +351,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
y = pos[1];
|
||||
z = pos[2];
|
||||
}
|
||||
Map<String, Tag> values = tile.getValue();
|
||||
Map<String, Tag> values = new HashMap<>(tile.getValue());
|
||||
Tag id = values.get("Id");
|
||||
if (id != null) {
|
||||
values.put("x", new IntTag(x));
|
||||
@ -361,17 +362,14 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
values.remove("Id");
|
||||
values.remove("Pos");
|
||||
|
||||
tile = fixBlockEntity(tile);
|
||||
clipboard.setTile(x, y, z, tile);
|
||||
clipboard.setTile(x, y, z, fixBlockEntity(new CompoundTag(values)));
|
||||
}
|
||||
}
|
||||
|
||||
// entities
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (Map<String, Object> entRaw : entities) {
|
||||
CompoundTag ent = FaweCache.IMP.asTag(entRaw);
|
||||
|
||||
Map<String, Tag> value = ent.getValue();
|
||||
Map<String, Tag> value = new HashMap<>(FaweCache.IMP.asTag(entRaw).getValue());
|
||||
StringTag id = (StringTag) value.get("Id");
|
||||
if (id == null) {
|
||||
id = (StringTag) value.get("id");
|
||||
@ -384,7 +382,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
|
||||
EntityType type = EntityTypes.parse(id.getValue());
|
||||
if (type != null) {
|
||||
ent = fixEntity(ent);
|
||||
final CompoundTag ent = fixEntity(new CompoundTag(value));
|
||||
BaseEntity state = new BaseEntity(type, ent);
|
||||
Location loc = ent.getEntityLocation(clipboard);
|
||||
if (brokenEntities) {
|
||||
|
@ -121,15 +121,16 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
outputStream.writeLazyCompoundTag("Schematic", out -> {
|
||||
out.writeNamedTag("DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion());
|
||||
out.writeNamedTag("Version", CURRENT_VERSION);
|
||||
out.writeNamedTag("FAWE", Fawe.get().getVersion().build);
|
||||
out.writeNamedTag("Width", (short) width);
|
||||
out.writeNamedTag("Height", (short) height);
|
||||
out.writeNamedTag("Length", (short) length);
|
||||
|
||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||
out.writeNamedTag("Offset", new int[]{
|
||||
min.getBlockX(),
|
||||
min.getBlockY(),
|
||||
min.getBlockZ(),
|
||||
min.getBlockX(),
|
||||
min.getBlockY(),
|
||||
min.getBlockZ(),
|
||||
});
|
||||
|
||||
out.writeLazyCompoundTag("Metadata", out1 -> {
|
||||
@ -162,7 +163,7 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
BaseBlock block = pos.getFullBlock(finalClipboard);
|
||||
CompoundTag nbt = block.getNbtData();
|
||||
if (nbt != null) {
|
||||
Map<String, Tag> values = nbt.getValue();
|
||||
Map<String, Tag> values = new HashMap<>(nbt.getValue());
|
||||
|
||||
// Positions are kept in NBT, we don't want that.
|
||||
values.remove("x");
|
||||
@ -175,12 +176,13 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
// Dum.
|
||||
values.remove("id");
|
||||
values.put("Pos", new IntArrayTag(new int[]{
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ()
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ()
|
||||
}));
|
||||
numTiles++;
|
||||
tilesOut.writeTagPayload(block.getNbtData());
|
||||
|
||||
tilesOut.writeTagPayload(new CompoundTag(values));
|
||||
}
|
||||
|
||||
int ordinal = block.getOrdinal();
|
||||
|
@ -1,4 +0,0 @@
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
public class FaweFormat {
|
||||
}
|
@ -68,26 +68,24 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Reads schematic files that are compatible with MCEdit and other editors.
|
||||
* @deprecated Use SchematicStreamer
|
||||
*/
|
||||
@Deprecated
|
||||
public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
||||
private final NBTInputStream inputStream;
|
||||
private final DataFixer fixer;
|
||||
private static final ImmutableList<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS
|
||||
= ImmutableList.of(
|
||||
new SignCompatibilityHandler(),
|
||||
new FlowerPotCompatibilityHandler(),
|
||||
new NoteBlockCompatibilityHandler(),
|
||||
new SkullBlockCompatibilityHandler(),
|
||||
new BannerBlockCompatibilityHandler(),
|
||||
new BedBlockCompatibilityHandler()
|
||||
= ImmutableList.of(
|
||||
new SignCompatibilityHandler(),
|
||||
new FlowerPotCompatibilityHandler(),
|
||||
new NoteBlockCompatibilityHandler(),
|
||||
new SkullBlockCompatibilityHandler(),
|
||||
new BannerBlockCompatibilityHandler(),
|
||||
new BedBlockCompatibilityHandler()
|
||||
);
|
||||
private static final ImmutableList<EntityNBTCompatibilityHandler> ENTITY_COMPATIBILITY_HANDLERS
|
||||
= ImmutableList.of(
|
||||
new Pre13HangingCompatibilityHandler()
|
||||
= ImmutableList.of(
|
||||
new Pre13HangingCompatibilityHandler()
|
||||
);
|
||||
|
||||
/**
|
||||
@ -99,8 +97,8 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
checkNotNull(inputStream);
|
||||
this.inputStream = inputStream;
|
||||
this.fixer = null;
|
||||
//com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability(
|
||||
//com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer();
|
||||
//com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability(
|
||||
//com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -207,7 +205,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
if (newBlock != null) {
|
||||
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
||||
if (handler.isAffectedBlock(newBlock)) {
|
||||
newBlock = handler.updateNBT(block, values);
|
||||
newBlock = handler.updateNBT(block, values).toImmutableState();
|
||||
if (newBlock == null || values.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
@ -256,7 +254,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
int combined = block << 8 | data;
|
||||
if (unknownBlocks.add(combined)) {
|
||||
log.warn("Unknown block when loading schematic: "
|
||||
+ block + ":" + data + ". This is most likely a bad schematic.");
|
||||
+ block + ":" + data + ". This is most likely a bad schematic.");
|
||||
}
|
||||
}
|
||||
} catch (WorldEditException ignored) { // BlockArrayClipboard won't throw this
|
||||
@ -302,7 +300,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
|
||||
private String convertEntityId(String id) {
|
||||
switch(id) {
|
||||
switch (id) {
|
||||
case "AreaEffectCloud": return "area_effect_cloud";
|
||||
case "ArmorStand": return "armor_stand";
|
||||
case "CaveSpider": return "cave_spider";
|
||||
|
@ -1,536 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.jnbt.streamer.StreamDelegate;
|
||||
import com.boydti.fawe.jnbt.streamer.ValueReader;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BannerBlockCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BedBlockCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.EntityNBTCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.FlowerPotCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NBTCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NoteBlockCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.Pre13HangingCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SignCompatibilityHandler;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SkullBlockCompatibilityHandler;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockCategories;
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypeSwitch;
|
||||
import com.sk89q.worldedit.world.block.BlockTypeSwitchBuilder;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
/**
|
||||
* Reads schematic files based that are compatible with MCEdit and other editors.
|
||||
*/
|
||||
public class SchematicReader implements ClipboardReader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SchematicReader.class);
|
||||
|
||||
private static final NBTCompatibilityHandler[] COMPATIBILITY_HANDLERS = {
|
||||
new SignCompatibilityHandler(),
|
||||
new FlowerPotCompatibilityHandler(),
|
||||
new NoteBlockCompatibilityHandler(),
|
||||
new SkullBlockCompatibilityHandler(),
|
||||
new BannerBlockCompatibilityHandler(),
|
||||
new BedBlockCompatibilityHandler()
|
||||
};
|
||||
private static final EntityNBTCompatibilityHandler[] ENTITY_COMPATIBILITY_HANDLERS = {
|
||||
new Pre13HangingCompatibilityHandler()
|
||||
};
|
||||
|
||||
private NBTInputStream inputStream;
|
||||
private InputStream rootStream;
|
||||
|
||||
// private final DataFixer fixer; TODO
|
||||
|
||||
private FastByteArrayOutputStream idOut = new FastByteArrayOutputStream();
|
||||
private FastByteArrayOutputStream dataOut = new FastByteArrayOutputStream();
|
||||
private FastByteArrayOutputStream addOut;
|
||||
private FastByteArrayOutputStream biomesOut;
|
||||
|
||||
private FaweOutputStream ids;
|
||||
private FaweOutputStream datas;
|
||||
private FaweOutputStream adds;
|
||||
private FaweOutputStream biomes;
|
||||
|
||||
private List<Map<String, Object>> tiles;
|
||||
private List<Map<String, Object>> entities;
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private int length;
|
||||
private int offsetX;
|
||||
private int offsetY;
|
||||
private int offsetZ;
|
||||
private int originX;
|
||||
private int originY;
|
||||
private int originZ;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
*/
|
||||
public SchematicReader(NBTInputStream inputStream) {
|
||||
checkNotNull(inputStream);
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
public void setUnderlyingStream(InputStream in) {
|
||||
this.rootStream = in;
|
||||
}
|
||||
|
||||
public StreamDelegate createDelegate() {
|
||||
StreamDelegate root = new StreamDelegate();
|
||||
StreamDelegate schematic = root.add("Schematic");
|
||||
schematic.add("Width").withInt((i, v) -> width = v);
|
||||
schematic.add("Height").withInt((i, v) -> height = v);
|
||||
schematic.add("Length").withInt((i, v) -> length = v);
|
||||
|
||||
schematic.add("WEOriginX").withInt((i, v) -> originX = v);
|
||||
schematic.add("WEOriginY").withInt((i, v) -> originY = v);
|
||||
schematic.add("WEOriginZ").withInt((i, v) -> originZ = v);
|
||||
|
||||
StreamDelegate metadata = schematic.add("Metadata");
|
||||
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
||||
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
||||
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
||||
|
||||
StreamDelegate blocksDelegate = schematic.add("Blocks");
|
||||
blocksDelegate.withInfo((length, type) -> ids = new FaweOutputStream(new LZ4BlockOutputStream(idOut)));
|
||||
blocksDelegate.withInt((index, value) -> ids.write(value));
|
||||
|
||||
StreamDelegate dataDelegate = schematic.add("Data");
|
||||
dataDelegate.withInfo((length, type) -> datas = new FaweOutputStream(new LZ4BlockOutputStream(dataOut)));
|
||||
dataDelegate.withInt((index, value) -> datas.write(value));
|
||||
|
||||
StreamDelegate addDelegate = schematic.add("AddBlocks");
|
||||
addDelegate.withInfo((length, type) -> {
|
||||
addOut = new FastByteArrayOutputStream();
|
||||
adds = new FaweOutputStream(new LZ4BlockOutputStream(addOut));
|
||||
});
|
||||
addDelegate.withInt((index, value) -> {
|
||||
if (value != 0) {
|
||||
int first = value & 0x0F;
|
||||
int second = (value & 0xF0) >> 4;
|
||||
adds.write(first);
|
||||
adds.write(second);
|
||||
} else {
|
||||
adds.write(0);
|
||||
adds.write(0);
|
||||
}
|
||||
});
|
||||
|
||||
StreamDelegate tilesDelegate = schematic.add("TileEntities");
|
||||
tilesDelegate.withInfo((length, type) -> tiles = new ArrayList<>(length));
|
||||
tilesDelegate.withElem((ValueReader<Map<String, Object>>) (index, tile) -> tiles.add(tile));
|
||||
|
||||
StreamDelegate entitiesDelegate = schematic.add("Entities");
|
||||
entitiesDelegate.withInfo((length, type) -> entities = new ArrayList<>(length));
|
||||
entitiesDelegate.withElem(
|
||||
(ValueReader<Map<String, Object>>) (index, entity) -> entities.add(entity));
|
||||
return root;
|
||||
}
|
||||
|
||||
private int readCombined(InputStream idIn, InputStream dataIn) throws IOException {
|
||||
return ((idIn.read() & 0xFF) << 4) + (dataIn.read() & 0xF);
|
||||
}
|
||||
|
||||
private int readCombined(InputStream idIn, InputStream dataIn, InputStream addIn) throws IOException {
|
||||
return ((addIn.read() & 0xFF) << 8) + readCombined(idIn, dataIn);
|
||||
}
|
||||
|
||||
private BlockState getBlock(int combined) {
|
||||
BlockState state = LegacyMapper.getInstance().getBlockFromLegacyCombinedId(combined);
|
||||
return state;
|
||||
}
|
||||
|
||||
private void write(int index, BlockState block, LinearClipboard clipboard) {
|
||||
clipboard.setBlock(index, block);
|
||||
}
|
||||
|
||||
private void write(int x, int y, int z, BlockState block, Clipboard clipboard) {
|
||||
clipboard.setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
private void readwrite(int index, InputStream idIn, InputStream dataIn, LinearClipboard out) throws IOException {
|
||||
readwrite(index, readCombined(idIn, dataIn), out);
|
||||
}
|
||||
|
||||
private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, Clipboard out) throws IOException {
|
||||
readwrite(x, y, z, readCombined(idIn, dataIn), out);
|
||||
}
|
||||
|
||||
private void readwrite(int index, InputStream idIn, InputStream dataIn, InputStream addIn, LinearClipboard out) throws IOException {
|
||||
readwrite(index, readCombined(idIn, dataIn, addIn), out);
|
||||
}
|
||||
|
||||
private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, InputStream addIn, Clipboard out) throws IOException {
|
||||
readwrite(x, y, z, readCombined(idIn, dataIn, addIn), out);
|
||||
}
|
||||
|
||||
private void readwrite(int index, int combined, LinearClipboard out) throws IOException {
|
||||
write(index, getBlock(combined), out);
|
||||
}
|
||||
|
||||
private void readwrite(int x, int y, int z, int combined, Clipboard out) throws IOException {
|
||||
write(x, y, z, getBlock(combined), out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
try {
|
||||
return readInternal(uuid, createOutput);
|
||||
} catch (EOFException e) {
|
||||
log.error("EOFException read in schematic. Did you give the schematic the wrong extension?");
|
||||
log.error("We will attempt to rectify your mistake for you and load the schematic assuming it is named .schem not .schematic");
|
||||
e.printStackTrace();
|
||||
final InputStream stream;
|
||||
if (rootStream instanceof FileInputStream) {
|
||||
stream = new ResettableFileInputStream((FileInputStream) rootStream);
|
||||
} else {
|
||||
stream = rootStream;
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(stream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
return (new FastSchematicReader(nbtStream)).read(uuid, createOutput);
|
||||
}
|
||||
}
|
||||
|
||||
private Clipboard readInternal(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
StreamDelegate root = createDelegate();
|
||||
inputStream.readNamedTagLazy(root);
|
||||
|
||||
if (ids != null) {
|
||||
ids.close();
|
||||
}
|
||||
if (datas != null) {
|
||||
datas.close();
|
||||
}
|
||||
if (adds != null) {
|
||||
adds.close();
|
||||
}
|
||||
if (biomes != null) {
|
||||
biomes.close();
|
||||
}
|
||||
ids = null;
|
||||
datas = null;
|
||||
adds = null;
|
||||
biomes = null;
|
||||
|
||||
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
||||
BlockVector3 origin = BlockVector3.ZERO;
|
||||
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
||||
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
||||
}
|
||||
|
||||
Clipboard clipboard = createOutput.apply(dimensions);
|
||||
try (InputStream dataIn = new LZ4BlockInputStream(new FastByteArraysInputStream(dataOut.toByteArrays())); InputStream idIn = new LZ4BlockInputStream(new FastByteArraysInputStream(idOut.toByteArrays()))) {
|
||||
if (addOut != null) {
|
||||
try (FaweInputStream addIn = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(addOut.toByteArrays())))) {
|
||||
if (clipboard instanceof LinearClipboard) {
|
||||
LinearClipboard linear = (LinearClipboard) clipboard;
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
readwrite(index, idIn, dataIn, addIn, linear);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
readwrite(x, y, z, idIn, dataIn, addIn, clipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (clipboard instanceof LinearClipboard) {
|
||||
LinearClipboard linear = (LinearClipboard) clipboard;
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
readwrite(index, idIn, dataIn, linear);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
readwrite(x, y, z, idIn, dataIn, clipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tiles
|
||||
if (tiles != null && !tiles.isEmpty()) {
|
||||
outer:
|
||||
for (Map<String, Object> tileRaw : tiles) {
|
||||
CompoundTag tile = FaweCache.IMP.asTag(tileRaw);
|
||||
int x = (int) tileRaw.get("x");
|
||||
int y = (int) tileRaw.get("y");
|
||||
int z = (int) tileRaw.get("z");
|
||||
|
||||
BlockState block = clipboard.getBlock(x, y, z);
|
||||
for (NBTCompatibilityHandler compat : COMPATIBILITY_HANDLERS) {
|
||||
if (compat.isAffectedBlock(block)) {
|
||||
block = compat.updateNBT(block, tile.getValue());
|
||||
BaseBlock baseBlock = block.toBaseBlock(tile);
|
||||
clipboard.setBlock(x, y, z, baseBlock);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
clipboard.setTile(x, y, z, tile);
|
||||
}
|
||||
}
|
||||
|
||||
// entities
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (Map<String, Object> entRaw : entities) {
|
||||
String id = (String) entRaw.get("id");
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
entRaw.put("Id", id);
|
||||
EntityType type = EntityTypes.parse(id);
|
||||
if (type != null) {
|
||||
CompoundTag ent = FaweCache.IMP.asTag(entRaw);
|
||||
for (EntityNBTCompatibilityHandler compat : ENTITY_COMPATIBILITY_HANDLERS) {
|
||||
if (compat.isAffectedEntity(type, ent)) {
|
||||
ent = compat.updateNBT(type, ent);
|
||||
}
|
||||
}
|
||||
BaseEntity state = new BaseEntity(type, ent);
|
||||
Location loc = ent.getEntityLocation(clipboard);
|
||||
clipboard.createEntity(loc, state);
|
||||
} else {
|
||||
getLogger(SchematicReader.class).debug("Invalid entity: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
fixStates(clipboard);
|
||||
clipboard.setOrigin(origin);
|
||||
|
||||
BlockVector3 min = BlockVector3.at(originX, originY, originZ);
|
||||
if (!min.equals(BlockVector3.ZERO)) {
|
||||
clipboard = new BlockArrayClipboard(clipboard, min);
|
||||
}
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
private void fixStates(Clipboard fc) {
|
||||
for (BlockVector3 pos : fc) {
|
||||
BlockState block = pos.getBlock(fc);
|
||||
if (block.getMaterial().isAir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
|
||||
BlockType type = block.getBlockType();
|
||||
if (BlockCategories.STAIRS.contains(type)) {
|
||||
Direction facing = block.getState(PropertyKey.FACING);
|
||||
|
||||
BlockVector3 forward = facing.toBlockVector();
|
||||
Direction left = facing.getLeft();
|
||||
Direction right = facing.getRight();
|
||||
|
||||
BlockState forwardBlock = fc.getBlock(x + forward.getBlockX(), y + forward.getBlockY(), z + forward.getBlockZ());
|
||||
BlockType forwardType = forwardBlock.getBlockType();
|
||||
if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) {
|
||||
Direction forwardFacing = forwardBlock.getState(PropertyKey.FACING);
|
||||
if (forwardFacing == left) {
|
||||
BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
|
||||
BlockType rightType = rightBlock.getBlockType();
|
||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "inner_left"));
|
||||
}
|
||||
return;
|
||||
} else if (forwardFacing == right) {
|
||||
BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
|
||||
BlockType leftType = leftBlock.getBlockType();
|
||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BlockState backwardsBlock = fc.getBlock(x - forward.getBlockX(), y - forward.getBlockY(), z - forward.getBlockZ());
|
||||
BlockType backwardsType = backwardsBlock.getBlockType();
|
||||
if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) {
|
||||
Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING);
|
||||
if (backwardsFacing == left) {
|
||||
BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
|
||||
BlockType rightType = rightBlock.getBlockType();
|
||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_left"));
|
||||
}
|
||||
return;
|
||||
} else if (backwardsFacing == right) {
|
||||
BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
|
||||
BlockType leftType = leftBlock.getBlockType();
|
||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_right"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int group = group(type);
|
||||
if (group == -1) {
|
||||
return;
|
||||
}
|
||||
BlockState set = block;
|
||||
|
||||
if (set.getState(PropertyKey.NORTH) == Boolean.FALSE && merge(fc, group, x, y, z - 1)) {
|
||||
set = set.with(PropertyKey.NORTH, true);
|
||||
}
|
||||
if (set.getState(PropertyKey.EAST) == Boolean.FALSE && merge(fc, group, x + 1, y, z)) {
|
||||
set = set.with(PropertyKey.EAST, true);
|
||||
}
|
||||
if (set.getState(PropertyKey.SOUTH) == Boolean.FALSE && merge(fc, group, x, y, z + 1)) {
|
||||
set = set.with(PropertyKey.SOUTH, true);
|
||||
}
|
||||
if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(fc, group, x - 1, y, z)) {
|
||||
set = set.with(PropertyKey.WEST, true);
|
||||
}
|
||||
|
||||
if (group == 2) {
|
||||
int ns = (set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0);
|
||||
int ew = (set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0);
|
||||
if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) {
|
||||
set = set.with(PropertyKey.UP, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (set != block) {
|
||||
pos.setBlock(fc, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private BlockTypeSwitch<Boolean> fullCube = new BlockTypeSwitchBuilder<>(false).add(type -> {
|
||||
BlockMaterial mat = type.getMaterial();
|
||||
return (mat.isFullCube() && !mat.isFragileWhenPushed() && mat.getLightValue() == 0 && mat.isOpaque() && mat.isSolid() && !mat.isTranslucent());
|
||||
}, true).build();
|
||||
|
||||
private boolean merge(Clipboard fc, int group, int x, int y, int z) {
|
||||
BlockState block = fc.getBlock(x, y, z);
|
||||
BlockType type = block.getBlockType();
|
||||
return group(type) == group || fullCube.apply(type);
|
||||
}
|
||||
|
||||
private int group(BlockType type) {
|
||||
switch (type.getInternalId()) {
|
||||
case BlockID.ACACIA_FENCE:
|
||||
case BlockID.BIRCH_FENCE:
|
||||
case BlockID.DARK_OAK_FENCE:
|
||||
case BlockID.JUNGLE_FENCE:
|
||||
case BlockID.OAK_FENCE:
|
||||
case BlockID.SPRUCE_FENCE:
|
||||
return 0;
|
||||
case BlockID.NETHER_BRICK_FENCE:
|
||||
return 1;
|
||||
case BlockID.COBBLESTONE_WALL:
|
||||
case BlockID.MOSSY_COBBLESTONE_WALL:
|
||||
return 2;
|
||||
case BlockID.IRON_BARS:
|
||||
case BlockID.BLACK_STAINED_GLASS_PANE:
|
||||
case BlockID.BLUE_STAINED_GLASS_PANE:
|
||||
case BlockID.BROWN_MUSHROOM_BLOCK:
|
||||
case BlockID.BROWN_STAINED_GLASS_PANE:
|
||||
case BlockID.CYAN_STAINED_GLASS_PANE:
|
||||
case BlockID.GLASS_PANE:
|
||||
case BlockID.GRAY_STAINED_GLASS_PANE:
|
||||
case BlockID.GREEN_STAINED_GLASS_PANE:
|
||||
case BlockID.LIGHT_BLUE_STAINED_GLASS_PANE:
|
||||
case BlockID.LIGHT_GRAY_STAINED_GLASS_PANE:
|
||||
case BlockID.LIME_STAINED_GLASS_PANE:
|
||||
case BlockID.MAGENTA_STAINED_GLASS_PANE:
|
||||
case BlockID.ORANGE_STAINED_GLASS_PANE:
|
||||
case BlockID.PINK_STAINED_GLASS_PANE:
|
||||
case BlockID.PURPLE_STAINED_GLASS_PANE:
|
||||
case BlockID.RED_STAINED_GLASS_PANE:
|
||||
case BlockID.WHITE_STAINED_GLASS_PANE:
|
||||
case BlockID.YELLOW_STAINED_GLASS_PANE:
|
||||
return 3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
@ -68,7 +68,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Reads schematic files using the Sponge Schematic Specification.
|
||||
*/
|
||||
@Deprecated // High mem usage + slow
|
||||
public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
|
||||
@ -93,7 +92,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
|
||||
final Platform platform = WorldEdit.getInstance().getPlatformManager()
|
||||
.queryCapability(Capability.WORLD_EDITING);
|
||||
.queryCapability(Capability.WORLD_EDITING);
|
||||
int liveDataVersion = platform.getDataVersion();
|
||||
|
||||
if (schematicVersion == 1) {
|
||||
@ -102,17 +101,23 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
return readVersion1(schematicTag);
|
||||
} else if (schematicVersion == 2) {
|
||||
dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||
if (dataVersion < 0) {
|
||||
log.warn("Schematic has an unknown data version ({}). Data may be incompatible.",
|
||||
dataVersion);
|
||||
// Do not DFU unknown data
|
||||
dataVersion = liveDataVersion;
|
||||
}
|
||||
if (dataVersion > liveDataVersion) {
|
||||
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
||||
dataVersion, liveDataVersion);
|
||||
dataVersion, liveDataVersion);
|
||||
} else if (dataVersion < liveDataVersion) {
|
||||
fixer = platform.getDataFixer();
|
||||
if (fixer != null) {
|
||||
log.debug("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.",
|
||||
dataVersion, liveDataVersion);
|
||||
dataVersion, liveDataVersion);
|
||||
} else {
|
||||
log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.",
|
||||
dataVersion, liveDataVersion);
|
||||
dataVersion, liveDataVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +135,11 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
if (schematicVersion == 1) {
|
||||
return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2);
|
||||
} else if (schematicVersion == 2) {
|
||||
return OptionalInt.of(requireTag(schematic, "DataVersion", IntTag.class).getValue());
|
||||
int dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||
if (dataVersion < 0) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
return OptionalInt.of(dataVersion);
|
||||
}
|
||||
return OptionalInt.empty();
|
||||
} catch (IOException e) {
|
||||
@ -140,9 +149,6 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private CompoundTag getBaseTag() throws IOException {
|
||||
NamedTag rootTag = inputStream.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
throw new IOException("Tag 'Schematic' does not exist or is not first");
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
@ -226,9 +232,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
if (tileEntities != null) {
|
||||
List<Map<String, Tag>> tileEntityTags = tileEntities.getValue().stream()
|
||||
.map(tag -> (CompoundTag) tag)
|
||||
.map(CompoundTag::getValue)
|
||||
.collect(Collectors.toList());
|
||||
.map(tag -> (CompoundTag) tag)
|
||||
.map(CompoundTag::getValue)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Map<String, Tag> tileEntity : tileEntityTags) {
|
||||
int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue();
|
||||
@ -321,8 +327,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
}
|
||||
BiomeType biome = BiomeTypes.get(key);
|
||||
if (biome == null) {
|
||||
log.warn("Unknown biome type :" + key +
|
||||
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
||||
log.warn("Unknown biome type :" + key
|
||||
+ " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
||||
}
|
||||
Tag idTag = palettePart.getValue();
|
||||
if (!(idTag instanceof IntTag)) {
|
||||
@ -385,8 +391,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
EntityType entityType = EntityTypes.get(id);
|
||||
if (entityType != null) {
|
||||
Location location = NBTConversions.toLocation(clipboard,
|
||||
requireTag(tags, "Pos", ListTag.class),
|
||||
requireTag(tags, "Rotation", ListTag.class));
|
||||
requireTag(tags, "Pos", ListTag.class),
|
||||
requireTag(tags, "Rotation", ListTag.class));
|
||||
BaseEntity state = new BaseEntity(entityType, entityTag);
|
||||
clipboard.createEntity(location, state);
|
||||
} else {
|
||||
|
@ -23,8 +23,6 @@ import com.boydti.fawe.Fawe;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.FloatTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
@ -37,7 +35,6 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
@ -57,7 +54,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Writes schematic files using the Sponge schematic format.
|
||||
*/
|
||||
@Deprecated // High mem usage + slow
|
||||
public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
|
||||
private static final int CURRENT_VERSION = 2;
|
||||
@ -109,7 +105,8 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
Map<String, Tag> schematic = new HashMap<>();
|
||||
schematic.put("Version", new IntTag(CURRENT_VERSION));
|
||||
schematic.put("DataVersion", new IntTag(
|
||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
||||
schematic.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build));
|
||||
|
||||
Map<String, Tag> metadata = new HashMap<>();
|
||||
metadata.put("WEOffsetX", new IntTag(offset.getBlockX()));
|
||||
@ -125,9 +122,9 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
|
||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||
schematic.put("Offset", new IntArrayTag(new int[]{
|
||||
min.getBlockX(),
|
||||
min.getBlockY(),
|
||||
min.getBlockZ(),
|
||||
min.getBlockX(),
|
||||
min.getBlockY(),
|
||||
min.getBlockZ(),
|
||||
}));
|
||||
|
||||
int paletteMax = 0;
|
||||
@ -270,21 +267,6 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
schematic.put("Entities", new ListTag(CompoundTag.class, entities));
|
||||
}
|
||||
|
||||
public Tag writeVector(Vector3 vector) {
|
||||
List<DoubleTag> list = new ArrayList<>();
|
||||
list.add(new DoubleTag(vector.getX()));
|
||||
list.add(new DoubleTag(vector.getY()));
|
||||
list.add(new DoubleTag(vector.getZ()));
|
||||
return new ListTag(DoubleTag.class, list);
|
||||
}
|
||||
|
||||
public Tag writeRotation(Location location) {
|
||||
List<FloatTag> list = new ArrayList<>();
|
||||
list.add(new FloatTag(location.getYaw()));
|
||||
list.add(new FloatTag(location.getPitch()));
|
||||
return new ListTag(FloatTag.class, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
|
@ -24,9 +24,8 @@ import com.sk89q.jnbt.CompoundTagBuilder;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.IntegerProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -38,15 +37,15 @@ import java.util.Map;
|
||||
|
||||
public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
|
||||
private static final DirectionalProperty FacingProperty;
|
||||
private static final IntegerProperty RotationProperty;
|
||||
private static final Property<Direction> FacingProperty;
|
||||
private static final Property<Integer> RotationProperty;
|
||||
|
||||
static {
|
||||
DirectionalProperty tempFacing;
|
||||
IntegerProperty tempRotation;
|
||||
Property<Direction> tempFacing;
|
||||
Property<Integer> tempRotation;
|
||||
try {
|
||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.WHITE_WALL_BANNER.getProperty("facing");
|
||||
tempRotation = (IntegerProperty) (Property<?>) BlockTypes.WHITE_BANNER.getProperty("rotation");
|
||||
tempFacing = BlockTypes.WHITE_WALL_BANNER.getProperty("facing");
|
||||
tempRotation = BlockTypes.WHITE_BANNER.getProperty("rotation");
|
||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||
tempFacing = null;
|
||||
tempRotation = null;
|
||||
@ -62,7 +61,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
Tag typeTag = values.get("Base");
|
||||
if (typeTag instanceof IntTag) {
|
||||
boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER;
|
||||
@ -73,10 +72,10 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
||||
BlockState state = type.getDefaultState();
|
||||
|
||||
if (isWall) {
|
||||
Property facingProp = type.getProperty("facing");
|
||||
Property<Direction> facingProp = type.getProperty("facing");
|
||||
state = state.with(facingProp, block.getState(FacingProperty));
|
||||
} else {
|
||||
Property rotationProp = type.getProperty("rotation");
|
||||
Property<Integer> rotationProp = type.getProperty("rotation");
|
||||
state = state.with(rotationProp, block.getState(RotationProperty));
|
||||
}
|
||||
|
||||
@ -102,7 +101,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
||||
}
|
||||
values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList));
|
||||
}
|
||||
return (B) state;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat;
|
||||
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.EnumProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -31,23 +30,24 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("")
|
||||
public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
|
||||
private static final DirectionalProperty FacingProperty;
|
||||
private static final EnumProperty PartProperty;
|
||||
private static final Property<Direction> FACING_PROPERTY;
|
||||
private static final Property<String> PART_PROPERTY;
|
||||
|
||||
static {
|
||||
DirectionalProperty tempFacing;
|
||||
EnumProperty tempPart;
|
||||
Property<Direction> tempFacing;
|
||||
Property<String> tempPart;
|
||||
try {
|
||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.RED_BED.getProperty("facing");
|
||||
tempPart = (EnumProperty) (Property<?>) BlockTypes.RED_BED.getProperty("part");
|
||||
tempFacing = BlockTypes.RED_BED.getProperty("facing");
|
||||
tempPart = BlockTypes.RED_BED.getProperty("part");
|
||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||
tempFacing = null;
|
||||
tempPart = null;
|
||||
}
|
||||
FacingProperty = tempFacing;
|
||||
PartProperty = tempPart;
|
||||
FACING_PROPERTY = tempFacing;
|
||||
PART_PROPERTY = tempPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,7 +56,7 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
Tag typeTag = values.get("color");
|
||||
if (typeTag instanceof IntTag) {
|
||||
String bedType = convertBedType(((IntTag) typeTag).getValue());
|
||||
@ -65,17 +65,17 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
if (type != null) {
|
||||
BlockState state = type.getDefaultState();
|
||||
|
||||
Property facingProp = type.getProperty("facing");
|
||||
state = state.with(facingProp, block.getState(FacingProperty));
|
||||
Property<Direction> facingProp = type.getProperty("facing");
|
||||
state = state.with(facingProp, block.getState(FACING_PROPERTY));
|
||||
|
||||
Property occupiedProp = type.getProperty("occupied");
|
||||
Property<Boolean> occupiedProp = type.getProperty("occupied");
|
||||
state = state.with(occupiedProp, false);
|
||||
|
||||
Property partProp = type.getProperty("part");
|
||||
state = state.with(partProp, block.getState(PartProperty));
|
||||
Property<String> partProp = type.getProperty("part");
|
||||
state = state.with(partProp, block.getState(PART_PROPERTY));
|
||||
|
||||
values.remove("color");
|
||||
return (B) state;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,12 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
Tag item = values.get("Item");
|
||||
if (item instanceof StringTag) {
|
||||
String id = ((StringTag) item).getValue();
|
||||
if (id.isEmpty()) {
|
||||
return (B) BlockTypes.FLOWER_POT.getDefaultState();
|
||||
return BlockTypes.FLOWER_POT.getDefaultState();
|
||||
}
|
||||
int data = 0;
|
||||
Tag dataTag = values.get("Data");
|
||||
@ -52,7 +52,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
BlockState newState = convertLegacyBlockType(id, data);
|
||||
if (newState != null) {
|
||||
values.clear();
|
||||
return (B) newState; // generics pls :\
|
||||
return newState;
|
||||
}
|
||||
}
|
||||
return block;
|
||||
|
@ -26,5 +26,6 @@ import java.util.Map;
|
||||
|
||||
public interface NBTCompatibilityHandler {
|
||||
<B extends BlockStateHolder<B>> boolean isAffectedBlock(B block);
|
||||
<B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values);
|
||||
|
||||
<B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
// note that instrument was not stored (in state or nbt) previously.
|
||||
// it will be updated to the block below when it gets set into the world for the first time
|
||||
Tag noteTag = values.get("note");
|
||||
@ -55,7 +55,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
Byte note = ((ByteTag) noteTag).getValue();
|
||||
if (note != null) {
|
||||
values.clear();
|
||||
return (B) block.with(NoteProperty, (int) note).toImmutableState();
|
||||
return block.with(NoteProperty, (int) note).toImmutableState();
|
||||
}
|
||||
}
|
||||
return block;
|
||||
|
@ -26,8 +26,8 @@ import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.util.DeprecationUtil;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -35,11 +35,11 @@ public class SignCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean isAffectedBlock(B block) {
|
||||
return block.getBlockType() == BlockTypes.SIGN || block.getBlockType() == BlockTypes.WALL_SIGN;
|
||||
return DeprecationUtil.isSign(block.getBlockType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
String key = "Text" + (i + 1);
|
||||
Tag value = values.get(key);
|
||||
|
@ -21,8 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat;
|
||||
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -32,12 +32,12 @@ import java.util.Map;
|
||||
|
||||
public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
|
||||
private static final DirectionalProperty FacingProperty;
|
||||
private static final Property<Direction> FacingProperty;
|
||||
|
||||
static {
|
||||
DirectionalProperty tempFacing;
|
||||
Property<Direction> tempFacing;
|
||||
try {
|
||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.SKELETON_WALL_SKULL.getProperty("facing");
|
||||
tempFacing = BlockTypes.SKELETON_WALL_SKULL.getProperty("facing");
|
||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||
tempFacing = null;
|
||||
}
|
||||
@ -51,7 +51,7 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
||||
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||
boolean isWall = block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL;
|
||||
Tag typeTag = values.get("SkullType");
|
||||
if (typeTag instanceof ByteTag) {
|
||||
@ -61,18 +61,18 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||
if (type != null) {
|
||||
BlockState state = type.getDefaultState();
|
||||
if (isWall) {
|
||||
Property newProp = type.getProperty("facing");
|
||||
Property<Direction> newProp = type.getProperty("facing");
|
||||
state = state.with(newProp, block.getState(FacingProperty));
|
||||
} else {
|
||||
Tag rotTag = values.get("Rot");
|
||||
if (rotTag instanceof ByteTag) {
|
||||
Property newProp = type.getProperty("rotation");
|
||||
Property<Integer> newProp = type.getProperty("rotation");
|
||||
state = state.with(newProp, (int) ((ByteTag) rotTag).getValue());
|
||||
}
|
||||
}
|
||||
values.remove("SkullType");
|
||||
values.remove("Rot");
|
||||
return (B) state;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user