Improved schematic exporting

This commit is contained in:
boy0001 2015-02-25 23:25:28 +11:00
parent 99899e45ad
commit 577b19e2ae
8 changed files with 582 additions and 133 deletions

View File

@ -31,6 +31,7 @@ import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SchematicHandler.Schematic;
/**
* @author Citymonstret
@ -61,16 +62,16 @@ public class Claim extends SubCommand {
final PlotWorld plotworld = PlotSquared.getPlotWorld(world);
final Plot plot2 = PlotSquared.getPlots(world).get(plot.id);
if (plotworld.SCHEMATIC_ON_CLAIM) {
SchematicHandler.Schematic sch;
Schematic sch;
if (schematic.equals("")) {
sch = SchematicHandler.getSchematic(plotworld.SCHEMATIC_FILE);
sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
} else {
sch = SchematicHandler.getSchematic(schematic);
sch = SchematicHandler.manager.getSchematic(schematic);
if (sch == null) {
sch = SchematicHandler.getSchematic(plotworld.SCHEMATIC_FILE);
sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
}
}
SchematicHandler.paste(player.getLocation(), sch, plot2, 0, 0);
SchematicHandler.manager.paste(player.getLocation(), sch, plot2, 0, 0);
}
PlotSquared.getPlotManager(world).claimPlot(plotworld, plot);
MainUtil.update(loc);

View File

@ -40,7 +40,7 @@ public class MainCommand {
/**
* Main Permission Node
*/
private final static SubCommand[] _subCommands = new SubCommand[] { new Template(), new Setup(), new DebugSaveTest(), new DebugLoadTest(), new CreateRoadSchematic(), new RegenAllRoads(), new DebugClear(), new Claim(), new Auto(), new Home(), new Visit(), new TP(), new Set(), new Clear(), new Delete(), new SetOwner(), new Denied(), new Helpers(), new Trusted(), new Info(), new list(), new Help(), new Debug(), new Schematic(), new plugin(), new Inventory(), new Purge(), new Reload(), new Merge(), new Unlink(), new Kick(), new Rate(), new DebugClaimTest(), new Inbox(), new Comment(), new Database(), new Unclaim(), new Swap(), new MusicSubcommand(), new DebugRoadRegen(), new Trim(), new DebugExec(), new FlagCmd(), new Target(), new DebugFixFlags(), new Move(), new Condense() };
private final static SubCommand[] _subCommands = new SubCommand[] { new Template(), new Setup(), new DebugSaveTest(), new DebugLoadTest(), new CreateRoadSchematic(), new RegenAllRoads(), new DebugClear(), new Claim(), new Auto(), new Home(), new Visit(), new TP(), new Set(), new Clear(), new Delete(), new SetOwner(), new Denied(), new Helpers(), new Trusted(), new Info(), new list(), new Help(), new Debug(), new SchematicCmd(), new plugin(), new Inventory(), new Purge(), new Reload(), new Merge(), new Unlink(), new Kick(), new Rate(), new DebugClaimTest(), new Inbox(), new Comment(), new Database(), new Unclaim(), new Swap(), new MusicSubcommand(), new DebugRoadRegen(), new Trim(), new DebugExec(), new FlagCmd(), new Target(), new DebugFixFlags(), new Move(), new Condense() };
public final static ArrayList<SubCommand> subCommands = new ArrayList<SubCommand>() {
{
addAll(Arrays.asList(_subCommands));

View File

@ -0,0 +1,327 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// 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, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.intellectualcrafters.plot.commands;
import java.util.Collection;
import java.util.HashMap;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.BlockManager;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SchematicHandler.DataCollection;
import com.intellectualcrafters.plot.util.SchematicHandler.Dimension;
import com.intellectualcrafters.plot.util.SchematicHandler.Schematic;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.bukkit.UUIDHandler;
public class SchematicCmd extends SubCommand {
private int counter = 0;
private boolean running = false;
private Plot[] plots;
private int task;
public SchematicCmd() {
super("schematic", "plots.schematic", "Schematic Command", "schematic {arg}", "sch", CommandCategory.ACTIONS, false);
// TODO command to fetch schematic from worldedit directory
}
@Override
public boolean execute(final PlotPlayer plr, final String... args) {
if (args.length < 1) {
sendMessage(plr, C.SCHEMATIC_MISSING_ARG);
return true;
}
final String arg = args[0].toLowerCase();
final String file;
final Schematic schematic;
switch (arg) {
case "paste": {
if (plr == null) {
PlotSquared.log(C.IS_CONSOLE.s());
return false;
}
if (!Permissions.hasPermission(plr, "plots.schematic.paste")) {
MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.schematic.paste");
return false;
}
if (args.length < 2) {
sendMessage(plr, C.SCHEMATIC_MISSING_ARG);
break;
}
final Location loc = plr.getLocation();
final Plot plot = MainUtil.getPlot(loc);
if (plot == null) {
sendMessage(plr, C.NOT_IN_PLOT);
break;
}
if (this.running) {
MainUtil.sendMessage(plr, "&cTask is already running.");
return false;
}
final String file2 = args[1];
this.running = true;
this.counter = 0;
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final Schematic schematic = SchematicHandler.manager.getSchematic(file2);
if (schematic == null) {
sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent or not in gzip format");
SchematicCmd.this.running = false;
return;
}
final int x;
final int z;
final Plot plot2 = MainUtil.getPlot(loc);
final Dimension dem = schematic.getSchematicDimension();
final Location bot = MainUtil.getPlotBottomLoc(loc.getWorld(), plot2.id).add(1, 0, 1);
final int length2 = MainUtil.getPlotWidth(loc.getWorld(), plot2.id);
if ((dem.getX() > length2) || (dem.getZ() > length2)) {
sendMessage(plr, C.SCHEMATIC_INVALID, String.format("Wrong size (x: %s, z: %d) vs %d ", dem.getX(), dem.getZ(), length2));
SchematicCmd.this.running = false;
return;
}
if ((dem.getX() != length2) || (dem.getZ() != length2)) {
final Location loc = plr.getLocation();
x = Math.min(length2 - dem.getX(), loc.getX() - bot.getX());
z = Math.min(length2 - dem.getZ(), loc.getZ() - bot.getZ());
} else {
x = 0;
z = 0;
}
final DataCollection[] b = schematic.getBlockCollection();
final int sy = BlockManager.manager.getHeighestBlock(bot);
final Location l1 = bot.add(0, sy - 1, 0);
final int WIDTH = schematic.getSchematicDimension().getX();
final int LENGTH = schematic.getSchematicDimension().getZ();
final int blen = b.length - 1;
SchematicCmd.this.task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
boolean result = false;
while (!result) {
final int start = SchematicCmd.this.counter * 5000;
if (start > blen) {
sendMessage(plr, C.SCHEMATIC_PASTE_SUCCESS);
MainUtil.update(plr.getLocation());
SchematicCmd.this.running = false;
PlotSquared.TASK.cancelTask(SchematicCmd.this.task);
return;
}
final int end = Math.min(start + 5000, blen);
result = SchematicHandler.manager.pastePart(loc.getWorld(), b, l1, x, z, start, end, WIDTH, LENGTH);
SchematicCmd.this.counter++;
}
}
}, 1);
}
});
break;
}
case "test": {
if (plr == null) {
PlotSquared.log(C.IS_CONSOLE.s());
return false;
}
if (!Permissions.hasPermission(plr, "plots.schematic.test")) {
MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.schematic.test");
return false;
}
if (args.length < 2) {
sendMessage(plr, C.SCHEMATIC_MISSING_ARG);
break;
}
file = args[1];
schematic = SchematicHandler.manager.getSchematic(file);
if (schematic == null) {
sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent");
break;
}
final Location loc = plr.getLocation();
final int l1 = schematic.getSchematicDimension().getX();
final int l2 = schematic.getSchematicDimension().getZ();
final Plot plot = MainUtil.getPlot(loc);
final int length = MainUtil.getPlotWidth(loc.getWorld(), plot.id);
if ((l1 < length) || (l2 < length)) {
sendMessage(plr, C.SCHEMATIC_INVALID, String.format("Wrong size (x: %s, z: %d) vs %d ", l1, l2, length));
break;
}
sendMessage(plr, C.SCHEMATIC_VALID);
break;
}
case "saveall":
case "exportall": {
if (plr != null) {
MainUtil.sendMessage(plr, C.NOT_CONSOLE);
return false;
}
if (args.length != 2) {
MainUtil.sendMessage(null, "&cNeed world arg. Use &7/plots sch exportall <world>");
return false;
}
final HashMap<PlotId, Plot> plotmap = PlotSquared.getPlots(args[1]);
if ((plotmap == null) || (plotmap.size() == 0)) {
MainUtil.sendMessage(null, "&cInvalid world. Use &7/plots sch exportall <world>");
return false;
}
if (this.running) {
MainUtil.sendMessage(null, "&cTask is already running.");
return false;
}
PlotSquared.log("&3PlotSquared&8->&3Schemaitc&8: &7Mass export has started. This may take a while.");
PlotSquared.log("&3PlotSquared&8->&3Schemaitc&8: &7Found &c" + plotmap.size() + "&7 plots...");
final String worldname = args[1];
final Collection<Plot> values = plotmap.values();
this.plots = values.toArray(new Plot[values.size()]);
this.running = true;
this.counter = 0;
this.task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (SchematicCmd.this.counter >= SchematicCmd.this.plots.length) {
PlotSquared.log("&3PlotSquared&8->&3Schemaitc&8: &aFinished!");
SchematicCmd.this.running = false;
PlotSquared.TASK.cancelTask(SchematicCmd.this.task);
return;
}
final Plot plot = SchematicCmd.this.plots[SchematicCmd.this.counter];
final CompoundTag sch = SchematicHandler.manager.getCompoundTag(worldname, plot.id);
final String o = UUIDHandler.getName(plot.owner);
final String owner = o == null ? "unknown" : o;
if (sch == null) {
MainUtil.sendMessage(null, "&7 - Skipped plot &c" + plot.id);
} else {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(null, "&6ID: " + plot.id);
final boolean result = SchematicHandler.manager.save(sch, Settings.SCHEMATIC_SAVE_PATH + "/" + plot.id.x + ";" + plot.id.y + "," + worldname + "," + owner + ".schematic");
if (!result) {
MainUtil.sendMessage(null, "&7 - Failed to save &c" + plot.id);
} else {
MainUtil.sendMessage(null, "&7 - &a success: " + plot.id);
}
}
});
}
SchematicCmd.this.counter++;
}
}, 20);
break;
}
case "export":
case "save": {
if (!Permissions.hasPermission(plr, "plots.schematic.save")) {
MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.schematic.save");
return false;
}
if (this.running) {
MainUtil.sendMessage(plr, "&cTask is already running.");
return false;
}
final String world;
final Plot p2;
if (plr != null) {
final Location loc = plr.getLocation();
final Plot plot = MainUtil.getPlot(loc);
if (plot == null) {
return !sendMessage(plr, C.NOT_IN_PLOT);
}
if (!plot.isAdded(plr.getUUID())) {
sendMessage(plr, C.NO_PLOT_PERMS);
return false;
}
p2 = plot;
world = loc.getWorld();
} else {
if (args.length == 3) {
try {
world = args[0];
final String[] split = args[2].split(";");
final PlotId i = new PlotId(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
if ((PlotSquared.getPlots(world) == null) || (PlotSquared.getPlots(world).get(i) == null)) {
MainUtil.sendMessage(null, "&cInvalid world or id. Use &7/plots sch save <world> <id>");
return false;
}
p2 = PlotSquared.getPlots(world).get(i);
} catch (final Exception e) {
MainUtil.sendMessage(null, "&cInvalid world or id. Use &7/plots sch save <world> <id>");
return false;
}
} else {
MainUtil.sendMessage(null, "&cInvalid world or id. Use &7/plots sch save <world> <id>");
return false;
}
}
this.plots = new Plot[] { p2 };
this.running = true;
this.counter = 0;
this.task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (SchematicCmd.this.counter >= SchematicCmd.this.plots.length) {
PlotSquared.log("&3PlotSquared&8->&3Schemaitc&8: &aFinished!");
SchematicCmd.this.running = false;
PlotSquared.TASK.cancelTask(SchematicCmd.this.task);
return;
}
final Plot plot = SchematicCmd.this.plots[SchematicCmd.this.counter];
final CompoundTag sch = SchematicHandler.manager.getCompoundTag(world, plot.id);
final String o = UUIDHandler.getName(plot.owner);
final String owner = o == null ? "unknown" : o;
if (sch == null) {
MainUtil.sendMessage(plr, "&7 - Skipped plot &c" + plot.id);
} else {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(plr, "&6ID: " + plot.id);
final boolean result = SchematicHandler.manager.save(sch, Settings.SCHEMATIC_SAVE_PATH + "/" + plot.id.x + ";" + plot.id.y + "," + world + "," + owner.trim() + ".schematic");
if (!result) {
MainUtil.sendMessage(plr, "&7 - Failed to save &c" + plot.id);
} else {
MainUtil.sendMessage(plr, "&7 - &aExport success: " + plot.id);
}
}
});
}
SchematicCmd.this.counter++;
}
}, 60);
break;
}
default: {
sendMessage(plr, C.SCHEMATIC_MISSING_ARG);
break;
}
}
return true;
}
}

View File

@ -95,9 +95,9 @@ public class HybridPlotWorld extends ClassicPlotWorld {
final String schem1Str = "GEN_ROAD_SCHEMATIC/" + this.worldname + "/sideroad";
final String schem2Str = "GEN_ROAD_SCHEMATIC/" + this.worldname + "/intersection";
final String schem3Str = "GEN_ROAD_SCHEMATIC/" + this.worldname + "/plot";
final Schematic schem1 = SchematicHandler.getSchematic(schem1Str);
final Schematic schem2 = SchematicHandler.getSchematic(schem2Str);
final Schematic schem3 = SchematicHandler.getSchematic(schem3Str);
final Schematic schem1 = SchematicHandler.manager.getSchematic(schem1Str);
final Schematic schem2 = SchematicHandler.manager.getSchematic(schem2Str);
final Schematic schem3 = SchematicHandler.manager.getSchematic(schem3Str);
final int shift = (int) Math.floor(this.ROAD_WIDTH / 2);
int oddshift = 0;
if ((this.ROAD_WIDTH % 2) != 0) {

View File

@ -72,11 +72,11 @@ public abstract class HybridUtils {
final int ty = get_ey(world, bx, tx, bz, tz, by);
final Location pos3 = new Location(world, bx, by, bz);
final Location pos4 = new Location(world, tx, ty, tz);
final CompoundTag sideroad = SchematicHandler.getCompoundTag(world, pos1, pos2);
final CompoundTag intersection = SchematicHandler.getCompoundTag(world, pos3, pos4);
final CompoundTag sideroad = SchematicHandler.manager.getCompoundTag(world, pos1, pos2);
final CompoundTag intersection = SchematicHandler.manager.getCompoundTag(world, pos3, pos4);
final String dir = PlotSquared.IMP.getDirectory() + File.separator + "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + plot.world + File.separator;
SchematicHandler.save(sideroad, dir + "sideroad.schematic");
SchematicHandler.save(intersection, dir + "intersection.schematic");
SchematicHandler.manager.save(sideroad, dir + "sideroad.schematic");
SchematicHandler.manager.save(intersection, dir + "intersection.schematic");
plotworld.ROAD_SCHEMATIC_ENABLED = true;
plotworld.setupSchematics();
return true;

View File

@ -0,0 +1,74 @@
package com.intellectualcrafters.plot.object.schematic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.block.BlockState;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import com.intellectualcrafters.jnbt.ByteTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.Tag;
public class StateWrapper {
public BlockState state;
public StateWrapper(BlockState state) {
this.state = state;
}
public CompoundTag getTag() {
if (state instanceof InventoryHolder) {
InventoryHolder inv = (InventoryHolder) state;
ItemStack[] contents = inv.getInventory().getContents();
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, serializeInventory(contents)));
return new CompoundTag(values);
}
return null;
}
public String getId() {
return "Chest";
}
public List<CompoundTag> serializeInventory(ItemStack[] items) {
List<CompoundTag> tags = new ArrayList<CompoundTag>();
for (int i = 0; i < items.length; ++i) {
if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag("Slot", (byte) i));
tags.add(new CompoundTag(tagData));
}
}
return tags;
}
public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<String, Tag>();
data.put("id", new ShortTag("id", (short) item.getTypeId()));
data.put("Damage", new ShortTag("Damage", item.getDurability()));
data.put("Count", new ByteTag("Count", (byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<CompoundTag>();
for(Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<String, Tag>();
enchantment.put("id", new ShortTag("id", (short) entry.getKey().getId()));
enchantment.put("lvl", new ShortTag("lvl", entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(enchantment));
}
Map<String, Tag> auxData = new HashMap<String, Tag>();
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag("tag", auxData));
}
return data;
}
}

View File

@ -0,0 +1,149 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// 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, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.intellectualcrafters.plot.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import com.intellectualcrafters.jnbt.ByteArrayTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.IntTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.StringTag;
import com.intellectualcrafters.jnbt.Tag;
import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.schematic.StateWrapper;
/**
* Schematic Handler
*
* @author Citymonstret
* @author Empire92
*/
public class BukkitSchematicHandler extends SchematicHandler {
@Override
public CompoundTag getCompoundTag(final String world, final Location pos1, final Location pos2) {
// loading chunks
int i = 0;
int j = 0;
try {
for (i = (pos1.getX() / 16) * 16; i < (16 + ((pos2.getX() / 16) * 16)); i += 16) {
for (j = (pos1.getZ() / 16) * 16; j < (16 + ((pos2.getZ() / 16) * 16)); j += 16) {
boolean result = ChunkManager.manager.loadChunk(world, new ChunkLoc(i, j));
if (!result) {
return null;
}
}
}
} catch (final Exception e) {
PlotSquared.log("&7 - Cannot save: corrupt chunk at " + (i / 16) + ", " + (j / 16));
return null;
}
final int width = (pos2.getX() - pos1.getX()) + 1;
final int height = (pos2.getY() - pos1.getY()) + 1;
final int length = (pos2.getZ() - pos1.getZ()) + 1;
final HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag("Width", (short) width));
schematic.put("Length", new ShortTag("Length", (short) length));
schematic.put("Height", new ShortTag("Height", (short) height));
schematic.put("Materials", new StringTag("Materials", "Alpha"));
schematic.put("WEOriginX", new IntTag("WEOriginX", 0));
schematic.put("WEOriginY", new IntTag("WEOriginY", 0));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", 0));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0));
final byte[] blocks = new byte[width * height * length];
byte[] addBlocks = null;
final byte[] blockData = new byte[width * height * length];
final int sx = pos1.getX();
pos2.getX();
final int sz = pos1.getZ();
pos2.getZ();
final int sy = pos1.getY();
pos2.getY();
List<Tag> tileEntities = new ArrayList<Tag>();
World worldObj = Bukkit.getWorld(world);
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
for (int y = 0; y < height; y++) {
final int index = (y * width * length) + (z * width) + x;
Block block = worldObj.getBlockAt(sx + x, sy + y, sz + z);
BlockState state = block.getState();
if (state != null) {
StateWrapper wrapper = new StateWrapper(state);
CompoundTag rawTag = wrapper.getTag();
if (rawTag != null) {
Map<String, Tag> values = new HashMap<String, Tag>();
for (Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
values.put("id", new StringTag("id", wrapper.getId()));
values.put("x", new IntTag("x", x));
values.put("y", new IntTag("y", y));
values.put("z", new IntTag("z", z));
CompoundTag tileEntityTag = new CompoundTag(values);
tileEntities.add(tileEntityTag);
}
}
int id = block.getTypeId();
byte data = block.getData();
if (id > 255) {
if (addBlocks == null) {
addBlocks = new byte[(blocks.length >> 1) + 1];
}
addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? (addBlocks[index >> 1] & 0xF0) | ((id >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((id >> 8) & 0xF) << 4));
}
blocks[index] = (byte) id;
blockData[index] = data;
}
}
}
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
if (addBlocks != null) {
schematic.put("AddBlocks", new ByteArrayTag("AddBlocks", addBlocks));
}
return new CompoundTag("Schematic", schematic);
}
}

View File

@ -1,23 +1,3 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// 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, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.intellectualcrafters.plot.util;
import java.io.File;
@ -26,37 +6,25 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.bukkit.Chunk;
import com.intellectualcrafters.jnbt.ByteArrayTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.IntTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.NBTInputStream;
import com.intellectualcrafters.jnbt.NBTOutputStream;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.StringTag;
import com.intellectualcrafters.jnbt.Tag;
import com.intellectualcrafters.plot.PlotSquared;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
/**
* Schematic Handler
*
* @author Citymonstret
* @author Empire92
*/
public class SchematicHandler {
public abstract class SchematicHandler {
public static SchematicHandler manager = new BukkitSchematicHandler();
/**
* Paste a schematic
*
@ -66,7 +34,7 @@ public class SchematicHandler {
*
* @return true if succeeded
*/
public static boolean paste(final Location location, final Schematic schematic, final Plot plot, final int x_offset, final int z_offset) {
public boolean paste(final Location location, final Schematic schematic, final Plot plot, final int x_offset, final int z_offset) {
if (schematic == null) {
PlotSquared.log("Schematic == null :|");
return false;
@ -109,7 +77,7 @@ public class SchematicHandler {
return true;
}
public static Schematic getSchematic(final CompoundTag tag, final File file) {
public Schematic getSchematic(final CompoundTag tag, final File file) {
final Map<String, Tag> tagMap = tag.getValue();
byte[] addId = new byte[0];
if (tagMap.containsKey("AddBlocks")) {
@ -140,7 +108,7 @@ public class SchematicHandler {
}
return new Schematic(collection, dimension, file);
}
/**
* Get a schematic
*
@ -148,7 +116,7 @@ public class SchematicHandler {
*
* @return schematic if found, else null
*/
public static Schematic getSchematic(final String name) {
public Schematic getSchematic(final String name) {
{
final File parent = new File(PlotSquared.IMP.getDirectory() + File.separator + "schematics");
if (!parent.exists()) {
@ -173,7 +141,7 @@ public class SchematicHandler {
return null;
}
}
/**
* Saves a schematic to a file path
*
@ -182,7 +150,7 @@ public class SchematicHandler {
*
* @return true if succeeded
*/
public static boolean save(final CompoundTag tag, final String path) {
public boolean save(final CompoundTag tag, final String path) {
if (tag == null) {
PlotSquared.log("&cCannot save empty tag");
return false;
@ -201,7 +169,7 @@ public class SchematicHandler {
}
return true;
}
/**
* Gets the schematic of a plot
*
@ -210,7 +178,7 @@ public class SchematicHandler {
*
* @return tag
*/
public static CompoundTag getCompoundTag(final String world, final PlotId id) {
public CompoundTag getCompoundTag(final String world, final PlotId id) {
if (!PlotSquared.getPlots(world).containsKey(id)) {
return null;
}
@ -218,80 +186,10 @@ public class SchematicHandler {
final Location pos2 = MainUtil.getPlotTopLoc(world, id);
return getCompoundTag(world, pos1, pos2);
}
@SuppressWarnings("deprecation")
public static CompoundTag getCompoundTag(final String world, final Location pos1, final Location pos2) {
// loading chunks
int i = 0;
int j = 0;
try {
for (i = (pos1.getX() / 16) * 16; i < (16 + ((pos2.getX() / 16) * 16)); i += 16) {
for (j = (pos1.getZ() / 16) * 16; j < (16 + ((pos2.getZ() / 16) * 16)); j += 16) {
final Chunk chunk = BukkitUtil.getChunkAt(world, i, j);
final boolean result = chunk.load(false);
if (!result) {
// Plot is not even generated
return null;
}
}
}
} catch (final Exception e) {
PlotSquared.log("&7 - Cannot save: corrupt chunk at " + (i / 16) + ", " + (j / 16));
return null;
}
final int width = (pos2.getX() - pos1.getX()) + 1;
final int height = (pos2.getY() - pos1.getY()) + 1;
final int length = (pos2.getZ() - pos1.getZ()) + 1;
final HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag("Width", (short) width));
schematic.put("Length", new ShortTag("Length", (short) length));
schematic.put("Height", new ShortTag("Height", (short) height));
schematic.put("Materials", new StringTag("Materials", "Alpha"));
schematic.put("WEOriginX", new IntTag("WEOriginX", 0));
schematic.put("WEOriginY", new IntTag("WEOriginY", 0));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", 0));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0));
final byte[] blocks = new byte[width * height * length];
byte[] addBlocks = null;
final byte[] blockData = new byte[width * height * length];
final int sx = pos1.getX();
pos2.getX();
final int sz = pos1.getZ();
pos2.getZ();
final int sy = pos1.getY();
pos2.getY();
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
for (int y = 0; y < height; y++) {
final int index = (y * width * length) + (z * width) + x;
final PlotBlock block = BukkitUtil.getBlock(new Location(world, sx + x, sy + y, sz + z));
if (block.id > 255) {
if (addBlocks == null) {
addBlocks = new byte[(blocks.length >> 1) + 1];
}
addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? (addBlocks[index >> 1] & 0xF0) | ((block.id >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((block.id >> 8) & 0xF) << 4));
}
blocks[index] = (byte) block.id;
blockData[index] = block.data;
// We need worldedit to save tileentity data or entities
// - it uses NMS and CB internal code, which changes every
// update
}
}
}
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, new ArrayList<Tag>()));
if (addBlocks != null) {
schematic.put("AddBlocks", new ByteArrayTag("AddBlocks", addBlocks));
}
return new CompoundTag("Schematic", schematic);
}
public static boolean pastePart(final String world, final DataCollection[] blocks, final Location l1, final int x_offset, final int z_offset, final int i1, final int i2, final int WIDTH, final int LENGTH) {
public abstract CompoundTag getCompoundTag(final String world, final Location pos1, final Location pos2);
public boolean pastePart(final String world, final DataCollection[] blocks, final Location l1, final int x_offset, final int z_offset, final int i1, final int i2, final int WIDTH, final int LENGTH) {
int length = 0;
for (int i = i1; i <= i2; i++) {
if (blocks[i].block == 0) {
@ -334,7 +232,7 @@ public class SchematicHandler {
*
* @author Citymonstret
*/
public static class Schematic {
public class Schematic {
private final DataCollection[] blockCollection;
private final Dimension schematicDimension;
private final File file;
@ -363,7 +261,7 @@ public class SchematicHandler {
*
* @author Citymonstret
*/
public static class Dimension {
public class Dimension {
private final int x;
private final int y;
private final int z;
@ -392,7 +290,7 @@ public class SchematicHandler {
*
* @author Citymonstret
*/
public static class DataCollection {
public class DataCollection {
private final short block;
private final byte data;