- Some minor cleanup
 - Test for null id, not for null PlotBlock
 - Small fixes to schematic saving (still broken)
This commit is contained in:
dordsor21 2018-12-20 23:33:24 +00:00
parent 341e386df8
commit 90682e9f8b
8 changed files with 187 additions and 213 deletions

View File

@ -124,7 +124,6 @@ public class BukkitChunkManager extends ChunkManager {
final World oldWorld = Bukkit.getWorld(pos1.getWorld());
final World newWorld = Bukkit.getWorld(newPos.getWorld());
final String newWorldName = newWorld.getName();
List<ChunkLoc> chunks = new ArrayList<>();
final ContentMap map = new ContentMap();
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(newWorldName, false);
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@ -144,27 +143,23 @@ public class BukkitChunkManager extends ChunkManager {
}
}
}
}, new Runnable() {
@Override public void run() {
for (Entry<PlotLoc, PlotBlock[]> entry : map.allBlocks.entrySet()) {
PlotLoc loc = entry.getKey();
PlotBlock[] blocks = entry.getValue();
for (int y = 0; y < blocks.length; y++) {
}, () -> {
for (Entry<PlotLoc, PlotBlock[]> entry : map.allBlocks.entrySet()) {
PlotLoc loc = entry.getKey();
PlotBlock[] blocks = entry.getValue();
for (int y = 0; y < blocks.length; y++) {
if (blocks[y] != null) {
PlotBlock block = blocks[y];
if (block != null) {
queue.setBlock(loc.x, y, loc.z, block);
}
queue.setBlock(loc.x, y, loc.z, block);
}
}
queue.enqueue();
GlobalBlockQueue.IMP.addTask(new Runnable() {
@Override public void run() {
map.restoreBlocks(newWorld, 0, 0);
map.restoreEntities(newWorld, relX, relZ);
TaskManager.runTask(whenDone);
}
});
}
queue.enqueue();
GlobalBlockQueue.IMP.addTask(() -> {
map.restoreBlocks(newWorld, 0, 0);
map.restoreEntities(newWorld, relX, relZ);
TaskManager.runTask(whenDone);
});
}, 5);
return true;
}
@ -211,11 +206,8 @@ public class BukkitChunkManager extends ChunkManager {
RegionWrapper currentPlotClear =
new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
AugmentedUtils.bypass(ignoreAugment, new Runnable() {
@Override public void run() {
queue.regenChunkSafe(chunk.x, chunk.z);
}
});
AugmentedUtils.bypass(ignoreAugment,
() -> queue.regenChunkSafe(chunk.x, chunk.z));
continue;
}
boolean checkX1 = false;
@ -278,43 +270,39 @@ public class BukkitChunkManager extends ChunkManager {
map.saveRegion(worldObj, xxt2, xxt, zzt2, zzt); //
}
map.saveEntitiesOut(chunkObj, currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, new Runnable() {
@Override public void run() {
setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
@Override public void run(ScopedLocalBlockQueue value) {
com.github.intellectualsites.plotsquared.plot.object.Location
min = value.getMin();
int bx = min.getX();
int bz = min.getZ();
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
PlotLoc loc = new PlotLoc(bx + x, bz + z);
PlotBlock[] ids = map.allBlocks.get(loc);
if (ids != null) {
for (int y = 0;
y < Math.min(128, ids.length); y++) {
PlotBlock id = ids[y];
if (id != null) {
value.setBlock(x, y, z, id);
} else {
value.setBlock(x, y, z,
PlotBlock.get("air"));
}
}
for (int y = Math.min(128, ids.length);
y < ids.length; y++) {
PlotBlock id = ids[y];
if (id != null) {
value.setBlock(x, y, z, id);
}
}
AugmentedUtils.bypass(ignoreAugment, () -> setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
@Override public void run(ScopedLocalBlockQueue value) {
com.github.intellectualsites.plotsquared.plot.object.Location
min = value.getMin();
int bx = min.getX();
int bz = min.getZ();
for (int x1 = 0; x1 < 16; x1++) {
for (int z1 = 0; z1 < 16; z1++) {
PlotLoc loc = new PlotLoc(bx + x1, bz + z1);
PlotBlock[] ids = map.allBlocks.get(loc);
if (ids != null) {
for (int y = 0;
y < Math.min(128, ids.length); y++) {
PlotBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
} else {
value.setBlock(x1, y, z1,
PlotBlock.get("air"));
}
}
for (int y = Math.min(128, ids.length);
y < ids.length; y++) {
PlotBlock id = ids[y];
if (id != null) {
value.setBlock(x1, y, z1, id);
}
}
}
}
}, world, chunk);
}
}
});
}, world, chunk));
map.restoreBlocks(worldObj, 0, 0);
map.restoreEntities(worldObj, 0, 0);
}
@ -359,11 +347,8 @@ public class BukkitChunkManager extends ChunkManager {
public void unloadChunk(final String world, final ChunkLoc loc, final boolean save,
final boolean safe) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask(new Runnable() {
@SuppressWarnings("deprecation") @Override public void run() {
BukkitUtil.getWorld(world).unloadChunk(loc.x, loc.z, save, safe);
}
});
TaskManager.runTask(
() -> BukkitUtil.getWorld(world).unloadChunk(loc.x, loc.z, save, safe));
} else {
BukkitUtil.getWorld(world).unloadChunk(loc.x, loc.z, save, safe);
}

View File

@ -33,7 +33,7 @@ public class BukkitSchematicHandler extends SchematicHandler {
// Main positions
Location[] corners = MainUtil.getCorners(world, regions);
final Location bot = corners[0];
Location top = corners[1];
final Location top = corners[1];
CuboidRegion cuboidRegion =
new CuboidRegion(BukkitUtil.IMP.getWeWorld(world), bot.getBlockVector3(),
@ -59,7 +59,6 @@ public class BukkitSchematicHandler extends SchematicHandler {
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
schematic.put("Offset", new IntArrayTag(new int[] {0, 0, 0,}));
final int[] paletteMax = {0};
Map<String, Integer> palette = new HashMap<>();
List<CompoundTag> tileEntities = new ArrayList<>();
@ -69,24 +68,20 @@ public class BukkitSchematicHandler extends SchematicHandler {
TaskManager.runTask(new Runnable() {
@Override public void run() {
if (queue.isEmpty()) {
TaskManager.runTaskAsync(new Runnable() {
@Override public void run() {
schematic.put("PaletteMax", new IntTag(paletteMax[0]));
TaskManager.runTaskAsync(() -> {
schematic.put("PaletteMax", new IntTag(palette.size()));
Map<String, Tag> paletteTag = new HashMap<>();
palette.forEach(
(key, value) -> paletteTag.put(key, new IntTag(value)));
Map<String, Tag> paletteTag = new HashMap<>();
palette.forEach(
(key, value) -> paletteTag.put(key, new IntTag(value)));
schematic.put("Palette", new CompoundTag(paletteTag));
schematic
.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
schematic.put("TileEntities",
new ListTag(CompoundTag.class, tileEntities));
whenDone.value = new CompoundTag(schematic);
TaskManager.runTask(whenDone);
System.gc();
System.gc();
}
schematic.put("Palette", new CompoundTag(paletteTag));
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
schematic.put("TileEntities",
new ListTag(CompoundTag.class, tileEntities));
whenDone.value = new CompoundTag(schematic);
TaskManager.runTask(whenDone);
System.gc();
});
return;
}
@ -147,13 +142,10 @@ public class BukkitSchematicHandler extends SchematicHandler {
}
for (int y = sy; y <= Math.min(255, ey); y++) {
int ry = y - sy;
int i1 = ry * width * length;
for (int z = zzb; z <= zzt; z++) {
int rz = z - bz;
int i2 = i1 + rz * width;
for (int x = xxb; x <= xxt; x++) {
int rx = x - bx;
int index = i2 + rx;
BlockVector3 point = BlockVector3.at(x, y, z);
BaseBlock block =
cuboidRegion.getWorld().getFullBlock(point);
@ -164,9 +156,8 @@ public class BukkitSchematicHandler extends SchematicHandler {
values
.put(entry.getKey(), entry.getValue());
}
values.remove(
"id"); // Remove 'id' if it exists. We want 'Id'
// Remove 'id' if it exists. We want 'Id'
values.remove("id");
// Positions are kept in NBT, we don't want that.
values.remove("x");
@ -176,7 +167,7 @@ public class BukkitSchematicHandler extends SchematicHandler {
values
.put("Id", new StringTag(block.getNbtId()));
values.put("Pos",
new IntArrayTag(new int[] {x, y, z}));
new IntArrayTag(new int[] {rx, ry, rz}));
tileEntities.add(new CompoundTag(values));
}
@ -186,9 +177,8 @@ public class BukkitSchematicHandler extends SchematicHandler {
if (palette.containsKey(blockKey)) {
blockId = palette.get(blockKey);
} else {
blockId = paletteMax[0];
palette.put(blockKey, blockId);
paletteMax[0]++;
blockId = palette.size();
palette.put(blockKey, palette.size());
}
while ((blockId & -128) != 0) {

View File

@ -87,8 +87,8 @@ public class BukkitLocalQueue<T> extends BasicLocalBlockQueue<T> {
PlotBlock[] blocksLayer = (PlotBlock[]) lc.blocks[layer];
if (blocksLayer != null) {
for (int j = 0; j < blocksLayer.length; j++) {
PlotBlock block = blocksLayer[j];
if (block != null) {
if (blocksLayer[j] != null) {
PlotBlock block = blocksLayer[j];
int x = MainUtil.x_loc[layer][j];
int y = MainUtil.y_loc[layer][j];
int z = MainUtil.z_loc[layer][j];

View File

@ -24,8 +24,8 @@ public class HybridGen extends IndependentPlotGenerator {
String[] blocks = world.G_SCH.get(MathMan.pair(relativeX, relativeZ));
if (blocks != null) {
for (int y = 0; y < blocks.length; y++) {
PlotBlock block = PlotBlock.get(blocks[y]);
if (block != null) {
if (blocks[y] != null) {
PlotBlock block = PlotBlock.get(blocks[y]);
result.setBlock(x, minY + y, z, block);
}
}

View File

@ -92,8 +92,8 @@ public class HybridPlotManager extends ClassicPlotManager {
String[] blocks = hpw.G_SCH.get(MathMan.pair(absX, absZ));
if (blocks != null) {
for (int y = 0; y < blocks.length; y++) {
PlotBlock block = PlotBlock.get(blocks[y]);
if (block != null) {
if (blocks[y] != null) {
PlotBlock block = PlotBlock.get(blocks[y]);
queue.setBlock(x, minY + y, z, block);
}
}

View File

@ -3,10 +3,7 @@ package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.schematic.Schematic;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
@ -146,7 +143,9 @@ public class HybridPlotWorld extends ClassicPlotWorld {
int minY = Math.min(PLOT_HEIGHT, ROAD_HEIGHT);
if (schematic3 != null) {
this.PLOT_SCHEMATIC = true;
BlockVector3 d3 = schematic3.getClipboard().getDimensions();
BlockArrayClipboard blockArrayClipboard3 = schematic3.getClipboard();
BlockVector3 d3 = blockArrayClipboard3.getDimensions();
short w3 = (short) d3.getX();
short l3 = (short) d3.getZ();
short h3 = (short) d3.getY();
@ -168,51 +167,50 @@ public class HybridPlotWorld extends ClassicPlotWorld {
int startY = minY - PLOT_HEIGHT;
// for (short x = 0; x < w3; x++) {
// for (short z = 0; z < l3; z++) {
// for (short y = 0; y < h3; y++) {
// int index = (y * w3 * l3) + (z * w3) + x;
// short id = ids[index];
// byte data = datas[index];
// if (id != 0) {
// addOverlayBlock((short) (x + shift + oddshift + centerShiftX),
// (short) (y + startY), (short) (z + shift + oddshift + centerShiftZ),
// id, data, false, h3);
// }
// }
// }
// }
// HashMap<BlockLoc, CompoundTag> items = schematic3.getTiles();
// if (!items.isEmpty()) {
// this.G_SCH_STATE = new HashMap<>();
// outer:
// for (Map.Entry<BlockLoc, CompoundTag> entry : items.entrySet()) {
// BlockLoc loc = entry.getKey();
// short x = (short) (loc.x + shift + oddshift + centerShiftX);
// short z = (short) (loc.z + shift + oddshift + centerShiftZ);
// short y = (short) (loc.y + this.PLOT_HEIGHT);
// int pair = MathMan.pair(x, z);
// HashMap<Integer, CompoundTag> existing = this.G_SCH_STATE.get(pair);
// if (existing == null) {
// existing = new HashMap<>();
// this.G_SCH_STATE.put(pair, existing);
// }
// existing.put((int) y, entry.getValue());
//
// CompoundTag tag = entry.getValue();
// Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
// for (int i = 1; i <= 4; i++) {
// String ln = tag.getString("Line" + i);
// if (ln == null || ln.length() > 11)
// continue outer;
// }
// SIGN_LOCATION =
// new Location(worldname, loc.x + centerShiftX, this.PLOT_HEIGHT + loc.y,
// loc.z + centerShiftZ);
// ALLOW_SIGNS = true;
// continue outer;
// }
// }
for (short x = 0; x < w3; x++) {
for (short z = 0; z < l3; z++) {
for (short y = 0; y < h3; y++) {
BaseBlock id = blockArrayClipboard3.getFullBlock(BlockVector3.at(x, y, z))
.toBaseBlock();
if (!id.getBlockType().getId().toLowerCase().contains("air")) {
addOverlayBlock((short) (x + shift + oddshift + centerShiftX),
(short) (y + startY), (short) (z + shift + oddshift + centerShiftZ),
id, false, h3);
}
}
}
}
/* HashMap<BlockLoc, CompoundTag> items = schematic3.getTiles();
if (!items.isEmpty()) {
this.G_SCH_STATE = new HashMap<>();
outer:
for (Map.Entry<BlockLoc, CompoundTag> entry : items.entrySet()) {
BlockLoc loc = entry.getKey();
short x = (short) (loc.x + shift + oddshift + centerShiftX);
short z = (short) (loc.z + shift + oddshift + centerShiftZ);
short y = (short) (loc.y + this.PLOT_HEIGHT);
int pair = MathMan.pair(x, z);
HashMap<Integer, CompoundTag> existing = this.G_SCH_STATE.get(pair);
if (existing == null) {
existing = new HashMap<>();
this.G_SCH_STATE.put(pair, existing);
}
existing.put((int) y, entry.getValue());
CompoundTag tag = entry.getValue();
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue());
for (int i = 1; i <= 4; i++) {
String ln = tag.getString("Line" + i);
if (ln == null || ln.length() > 11)
continue outer;
}
SIGN_LOCATION =
new Location(worldname, loc.x + centerShiftX, this.PLOT_HEIGHT + loc.y,
loc.z + centerShiftZ);
ALLOW_SIGNS = true;
continue outer;
}
}*/
}
if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) {
PlotSquared.debug(C.PREFIX + "&3 - schematic: &7false");

View File

@ -356,8 +356,8 @@ public abstract class HybridUtils {
int minY = Math.min(plotWorld.PLOT_HEIGHT, plotWorld.ROAD_HEIGHT);
if (blocks != null) {
for (int y = 0; y < blocks.length; y++) {
PlotBlock block = PlotBlock.get(blocks[y]);
if (block != null) {
if ((blocks[y] != null) {
PlotBlock block = PlotBlock.get(blocks[y]);
queue.setBlock(x + X + plotWorld.ROAD_OFFSET_X, minY + y,
z + Z + plotWorld.ROAD_OFFSET_Z, block);
}
@ -365,11 +365,9 @@ public abstract class HybridUtils {
}
}
}
}
queue.enqueue();
} queue.enqueue();
return true;
}
}
return false;
} return false;
}
}

View File

@ -11,12 +11,8 @@ import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.schematic.Schematic;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader;
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
import com.sk89q.worldedit.extent.clipboard.io.*;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
@ -118,13 +114,14 @@ public abstract class SchematicHandler {
* @return boolean true if succeeded
*/
public void paste(final Schematic schematic, final Plot plot, final int xOffset,
final int yOffset, final int zOffset, final boolean autoHeight, final Runnable whenDone) {
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(WorldUtil.IMP.getWeWorld(plot.getWorldName()), -1);
final int yOffset, final int zOffset, final boolean autoHeight,
final RunnableVal<Boolean> whenDone) {
TaskManager.runTask(new Runnable() {
@Override public void run() {
if (whenDone != null) {
whenDone.value = false;
}
if (schematic == null) {
PlotSquared.debug("Schematic == null :|");
TaskManager.runTask(whenDone);
@ -191,62 +188,63 @@ public abstract class SchematicHandler {
final int bcz = p1z >> 4;
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
final ArrayList<ChunkLoc> chunks = new ArrayList<>();
/* final ArrayList<ChunkLoc> chunks = new ArrayList<>();
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
chunks.add(new ChunkLoc(x, z));
}
}
}*/
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
int count = 0;
while (!chunks.isEmpty() && count < 256) {
count++;
ChunkLoc chunk = chunks.remove(0);
int x = chunk.x;
int z = chunk.z;
int xxb = x << 4;
int zzb = z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (x == bcx) {
xxb = p1x;
}
if (x == tcx) {
xxt = p2x;
}
if (z == bcz) {
zzb = p1z;
}
if (z == tcz) {
zzt = p2z;
}
// Paste schematic here
//int count = 0;
//while (!chunks.isEmpty() && count < 256) {
//count++;
ChunkLoc chunk = new ChunkLoc(value[0], value[1]);
PlotSquared.log(chunk.toString());
int x = chunk.x;
int z = chunk.z;
int xxb = x << 4;
int zzb = z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (x == bcx) {
xxb = p1x;
}
if (x == tcx) {
xxt = p2x;
}
if (z == bcz) {
zzb = p1z;
}
if (z == tcz) {
zzt = p2z;
}
// Paste schematic here
for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) {
int yy = y_offset_actual + ry;
if (yy > 255) {
continue;
}
int i1 = ry * WIDTH * LENGTH;
for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) {
int i2 = (rz * WIDTH) + i1;
for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) {
int i = i2 + rx;
int xx = p1x + rx;
int zz = p1z + rz;
BaseBlock id = blockArrayClipboard
.getFullBlock(BlockVector3.at(rx, ry, rz));
queue.setBlock(xx, yy, zz, id);
}
for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) {
int yy = y_offset_actual + ry;
if (yy > 255) {
continue;
}
int i1 = ry * WIDTH * LENGTH;
for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) {
int i2 = (rz * WIDTH) + i1;
for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) {
int i = i2 + rx;
int xx = p1x + rx;
int zz = p1z + rz;
BaseBlock id = blockArrayClipboard
.getFullBlock(BlockVector3.at(rx, ry, rz));
queue.setBlock(xx, yy, zz, id);
}
}
}
/* }
if (!chunks.isEmpty()) {
this.run();
} else {
queue.flush();
/*HashMap<BlockLoc, CompoundTag> tiles = schematic.getClipboard().getTiles();
HashMap<BlockLoc, CompoundTag> tiles = schematic.getClipboard().getTiles();
if (!tiles.isEmpty()) {
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override public void run(Object value) {
@ -259,10 +257,14 @@ public abstract class SchematicHandler {
}
}
});
}*/
}
}
}*/
}
}, whenDone, 10);
}, null, 10);
if (whenDone != null) {
whenDone.value = true;
whenDone.run();
}
} catch (Exception e) {
e.printStackTrace();
TaskManager.runTask(whenDone);
@ -327,14 +329,15 @@ public abstract class SchematicHandler {
return null;
}
try {
if (BuiltInClipboardFormat.SPONGE_SCHEMATIC.isFormat(file)) {
SpongeSchematicReader ssr =
new SpongeSchematicReader(new NBTInputStream(new FileInputStream(file)));
ClipboardFormat format = ClipboardFormats.findByFile(file);
if (format == BuiltInClipboardFormat.SPONGE_SCHEMATIC) {
SpongeSchematicReader ssr = new SpongeSchematicReader(
new NBTInputStream(new GZIPInputStream(new FileInputStream(file))));
BlockArrayClipboard clip = (BlockArrayClipboard) ssr.read();
return new Schematic(clip);
} else if (BuiltInClipboardFormat.MCEDIT_SCHEMATIC.isFormat(file)) {
MCEditSchematicReader msr =
new MCEditSchematicReader(new NBTInputStream(new FileInputStream(file)));
} else if (format == BuiltInClipboardFormat.MCEDIT_SCHEMATIC) {
MCEditSchematicReader msr = new MCEditSchematicReader(
new NBTInputStream(new GZIPInputStream(new FileInputStream(file))));
BlockArrayClipboard clip = (BlockArrayClipboard) msr.read();
return new Schematic(clip);
} else {
@ -446,9 +449,9 @@ public abstract class SchematicHandler {
try {
File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path);
tmp.getParentFile().mkdirs();
try (OutputStream stream = new FileOutputStream(tmp);
NBTOutputStream output = new NBTOutputStream(new GZIPOutputStream(stream))) {
output.writeNamedTag("Schematic", tag);
try (NBTOutputStream nbtStream = new NBTOutputStream(
new GZIPOutputStream(new FileOutputStream(tmp)))) {
nbtStream.writeNamedTag("Schematic", tag);
}
} catch (FileNotFoundException e) {
e.printStackTrace();