2020-04-16 04:52:39 +02:00
|
|
|
/*
|
|
|
|
* _____ _ _ _____ _
|
|
|
|
* | __ \| | | | / ____| | |
|
|
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
|
|
* | |
|
|
|
|
* |_|
|
|
|
|
* PlotSquared plot management system for Minecraft
|
|
|
|
* Copyright (C) 2020 IntellectualSites
|
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-04-15 21:26:54 +02:00
|
|
|
package com.plotsquared.core.util;
|
2016-02-23 05:11:28 +01:00
|
|
|
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.PlotSquared;
|
2020-04-16 06:14:33 +02:00
|
|
|
import com.plotsquared.core.configuration.Settings;
|
2020-04-15 21:26:54 +02:00
|
|
|
import com.plotsquared.core.generator.ClassicPlotWorld;
|
|
|
|
import com.plotsquared.core.location.Location;
|
|
|
|
import com.plotsquared.core.plot.Plot;
|
|
|
|
import com.plotsquared.core.plot.PlotArea;
|
|
|
|
import com.plotsquared.core.util.uuid.UUIDHandler;
|
|
|
|
import com.plotsquared.core.util.task.RunnableVal;
|
|
|
|
import com.plotsquared.core.plot.schematic.Schematic;
|
|
|
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
|
|
|
import com.plotsquared.core.util.task.TaskManager;
|
2019-05-14 03:57:41 +02:00
|
|
|
import com.sk89q.jnbt.CompoundTag;
|
|
|
|
import com.sk89q.jnbt.NBTInputStream;
|
|
|
|
import com.sk89q.jnbt.NBTOutputStream;
|
2019-11-04 20:55:55 +01:00
|
|
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
2019-05-14 03:57:41 +02:00
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader;
|
|
|
|
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
|
2019-11-04 18:44:23 +01:00
|
|
|
import com.sk89q.worldedit.math.BlockVector2;
|
2018-12-20 00:18:57 +01:00
|
|
|
import com.sk89q.worldedit.math.BlockVector3;
|
2019-11-10 18:47:37 +01:00
|
|
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
2020-03-24 09:08:56 +01:00
|
|
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
2018-12-20 00:18:57 +01:00
|
|
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
2019-05-22 00:32:26 +02:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2020-04-09 17:41:55 +02:00
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2019-11-04 18:44:23 +01:00
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.OutputStream;
|
2016-02-23 05:11:28 +01:00
|
|
|
import java.net.URL;
|
|
|
|
import java.net.URLConnection;
|
|
|
|
import java.nio.channels.Channels;
|
|
|
|
import java.nio.channels.ReadableByteChannel;
|
2019-11-04 18:44:23 +01:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.UUID;
|
2018-12-06 18:01:33 +01:00
|
|
|
import java.util.stream.Collectors;
|
2016-02-23 05:11:28 +01:00
|
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
import java.util.zip.GZIPOutputStream;
|
|
|
|
|
|
|
|
public abstract class SchematicHandler {
|
|
|
|
public static SchematicHandler manager;
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2016-02-23 05:11:28 +01:00
|
|
|
private boolean exportAll = false;
|
2016-03-29 01:30:55 +02:00
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
public boolean exportAll(Collection<Plot> collection, final File outputDir,
|
|
|
|
final String namingScheme, final Runnable ifSuccess) {
|
2016-03-29 01:30:55 +02:00
|
|
|
if (this.exportAll) {
|
2016-02-23 05:11:28 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (collection.isEmpty()) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
this.exportAll = true;
|
2016-03-14 07:18:04 +01:00
|
|
|
final ArrayList<Plot> plots = new ArrayList<>(collection);
|
2016-02-23 05:11:28 +01:00
|
|
|
TaskManager.runTask(new Runnable() {
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void run() {
|
2016-02-23 05:11:28 +01:00
|
|
|
if (plots.isEmpty()) {
|
2016-03-29 01:30:55 +02:00
|
|
|
SchematicHandler.this.exportAll = false;
|
2016-02-23 05:11:28 +01:00
|
|
|
TaskManager.runTask(ifSuccess);
|
|
|
|
return;
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
Iterator<Plot> i = plots.iterator();
|
2016-02-23 05:11:28 +01:00
|
|
|
final Plot plot = i.next();
|
|
|
|
i.remove();
|
2019-05-22 00:32:26 +02:00
|
|
|
String owner = UUIDHandler.getName(plot.guessOwner());
|
|
|
|
if (owner == null) {
|
|
|
|
owner = "unknown";
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
final String name;
|
|
|
|
if (namingScheme == null) {
|
2019-05-22 00:32:26 +02:00
|
|
|
name =
|
|
|
|
plot.getId().x + ";" + plot.getId().y + ',' + plot.getArea() + ',' + owner;
|
2016-02-23 05:11:28 +01:00
|
|
|
} else {
|
2019-05-22 00:32:26 +02:00
|
|
|
name = namingScheme.replaceAll("%owner%", owner)
|
2018-08-10 17:01:10 +02:00
|
|
|
.replaceAll("%id%", plot.getId().toString())
|
|
|
|
.replaceAll("%idx%", plot.getId().x + "")
|
|
|
|
.replaceAll("%idy%", plot.getId().y + "")
|
|
|
|
.replaceAll("%world%", plot.getArea().toString());
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
final String directory;
|
|
|
|
if (outputDir == null) {
|
2016-06-10 19:00:34 +02:00
|
|
|
directory = Settings.Paths.SCHEMATICS;
|
2016-02-23 05:11:28 +01:00
|
|
|
} else {
|
2016-03-11 05:33:18 +01:00
|
|
|
directory = outputDir.getAbsolutePath();
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
final Runnable THIS = this;
|
|
|
|
SchematicHandler.manager.getCompoundTag(plot, new RunnableVal<CompoundTag>() {
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void run(final CompoundTag value) {
|
2016-02-23 05:11:28 +01:00
|
|
|
if (value == null) {
|
|
|
|
MainUtil.sendMessage(null, "&7 - Skipped plot &c" + plot.getId());
|
|
|
|
} else {
|
2018-12-21 01:49:15 +01:00
|
|
|
TaskManager.runTaskAsync(() -> {
|
|
|
|
MainUtil.sendMessage(null, "&6ID: " + plot.getId());
|
|
|
|
boolean result = SchematicHandler.manager
|
2019-04-01 12:39:01 +02:00
|
|
|
.save(value, directory + File.separator + name + ".schem");
|
2018-12-21 01:49:15 +01:00
|
|
|
if (!result) {
|
|
|
|
MainUtil
|
|
|
|
.sendMessage(null, "&7 - Failed to save &c" + plot.getId());
|
|
|
|
} else {
|
|
|
|
MainUtil.sendMessage(null, "&7 - &a success: " + plot.getId());
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2019-02-15 18:50:43 +01:00
|
|
|
TaskManager.runTask(THIS);
|
2016-02-23 05:11:28 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
2016-03-02 07:42:04 +01:00
|
|
|
|
2016-02-23 05:11:28 +01:00
|
|
|
/**
|
2016-03-29 01:30:55 +02:00
|
|
|
* Paste a schematic.
|
2016-02-23 05:11:28 +01:00
|
|
|
*
|
|
|
|
* @param schematic the schematic object to paste
|
|
|
|
* @param plot plot to paste in
|
2018-08-10 17:01:10 +02:00
|
|
|
* @param xOffset offset x to paste it from plot origin
|
|
|
|
* @param zOffset offset z to paste it from plot origin
|
2016-02-23 05:11:28 +01:00
|
|
|
*/
|
2018-08-10 17:01:10 +02:00
|
|
|
public void paste(final Schematic schematic, final Plot plot, final int xOffset,
|
2018-12-21 00:33:24 +01:00
|
|
|
final int yOffset, final int zOffset, final boolean autoHeight,
|
|
|
|
final RunnableVal<Boolean> whenDone) {
|
2018-12-20 00:18:57 +01:00
|
|
|
|
2018-12-21 01:49:15 +01:00
|
|
|
TaskManager.runTask(() -> {
|
|
|
|
if (whenDone != null) {
|
|
|
|
whenDone.value = false;
|
|
|
|
}
|
|
|
|
if (schematic == null) {
|
|
|
|
PlotSquared.debug("Schematic == null :|");
|
|
|
|
TaskManager.runTask(whenDone);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
final LocalBlockQueue queue = plot.getArea().getQueue(false);
|
|
|
|
BlockVector3 dimension = schematic.getClipboard().getDimensions();
|
|
|
|
final int WIDTH = dimension.getX();
|
|
|
|
final int LENGTH = dimension.getZ();
|
|
|
|
final int HEIGHT = dimension.getY();
|
|
|
|
// Validate dimensions
|
2019-11-04 22:08:33 +01:00
|
|
|
CuboidRegion region = plot.getLargestRegion();
|
2020-02-24 18:42:02 +01:00
|
|
|
if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset
|
|
|
|
+ 1) < WIDTH) || (
|
|
|
|
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset
|
|
|
|
+ 1) < LENGTH) || (HEIGHT > 256)) {
|
2018-12-21 01:49:15 +01:00
|
|
|
PlotSquared.debug("Schematic is too large");
|
|
|
|
PlotSquared.debug(
|
|
|
|
"(" + WIDTH + ',' + LENGTH + ',' + HEIGHT + ") is bigger than (" + (
|
2020-02-24 18:42:02 +01:00
|
|
|
region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) + ','
|
|
|
|
+ (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ())
|
2018-12-21 01:49:15 +01:00
|
|
|
+ ",256)");
|
2016-02-23 05:11:28 +01:00
|
|
|
TaskManager.runTask(whenDone);
|
|
|
|
return;
|
|
|
|
}
|
2018-12-21 01:49:15 +01:00
|
|
|
// block type and data arrays
|
2019-11-04 20:55:55 +01:00
|
|
|
final Clipboard blockArrayClipboard = schematic.getClipboard();
|
2018-12-21 01:49:15 +01:00
|
|
|
// Calculate the optimal height to paste the schematic at
|
|
|
|
final int y_offset_actual;
|
|
|
|
if (autoHeight) {
|
|
|
|
if (HEIGHT >= 256) {
|
|
|
|
y_offset_actual = yOffset;
|
|
|
|
} else {
|
|
|
|
PlotArea pw = plot.getArea();
|
|
|
|
if (pw instanceof ClassicPlotWorld) {
|
|
|
|
y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT;
|
2016-02-23 05:11:28 +01:00
|
|
|
} else {
|
2020-04-07 20:19:39 +02:00
|
|
|
y_offset_actual = yOffset + 1 + WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(),
|
2020-02-24 18:42:02 +01:00
|
|
|
region.getMinimumPoint().getX() + 1,
|
2019-11-04 22:08:33 +01:00
|
|
|
region.getMinimumPoint().getZ() + 1);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2016-03-02 07:42:04 +01:00
|
|
|
}
|
2018-12-21 01:49:15 +01:00
|
|
|
} else {
|
|
|
|
y_offset_actual = yOffset;
|
|
|
|
}
|
|
|
|
Location pos1 =
|
2020-02-24 18:42:02 +01:00
|
|
|
new Location(plot.getWorldName(), region.getMinimumPoint().getX() + xOffset,
|
|
|
|
y_offset_actual, region.getMinimumPoint().getZ() + zOffset);
|
2018-12-21 01:49:15 +01:00
|
|
|
Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1);
|
|
|
|
final int p1x = pos1.getX();
|
|
|
|
final int p1z = pos1.getZ();
|
|
|
|
final int p2x = pos2.getX();
|
|
|
|
final int p2z = pos2.getZ();
|
|
|
|
final int bcx = p1x >> 4;
|
|
|
|
final int bcz = p1z >> 4;
|
|
|
|
final int tcx = p2x >> 4;
|
|
|
|
final int tcz = p2z >> 4;
|
2018-12-24 18:56:13 +01:00
|
|
|
|
2018-12-21 01:49:15 +01:00
|
|
|
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
|
|
|
@Override public void run(int[] value) {
|
2019-11-04 18:44:23 +01:00
|
|
|
BlockVector2 chunk = BlockVector2.at(value[0], value[1]);
|
|
|
|
int x = chunk.getX();
|
|
|
|
int z = chunk.getZ();
|
2018-12-21 01:49:15 +01:00
|
|
|
int xxb = x << 4;
|
|
|
|
int zzb = z << 4;
|
|
|
|
int xxt = xxb + 15;
|
|
|
|
int zzt = zzb + 15;
|
|
|
|
if (x == bcx) {
|
|
|
|
xxb = p1x;
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2018-12-21 01:49:15 +01:00
|
|
|
if (x == tcx) {
|
|
|
|
xxt = p2x;
|
|
|
|
}
|
|
|
|
if (z == bcz) {
|
|
|
|
zzb = p1z;
|
|
|
|
}
|
|
|
|
if (z == tcz) {
|
|
|
|
zzt = p2z;
|
|
|
|
}
|
|
|
|
// Paste schematic here
|
2016-02-23 05:11:28 +01:00
|
|
|
|
2018-12-21 01:49:15 +01:00
|
|
|
for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) {
|
|
|
|
int yy = y_offset_actual + ry;
|
|
|
|
if (yy > 255) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) {
|
|
|
|
for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) {
|
2018-12-24 18:56:13 +01:00
|
|
|
int xx = p1x + xOffset + rx;
|
|
|
|
int zz = p1z + zOffset + rz;
|
2018-12-21 01:49:15 +01:00
|
|
|
BaseBlock id = blockArrayClipboard
|
|
|
|
.getFullBlock(BlockVector3.at(rx, ry, rz));
|
|
|
|
queue.setBlock(xx, yy, zz, id);
|
2020-03-24 09:08:56 +01:00
|
|
|
if (ry == 0) {
|
|
|
|
BiomeType biome =
|
|
|
|
blockArrayClipboard.getBiome(BlockVector2.at(rx, rz));
|
|
|
|
queue.setBiome(xx, zz, biome);
|
|
|
|
}
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
}
|
2018-12-21 01:49:15 +01:00
|
|
|
}
|
2018-12-24 08:13:15 +01:00
|
|
|
queue.enqueue();
|
2018-12-21 00:33:24 +01:00
|
|
|
}
|
2018-12-24 18:56:13 +01:00
|
|
|
}, () -> {
|
|
|
|
if (whenDone != null) {
|
|
|
|
whenDone.value = true;
|
|
|
|
whenDone.run();
|
|
|
|
}
|
|
|
|
}, 10);
|
2018-12-21 01:49:15 +01:00
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
TaskManager.runTask(whenDone);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
|
2018-08-10 17:01:10 +02:00
|
|
|
public abstract boolean restoreTile(LocalBlockQueue queue, CompoundTag tag, int x, int y,
|
|
|
|
int z);
|
2016-02-23 05:11:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a schematic
|
|
|
|
*
|
|
|
|
* @param name to check
|
|
|
|
* @return schematic if found, else null
|
|
|
|
*/
|
2018-12-20 00:18:57 +01:00
|
|
|
public Schematic getSchematic(String name) throws UnsupportedFormatException {
|
2018-11-14 15:44:07 +01:00
|
|
|
File parent =
|
|
|
|
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS);
|
2016-02-23 05:11:28 +01:00
|
|
|
if (!parent.exists()) {
|
|
|
|
if (!parent.mkdir()) {
|
|
|
|
throw new RuntimeException("Could not create schematic parent directory");
|
|
|
|
}
|
|
|
|
}
|
2019-04-01 12:39:01 +02:00
|
|
|
if (!name.endsWith(".schem") && !name.endsWith(".schematic")) {
|
|
|
|
name = name + ".schem";
|
|
|
|
}
|
2019-04-24 00:48:22 +02:00
|
|
|
File file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
|
|
|
|
Settings.Paths.SCHEMATICS + File.separator + name);
|
2019-04-01 12:39:01 +02:00
|
|
|
if (!file.exists()) {
|
2019-04-24 00:48:22 +02:00
|
|
|
file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
|
2020-03-26 21:55:27 +01:00
|
|
|
Settings.Paths.SCHEMATICS + File.separator + name);
|
2019-04-01 12:39:01 +02:00
|
|
|
}
|
2016-02-23 05:11:28 +01:00
|
|
|
return getSchematic(file);
|
|
|
|
}
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2018-12-06 18:01:33 +01:00
|
|
|
/**
|
|
|
|
* Get an immutable collection containing all schematic names
|
|
|
|
*
|
|
|
|
* @return Immutable collection with schematic names
|
|
|
|
*/
|
2019-05-14 03:57:41 +02:00
|
|
|
public Collection<String> getSchematicNames() {
|
2018-12-20 00:18:57 +01:00
|
|
|
final File parent =
|
|
|
|
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS);
|
2018-12-06 18:01:33 +01:00
|
|
|
final List<String> names = new ArrayList<>();
|
|
|
|
if (parent.exists()) {
|
2019-04-24 00:48:22 +02:00
|
|
|
final String[] rawNames =
|
|
|
|
parent.list((dir, name) -> name.endsWith(".schematic") || name.endsWith(".schem"));
|
2018-12-06 18:01:33 +01:00
|
|
|
if (rawNames != null) {
|
2018-12-20 00:18:57 +01:00
|
|
|
final List<String> transformed = Arrays.stream(rawNames)
|
2019-09-12 03:44:31 +02:00
|
|
|
//.map(rawName -> rawName.substring(0, rawName.length() - 10))
|
2018-12-06 18:01:33 +01:00
|
|
|
.collect(Collectors.toList());
|
|
|
|
names.addAll(transformed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Collections.unmodifiableList(names);
|
|
|
|
}
|
|
|
|
|
2016-02-23 05:11:28 +01:00
|
|
|
/**
|
|
|
|
* Get a schematic
|
|
|
|
*
|
|
|
|
* @param file to check
|
|
|
|
* @return schematic if found, else null
|
|
|
|
*/
|
2018-12-20 00:18:57 +01:00
|
|
|
public Schematic getSchematic(File file) throws UnsupportedFormatException {
|
2016-02-23 05:11:28 +01:00
|
|
|
if (!file.exists()) {
|
|
|
|
return null;
|
|
|
|
}
|
2020-03-26 21:55:27 +01:00
|
|
|
ClipboardFormat format = ClipboardFormats.findByFile(file);
|
|
|
|
if (format != null) {
|
|
|
|
try (ClipboardReader reader = format.getReader(new FileInputStream(file))) {
|
2019-11-04 20:55:55 +01:00
|
|
|
Clipboard clip = reader.read();
|
2018-12-20 00:18:57 +01:00
|
|
|
return new Schematic(clip);
|
2020-03-26 21:55:27 +01:00
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
2018-12-20 00:18:57 +01:00
|
|
|
}
|
2020-03-26 21:55:27 +01:00
|
|
|
} else {
|
|
|
|
throw new UnsupportedFormatException(
|
|
|
|
"This schematic format is not recognised or supported.");
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
|
2019-05-22 00:32:26 +02:00
|
|
|
public Schematic getSchematic(@NotNull URL url) {
|
2016-02-23 05:11:28 +01:00
|
|
|
try {
|
2019-09-08 20:02:45 +02:00
|
|
|
ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
|
|
|
|
InputStream inputStream = Channels.newInputStream(readableByteChannel);
|
|
|
|
return getSchematic(inputStream);
|
2016-02-23 05:11:28 +01:00
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
|
2019-05-22 00:32:26 +02:00
|
|
|
public Schematic getSchematic(@NotNull InputStream is) {
|
2016-02-23 05:11:28 +01:00
|
|
|
try {
|
2019-09-08 20:02:45 +02:00
|
|
|
SpongeSchematicReader schematicReader =
|
2018-12-20 00:18:57 +01:00
|
|
|
new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
2019-11-04 20:55:55 +01:00
|
|
|
Clipboard clip = schematicReader.read();
|
2018-12-20 00:18:57 +01:00
|
|
|
return new Schematic(clip);
|
|
|
|
} catch (IOException ignored) {
|
|
|
|
try {
|
2019-09-08 20:02:45 +02:00
|
|
|
MCEditSchematicReader schematicReader =
|
2018-12-20 00:18:57 +01:00
|
|
|
new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
2019-11-04 20:55:55 +01:00
|
|
|
Clipboard clip = schematicReader.read();
|
2018-12-20 00:18:57 +01:00
|
|
|
return new Schematic(clip);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
PlotSquared.debug(is.toString() + " | " + is.getClass().getCanonicalName()
|
|
|
|
+ " is not in GZIP format : " + e.getMessage());
|
|
|
|
}
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2016-03-29 01:30:55 +02:00
|
|
|
|
|
|
|
public List<String> getSaves(UUID uuid) {
|
2019-02-15 18:50:43 +01:00
|
|
|
String rawJSON = "";
|
2016-02-23 05:11:28 +01:00
|
|
|
try {
|
2016-06-10 19:00:34 +02:00
|
|
|
String website = Settings.Web.URL + "list.php?" + uuid.toString();
|
2016-03-29 01:30:55 +02:00
|
|
|
URL url = new URL(website);
|
|
|
|
URLConnection connection = new URL(url.toString()).openConnection();
|
2016-02-23 05:11:28 +01:00
|
|
|
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
|
2019-02-15 18:50:43 +01:00
|
|
|
try (BufferedReader reader = new BufferedReader(
|
|
|
|
new InputStreamReader(connection.getInputStream()))) {
|
|
|
|
rawJSON = reader.lines().collect(Collectors.joining());
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2019-02-15 18:50:43 +01:00
|
|
|
JSONArray array = new JSONArray(rawJSON);
|
2016-03-29 01:30:55 +02:00
|
|
|
List<String> schematics = new ArrayList<>();
|
2016-02-23 05:11:28 +01:00
|
|
|
for (int i = 0; i < array.length(); i++) {
|
2016-03-29 01:30:55 +02:00
|
|
|
String schematic = array.getString(i);
|
2016-02-23 05:11:28 +01:00
|
|
|
schematics.add(schematic);
|
|
|
|
}
|
2016-06-16 09:31:02 +02:00
|
|
|
return schematics;
|
2016-02-23 05:11:28 +01:00
|
|
|
} catch (JSONException | IOException e) {
|
|
|
|
e.printStackTrace();
|
2018-11-14 14:19:56 +01:00
|
|
|
PlotSquared.debug("ERROR PARSING: " + rawJSON);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2016-03-17 10:11:07 +01:00
|
|
|
public void upload(final CompoundTag tag, UUID uuid, String file, RunnableVal<URL> whenDone) {
|
2016-02-23 05:11:28 +01:00
|
|
|
if (tag == null) {
|
2018-11-14 14:19:56 +01:00
|
|
|
PlotSquared.debug("&cCannot save empty tag");
|
2016-03-17 10:11:07 +01:00
|
|
|
TaskManager.runTask(whenDone);
|
|
|
|
return;
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2020-03-24 09:08:56 +01:00
|
|
|
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void run(OutputStream output) {
|
2018-12-23 23:49:43 +01:00
|
|
|
try (NBTOutputStream nos = new NBTOutputStream(
|
|
|
|
new GZIPOutputStream(output, true))) {
|
|
|
|
nos.writeNamedTag("Schematic", tag);
|
|
|
|
} catch (IOException e1) {
|
|
|
|
e1.printStackTrace();
|
2016-03-17 10:11:07 +01:00
|
|
|
}
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2016-03-17 10:11:07 +01:00
|
|
|
}, whenDone);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2016-02-23 05:11:28 +01:00
|
|
|
/**
|
2016-03-29 01:30:55 +02:00
|
|
|
* Saves a schematic to a file path.
|
2016-02-23 05:11:28 +01:00
|
|
|
*
|
|
|
|
* @param tag to save
|
|
|
|
* @param path to save in
|
|
|
|
* @return true if succeeded
|
|
|
|
*/
|
2016-03-29 01:30:55 +02:00
|
|
|
public boolean save(CompoundTag tag, String path) {
|
2016-02-23 05:11:28 +01:00
|
|
|
if (tag == null) {
|
2018-11-14 14:19:56 +01:00
|
|
|
PlotSquared.debug("&cCannot save empty tag");
|
2016-02-23 05:11:28 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
try {
|
2018-11-14 14:19:56 +01:00
|
|
|
File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path);
|
2016-02-23 05:11:28 +01:00
|
|
|
tmp.getParentFile().mkdirs();
|
2018-12-21 00:33:24 +01:00
|
|
|
try (NBTOutputStream nbtStream = new NBTOutputStream(
|
|
|
|
new GZIPOutputStream(new FileOutputStream(tmp)))) {
|
|
|
|
nbtStream.writeNamedTag("Schematic", tag);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2016-04-28 22:38:51 +02:00
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
e.printStackTrace();
|
2016-03-29 01:30:55 +02:00
|
|
|
} catch (IOException e) {
|
2016-02-23 05:11:28 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2019-11-04 22:08:33 +01:00
|
|
|
public abstract void getCompoundTag(String world, Set<CuboidRegion> regions,
|
2018-08-10 17:01:10 +02:00
|
|
|
RunnableVal<CompoundTag> whenDone);
|
|
|
|
|
2016-02-29 16:01:52 +01:00
|
|
|
public void getCompoundTag(final Plot plot, final RunnableVal<CompoundTag> whenDone) {
|
2017-03-23 01:10:29 +01:00
|
|
|
getCompoundTag(plot.getWorldName(), plot.getRegions(), new RunnableVal<CompoundTag>() {
|
2018-08-10 17:01:10 +02:00
|
|
|
@Override public void run(CompoundTag value) {
|
2016-03-07 07:34:57 +01:00
|
|
|
whenDone.run(value);
|
2016-02-29 16:01:52 +01:00
|
|
|
}
|
|
|
|
});
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
2018-08-10 17:01:10 +02:00
|
|
|
|
2018-12-23 23:49:43 +01:00
|
|
|
|
2020-03-24 09:08:56 +01:00
|
|
|
public static class UnsupportedFormatException extends Exception {
|
2016-02-23 05:11:28 +01:00
|
|
|
/**
|
2018-12-20 00:18:57 +01:00
|
|
|
* Throw with a message.
|
2018-08-10 17:01:10 +02:00
|
|
|
*
|
2018-12-20 00:18:57 +01:00
|
|
|
* @param message the message
|
2016-02-23 05:11:28 +01:00
|
|
|
*/
|
2018-12-20 00:18:57 +01:00
|
|
|
public UnsupportedFormatException(String message) {
|
|
|
|
super(message);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-12-20 00:18:57 +01:00
|
|
|
* Throw with a message and a cause.
|
2018-08-10 17:01:10 +02:00
|
|
|
*
|
2018-12-20 00:18:57 +01:00
|
|
|
* @param message the message
|
|
|
|
* @param cause the cause
|
2016-02-23 05:11:28 +01:00
|
|
|
*/
|
2018-12-20 00:18:57 +01:00
|
|
|
public UnsupportedFormatException(String message, Throwable cause) {
|
|
|
|
super(message, cause);
|
2016-02-23 05:11:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|