PlotSquared/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java

476 lines
19 KiB
Java
Raw Normal View History

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;
import com.plotsquared.core.config.Settings;
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;
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;
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;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.jetbrains.annotations.NotNull;
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();
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) {
name =
plot.getId().x + ";" + plot.getId().y + ',' + plot.getArea() + ',' + owner;
2016-02-23 05:11:28 +01:00
} else {
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) {
directory = Settings.Paths.SCHEMATICS;
2016-02-23 05:11:28 +01:00
} else {
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 {
TaskManager.runTaskAsync(() -> {
MainUtil.sendMessage(null, "&6ID: " + plot.getId());
boolean result = SchematicHandler.manager
.save(value, directory + File.separator + name + ".schem");
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
}
TaskManager.runTask(THIS);
2016-02-23 05:11:28 +01:00
});
}
}
});
}
});
return true;
}
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,
final int yOffset, final int zOffset, final boolean autoHeight,
final RunnableVal<Boolean> whenDone) {
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
CuboidRegion region = plot.getLargestRegion();
Pull/2693 (#2694) * Commit WIP flag work. * More ported flag types, and additions to the flag API. * Make PlotFlag more generic to allow generic flag creation * Pull Captions methods into a Caption interface. * Port MusicFlag * Port flight flag * Port UntrustedVisitFlag * Port DenyExitFlag * Remove paper suggestion * Make ListFlag lists immutable * Update Flag containers. Add javadocs. Add missing methods. * Port description flag * Port greeting and farewell flags * Port weather flag * Move getExample implementation to BooleanFlag * Port reserved flags * Port all boolean flags. * Remove unused flag types * Invert liquid-flow flag * Find the real (legacy) flag name * Change NOITFY -> NOTIFY in Captions * Make IntegerFlag extendable * Port integer flags * Update Flag command to current API state * Begin remaking flag command * Create DoubleFlag + extract common parsing stuff * Supply arguments in flag parse exceptions * Implement missing flag subcommands * Update Flag command to current API state * Implement PriceFlag * Port deny-teleport * Port gamemode flags * Port BreakFlag * Port PlaceFlag * Port UseFlag * Remove old unused flag constants * Port blocked-cmds flag * Fix entity util * Port TimeFlag * Use CaptionUtility for formatting * Port keep flag * Fix imports * Reformat code * Remove unused classes * Fix MainUtil.java * Remove FlagCmd * Add flag info header and footer * Comment out flag related stuff in SchematicHandler * Remove FlagManager * Finalize Plot.java * Finalize PlotArea.java * Finalize PlotListener * Fix API issues * Fix a bunch of compile errors * Fix `/plot flag remove` * Fix initialization of GlobalFlagContainer * Apply API changes to events * Update SQLManager to new API * Invert default value for DenyExitFlag * Replace flag.getValue().toString() with flag.toString() * Make FlagContainer instance in Plot final * Fix various command issues * Clean up PlotSettings * Don't show internal flags in flag list * Fix `/plot flag add` * Remove the info inventory as it's 100% broken * Add plot info entries and fix up the default format * Fix default flag state in Captions * 781c200 part 2 * Fix odd grammar in captions * Fix odd grammar in captions v2 * Add create table statements for plot_flags * Remove old flag references in SQLManager * Use the new plot_flags table * Add tab completion to `/plot flag` * Improve parse error handling * Make flag permission check recognize parse exceptions * Initial progress towards flag conversion * Fix minor issues * Don't validate flags during flag conversion * Allow unrecognized flags to be parsed * Filter out internal flags from command sugguestions * Use the wrong caption when there's no plot description set * Limit command suggestions for boolean flags * Make blocktypelistflags accept blockcategories * Require categories to be prefixed with '#' and fix some minor display issues * Fix plot database conversion * Update PlotFlagEvent.java Updated return description * Fix command annotation wrapping * Add FLAG_UPDATE event for FlagContainer listeners * Make getParentContainer nullable * Document castUnsafe in FlagContainer * Document FlagContainer constructors * Add missing documentation to FlagContainer * Document FlagParseException * Fix wording in FlagContainer javadoc * Document InternalFlag * Document PlotFlag * Minor changes * Remove revisit comments Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com> Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
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)) {
PlotSquared.debug("Schematic is too large");
PlotSquared.debug(
"(" + WIDTH + ',' + LENGTH + ',' + HEIGHT + ") is bigger than (" + (
Pull/2693 (#2694) * Commit WIP flag work. * More ported flag types, and additions to the flag API. * Make PlotFlag more generic to allow generic flag creation * Pull Captions methods into a Caption interface. * Port MusicFlag * Port flight flag * Port UntrustedVisitFlag * Port DenyExitFlag * Remove paper suggestion * Make ListFlag lists immutable * Update Flag containers. Add javadocs. Add missing methods. * Port description flag * Port greeting and farewell flags * Port weather flag * Move getExample implementation to BooleanFlag * Port reserved flags * Port all boolean flags. * Remove unused flag types * Invert liquid-flow flag * Find the real (legacy) flag name * Change NOITFY -> NOTIFY in Captions * Make IntegerFlag extendable * Port integer flags * Update Flag command to current API state * Begin remaking flag command * Create DoubleFlag + extract common parsing stuff * Supply arguments in flag parse exceptions * Implement missing flag subcommands * Update Flag command to current API state * Implement PriceFlag * Port deny-teleport * Port gamemode flags * Port BreakFlag * Port PlaceFlag * Port UseFlag * Remove old unused flag constants * Port blocked-cmds flag * Fix entity util * Port TimeFlag * Use CaptionUtility for formatting * Port keep flag * Fix imports * Reformat code * Remove unused classes * Fix MainUtil.java * Remove FlagCmd * Add flag info header and footer * Comment out flag related stuff in SchematicHandler * Remove FlagManager * Finalize Plot.java * Finalize PlotArea.java * Finalize PlotListener * Fix API issues * Fix a bunch of compile errors * Fix `/plot flag remove` * Fix initialization of GlobalFlagContainer * Apply API changes to events * Update SQLManager to new API * Invert default value for DenyExitFlag * Replace flag.getValue().toString() with flag.toString() * Make FlagContainer instance in Plot final * Fix various command issues * Clean up PlotSettings * Don't show internal flags in flag list * Fix `/plot flag add` * Remove the info inventory as it's 100% broken * Add plot info entries and fix up the default format * Fix default flag state in Captions * 781c200 part 2 * Fix odd grammar in captions * Fix odd grammar in captions v2 * Add create table statements for plot_flags * Remove old flag references in SQLManager * Use the new plot_flags table * Add tab completion to `/plot flag` * Improve parse error handling * Make flag permission check recognize parse exceptions * Initial progress towards flag conversion * Fix minor issues * Don't validate flags during flag conversion * Allow unrecognized flags to be parsed * Filter out internal flags from command sugguestions * Use the wrong caption when there's no plot description set * Limit command suggestions for boolean flags * Make blocktypelistflags accept blockcategories * Require categories to be prefixed with '#' and fix some minor display issues * Fix plot database conversion * Update PlotFlagEvent.java Updated return description * Fix command annotation wrapping * Add FLAG_UPDATE event for FlagContainer listeners * Make getParentContainer nullable * Document castUnsafe in FlagContainer * Document FlagContainer constructors * Add missing documentation to FlagContainer * Document FlagParseException * Fix wording in FlagContainer javadoc * Document InternalFlag * Document PlotFlag * Minor changes * Remove revisit comments Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com> Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
2020-02-24 18:42:02 +01:00
region.getMaximumPoint().getX() - region.getMinimumPoint().getX()) + ','
+ (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ())
+ ",256)");
2016-02-23 05:11:28 +01:00
TaskManager.runTask(whenDone);
return;
}
// block type and data arrays
2019-11-04 20:55:55 +01:00
final Clipboard blockArrayClipboard = schematic.getClipboard();
// 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 {
y_offset_actual = yOffset + 1 + WorldUtil.IMP.getHighestBlockSynchronous(plot.getWorldName(),
Pull/2693 (#2694) * Commit WIP flag work. * More ported flag types, and additions to the flag API. * Make PlotFlag more generic to allow generic flag creation * Pull Captions methods into a Caption interface. * Port MusicFlag * Port flight flag * Port UntrustedVisitFlag * Port DenyExitFlag * Remove paper suggestion * Make ListFlag lists immutable * Update Flag containers. Add javadocs. Add missing methods. * Port description flag * Port greeting and farewell flags * Port weather flag * Move getExample implementation to BooleanFlag * Port reserved flags * Port all boolean flags. * Remove unused flag types * Invert liquid-flow flag * Find the real (legacy) flag name * Change NOITFY -> NOTIFY in Captions * Make IntegerFlag extendable * Port integer flags * Update Flag command to current API state * Begin remaking flag command * Create DoubleFlag + extract common parsing stuff * Supply arguments in flag parse exceptions * Implement missing flag subcommands * Update Flag command to current API state * Implement PriceFlag * Port deny-teleport * Port gamemode flags * Port BreakFlag * Port PlaceFlag * Port UseFlag * Remove old unused flag constants * Port blocked-cmds flag * Fix entity util * Port TimeFlag * Use CaptionUtility for formatting * Port keep flag * Fix imports * Reformat code * Remove unused classes * Fix MainUtil.java * Remove FlagCmd * Add flag info header and footer * Comment out flag related stuff in SchematicHandler * Remove FlagManager * Finalize Plot.java * Finalize PlotArea.java * Finalize PlotListener * Fix API issues * Fix a bunch of compile errors * Fix `/plot flag remove` * Fix initialization of GlobalFlagContainer * Apply API changes to events * Update SQLManager to new API * Invert default value for DenyExitFlag * Replace flag.getValue().toString() with flag.toString() * Make FlagContainer instance in Plot final * Fix various command issues * Clean up PlotSettings * Don't show internal flags in flag list * Fix `/plot flag add` * Remove the info inventory as it's 100% broken * Add plot info entries and fix up the default format * Fix default flag state in Captions * 781c200 part 2 * Fix odd grammar in captions * Fix odd grammar in captions v2 * Add create table statements for plot_flags * Remove old flag references in SQLManager * Use the new plot_flags table * Add tab completion to `/plot flag` * Improve parse error handling * Make flag permission check recognize parse exceptions * Initial progress towards flag conversion * Fix minor issues * Don't validate flags during flag conversion * Allow unrecognized flags to be parsed * Filter out internal flags from command sugguestions * Use the wrong caption when there's no plot description set * Limit command suggestions for boolean flags * Make blocktypelistflags accept blockcategories * Require categories to be prefixed with '#' and fix some minor display issues * Fix plot database conversion * Update PlotFlagEvent.java Updated return description * Fix command annotation wrapping * Add FLAG_UPDATE event for FlagContainer listeners * Make getParentContainer nullable * Document castUnsafe in FlagContainer * Document FlagContainer constructors * Add missing documentation to FlagContainer * Document FlagParseException * Fix wording in FlagContainer javadoc * Document InternalFlag * Document PlotFlag * Minor changes * Remove revisit comments Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com> Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
2020-02-24 18:42:02 +01:00
region.getMinimumPoint().getX() + 1,
region.getMinimumPoint().getZ() + 1);
2016-02-23 05:11:28 +01:00
}
}
} else {
y_offset_actual = yOffset;
}
Location pos1 =
Pull/2693 (#2694) * Commit WIP flag work. * More ported flag types, and additions to the flag API. * Make PlotFlag more generic to allow generic flag creation * Pull Captions methods into a Caption interface. * Port MusicFlag * Port flight flag * Port UntrustedVisitFlag * Port DenyExitFlag * Remove paper suggestion * Make ListFlag lists immutable * Update Flag containers. Add javadocs. Add missing methods. * Port description flag * Port greeting and farewell flags * Port weather flag * Move getExample implementation to BooleanFlag * Port reserved flags * Port all boolean flags. * Remove unused flag types * Invert liquid-flow flag * Find the real (legacy) flag name * Change NOITFY -> NOTIFY in Captions * Make IntegerFlag extendable * Port integer flags * Update Flag command to current API state * Begin remaking flag command * Create DoubleFlag + extract common parsing stuff * Supply arguments in flag parse exceptions * Implement missing flag subcommands * Update Flag command to current API state * Implement PriceFlag * Port deny-teleport * Port gamemode flags * Port BreakFlag * Port PlaceFlag * Port UseFlag * Remove old unused flag constants * Port blocked-cmds flag * Fix entity util * Port TimeFlag * Use CaptionUtility for formatting * Port keep flag * Fix imports * Reformat code * Remove unused classes * Fix MainUtil.java * Remove FlagCmd * Add flag info header and footer * Comment out flag related stuff in SchematicHandler * Remove FlagManager * Finalize Plot.java * Finalize PlotArea.java * Finalize PlotListener * Fix API issues * Fix a bunch of compile errors * Fix `/plot flag remove` * Fix initialization of GlobalFlagContainer * Apply API changes to events * Update SQLManager to new API * Invert default value for DenyExitFlag * Replace flag.getValue().toString() with flag.toString() * Make FlagContainer instance in Plot final * Fix various command issues * Clean up PlotSettings * Don't show internal flags in flag list * Fix `/plot flag add` * Remove the info inventory as it's 100% broken * Add plot info entries and fix up the default format * Fix default flag state in Captions * 781c200 part 2 * Fix odd grammar in captions * Fix odd grammar in captions v2 * Add create table statements for plot_flags * Remove old flag references in SQLManager * Use the new plot_flags table * Add tab completion to `/plot flag` * Improve parse error handling * Make flag permission check recognize parse exceptions * Initial progress towards flag conversion * Fix minor issues * Don't validate flags during flag conversion * Allow unrecognized flags to be parsed * Filter out internal flags from command sugguestions * Use the wrong caption when there's no plot description set * Limit command suggestions for boolean flags * Make blocktypelistflags accept blockcategories * Require categories to be prefixed with '#' and fix some minor display issues * Fix plot database conversion * Update PlotFlagEvent.java Updated return description * Fix command annotation wrapping * Add FLAG_UPDATE event for FlagContainer listeners * Make getParentContainer nullable * Document castUnsafe in FlagContainer * Document FlagContainer constructors * Add missing documentation to FlagContainer * Document FlagParseException * Fix wording in FlagContainer javadoc * Document InternalFlag * Document PlotFlag * Minor changes * Remove revisit comments Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com> Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
2020-02-24 18:42:02 +01:00
new Location(plot.getWorldName(), region.getMinimumPoint().getX() + xOffset,
y_offset_actual, region.getMinimumPoint().getZ() + zOffset);
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;
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();
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
}
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
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++) {
int xx = p1x + xOffset + rx;
int zz = p1z + zOffset + rz;
BaseBlock id = blockArrayClipboard
.getFullBlock(BlockVector3.at(rx, ry, rz));
queue.setBlock(xx, yy, zz, id);
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-24 08:13:15 +01:00
queue.enqueue();
}
}, () -> {
if (whenDone != null) {
whenDone.value = true;
whenDone.run();
}
}, 10);
} 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
*/
public Schematic getSchematic(String name) throws UnsupportedFormatException {
Merge branch 'master' into breaking # Conflicts: # Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/events/PlotRateEvent.java # Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitEventUtil.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/PlotSquared.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Add.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Auto.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Delete.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Kick.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Load.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Music.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Owner.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Rate.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Reload.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/SchematicCmd.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/commands/Trust.java # Core/src/main/java/com/github/intellectualsites/plotsquared/plot/flag/GameModeFlag.java # Core/src/main/java/com/intellectualcrafters/plot/commands/Clear.java # Core/src/main/java/com/intellectualcrafters/plot/commands/PluginCmd.java # Core/src/main/java/com/intellectualcrafters/plot/commands/Relight.java # Core/src/main/java/com/intellectualcrafters/plot/commands/SetHome.java # Core/src/main/java/com/intellectualcrafters/plot/config/C.java # Core/src/main/java/com/intellectualcrafters/plot/config/Configuration.java # Core/src/main/java/com/intellectualcrafters/plot/config/Settings.java # Core/src/test/java/com/github/intellectualsites/plotsquared/plot/util/EventUtilTest.java # Nukkit/src/main/java/com/plotsquared/nukkit/util/NukkitEventUtil.java # README.md # Sponge/src/main/java/com/github/intellectualsites/plotsquared/sponge/events/PlotRateEvent.java # Sponge/src/main/java/com/github/intellectualsites/plotsquared/sponge/util/SpongeSchematicHandler.java # Sponge/src/main/java/com/github/intellectualsites/plotsquared/sponge/util/block/SpongeLocalQueue.java # Sponge/src/main/java/com/plotsquared/sponge/util/SpongeEventUtil.java
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");
}
}
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);
if (!file.exists()) {
2019-04-24 00:48:22 +02:00
file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
Settings.Paths.SCHEMATICS + File.separator + name);
}
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
*/
public Collection<String> getSchematicNames() {
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) {
final List<String> transformed = Arrays.stream(rawNames)
//.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
*/
public Schematic getSchematic(File file) throws UnsupportedFormatException {
2016-02-23 05:11:28 +01:00
if (!file.exists()) {
return null;
}
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();
return new Schematic(clip);
} catch (IOException e) {
e.printStackTrace();
}
} 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
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
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 =
new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
2019-11-04 20:55:55 +01:00
Clipboard clip = schematicReader.read();
return new Schematic(clip);
} catch (IOException ignored) {
try {
2019-09-08 20:02:45 +02:00
MCEditSchematicReader schematicReader =
new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
2019-11-04 20:55:55 +01:00
Clipboard clip = schematicReader.read();
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) {
String rawJSON = "";
2016-02-23 05:11:28 +01:00
try {
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");
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()))) {
rawJSON = reader.lines().collect(Collectors.joining());
2016-02-23 05:11:28 +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);
}
return schematics;
2016-02-23 05:11:28 +01:00
} catch (JSONException | IOException e) {
e.printStackTrace();
PlotSquared.debug("ERROR PARSING: " + rawJSON);
2016-02-23 05:11:28 +01:00
}
return null;
}
2018-08-10 17:01:10 +02: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) {
PlotSquared.debug("&cCannot save empty tag");
TaskManager.runTask(whenDone);
return;
2016-02-23 05:11:28 +01:00
}
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
2018-08-10 17:01:10 +02:00
@Override public void run(OutputStream output) {
try (NBTOutputStream nos = new NBTOutputStream(
new GZIPOutputStream(output, true))) {
nos.writeNamedTag("Schematic", tag);
} catch (IOException e1) {
e1.printStackTrace();
}
2016-02-23 05:11:28 +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) {
PlotSquared.debug("&cCannot save empty tag");
2016-02-23 05:11:28 +01:00
return false;
}
try {
File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path);
2016-02-23 05:11:28 +01:00
tmp.getParentFile().mkdirs();
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
public abstract void getCompoundTag(String world, Set<CuboidRegion> regions,
2018-08-10 17:01:10 +02:00
RunnableVal<CompoundTag> whenDone);
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) {
whenDone.run(value);
}
});
2016-02-23 05:11:28 +01:00
}
2018-08-10 17:01:10 +02:00
public static class UnsupportedFormatException extends Exception {
2016-02-23 05:11:28 +01:00
/**
* Throw with a message.
2018-08-10 17:01:10 +02:00
*
* @param message the message
2016-02-23 05:11:28 +01:00
*/
public UnsupportedFormatException(String message) {
super(message);
2016-02-23 05:11:28 +01:00
}
/**
* Throw with a message and a cause.
2018-08-10 17:01:10 +02:00
*
* @param message the message
* @param cause the cause
2016-02-23 05:11:28 +01:00
*/
public UnsupportedFormatException(String message, Throwable cause) {
super(message, cause);
2016-02-23 05:11:28 +01:00
}
}
}