Update to WorldEdit 7 (and WE7-compatible schematics, *hopefully keeping legacy*)

This commit is contained in:
dordsor21 2018-12-19 23:18:57 +00:00
parent e7b25d3fc8
commit fa2dbb2b89
52 changed files with 742 additions and 3297 deletions

View File

@ -8,6 +8,7 @@ repositories {
dependencies { dependencies {
compile project(':Core') compile project(':Core')
compile 'org.spigotmc:spigot-api:1.13-R0.1-SNAPSHOT' compile 'org.spigotmc:spigot-api:1.13-R0.1-SNAPSHOT'
compile(group: 'com.sk89q.worldedit', name: 'worldedit-bukkit', version: '7.0.0-SNAPSHOT')
compile("net.milkbowl.vault:VaultAPI:1.6") { compile("net.milkbowl.vault:VaultAPI:1.6") {
exclude module: 'bukkit' exclude module: 'bukkit'
} }

View File

@ -1,47 +1,14 @@
package com.github.intellectualsites.plotsquared.bukkit; package com.github.intellectualsites.plotsquared.bukkit;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
import com.github.intellectualsites.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector; import com.github.intellectualsites.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector;
import com.github.intellectualsites.plotsquared.bukkit.database.plotme.LikePlotMeConverter; import com.github.intellectualsites.plotsquared.bukkit.database.plotme.LikePlotMeConverter;
import com.github.intellectualsites.plotsquared.bukkit.database.plotme.PlotMeConnector_017; import com.github.intellectualsites.plotsquared.bukkit.database.plotme.PlotMeConnector_017;
import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator; import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.github.intellectualsites.plotsquared.bukkit.listeners.ChunkListener; import com.github.intellectualsites.plotsquared.bukkit.listeners.*;
import com.github.intellectualsites.plotsquared.bukkit.listeners.EntityPortal_1_7_9;
import com.github.intellectualsites.plotsquared.bukkit.listeners.EntitySpawnListener;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlayerEvents;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlayerEvents183;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlayerEvents_1_8;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlayerEvents_1_9;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlotPlusListener;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlotPlusListener_1_12;
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlotPlusListener_Legacy;
import com.github.intellectualsites.plotsquared.bukkit.listeners.SingleWorldListener;
import com.github.intellectualsites.plotsquared.bukkit.listeners.WorldEvents;
import com.github.intellectualsites.plotsquared.bukkit.titles.DefaultTitle_111; import com.github.intellectualsites.plotsquared.bukkit.titles.DefaultTitle_111;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitBlockRegistry; import com.github.intellectualsites.plotsquared.bukkit.util.*;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitChatManager;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitChunkManager;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitCommand;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitEconHandler;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitEventUtil;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitHybridUtils;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitLegacyMappings;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitSchematicHandler;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitSetupUtils;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitTaskManager;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitVersion;
import com.github.intellectualsites.plotsquared.bukkit.util.Metrics;
import com.github.intellectualsites.plotsquared.bukkit.util.SendChunk;
import com.github.intellectualsites.plotsquared.bukkit.util.SetGenCB;
import com.github.intellectualsites.plotsquared.bukkit.util.block.BukkitLocalQueue; import com.github.intellectualsites.plotsquared.bukkit.util.block.BukkitLocalQueue;
import com.github.intellectualsites.plotsquared.bukkit.uuid.DefaultUUIDWrapper; import com.github.intellectualsites.plotsquared.bukkit.uuid.*;
import com.github.intellectualsites.plotsquared.bukkit.uuid.FileUUIDHandler;
import com.github.intellectualsites.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
import com.github.intellectualsites.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
import com.github.intellectualsites.plotsquared.bukkit.uuid.SQLUUIDHandler;
import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection; import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
import com.github.intellectualsites.plotsquared.plot.IPlotMain; import com.github.intellectualsites.plotsquared.plot.IPlotMain;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
@ -52,58 +19,20 @@ import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
import com.github.intellectualsites.plotsquared.plot.generator.HybridGen; import com.github.intellectualsites.plotsquared.plot.generator.HybridGen;
import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils; import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils;
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator; import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
import com.github.intellectualsites.plotsquared.plot.object.BlockRegistry; import com.github.intellectualsites.plotsquared.plot.object.*;
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.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
import com.github.intellectualsites.plotsquared.plot.object.chat.PlainChatManager; import com.github.intellectualsites.plotsquared.plot.object.chat.PlainChatManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager; import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotArea; import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotArea;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager; import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator; import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator;
import com.github.intellectualsites.plotsquared.plot.util.AbstractTitle; import com.github.intellectualsites.plotsquared.plot.util.*;
import com.github.intellectualsites.plotsquared.plot.util.ChatManager;
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
import com.github.intellectualsites.plotsquared.plot.util.ConsoleColors;
import com.github.intellectualsites.plotsquared.plot.util.EconHandler;
import com.github.intellectualsites.plotsquared.plot.util.EventUtil;
import com.github.intellectualsites.plotsquared.plot.util.InventoryUtil;
import com.github.intellectualsites.plotsquared.plot.util.LegacyMappings;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandlerImplementation;
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
import com.github.intellectualsites.plotsquared.plot.util.block.QueueProvider; import com.github.intellectualsites.plotsquared.plot.util.block.QueueProvider;
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper; import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nullable;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@ -116,6 +45,15 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import javax.annotation.Nullable;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain { public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
@Getter private static WorldEdit worldEdit; @Getter private static WorldEdit worldEdit;
@ -168,12 +106,13 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
} }
private final LegacyMappings legacyMappings = new BukkitLegacyMappings(); private final LegacyMappings legacyMappings = new BukkitLegacyMappings();
private final BlockRegistry<Material> blockRegistry =
new BukkitBlockRegistry(Material.values());
private int[] version; private int[] version;
@Getter private String pluginName; @Getter private String pluginName;
@Getter private SingleWorldListener singleWorldListener; @Getter private SingleWorldListener singleWorldListener;
private Method methodUnloadChunk0; private Method methodUnloadChunk0;
private boolean methodUnloadSetup = false; private boolean methodUnloadSetup = false;
private final BlockRegistry<Material> blockRegistry = new BukkitBlockRegistry(Material.values());
@Override public int[] getServerVersion() { @Override public int[] getServerVersion() {
if (this.version == null) { if (this.version == null) {
@ -927,8 +866,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return names; return names;
} }
@Override @Override public BlockRegistry<Material> getBlockRegistry() {
public BlockRegistry<Material> getBlockRegistry() {
return this.blockRegistry; return this.blockRegistry;
} }

View File

@ -1,9 +1,8 @@
package com.github.intellectualsites.plotsquared.bukkit.object.schematic; package com.github.intellectualsites.plotsquared.bukkit.object.schematic;
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil; import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
import com.github.intellectualsites.plotsquared.jnbt.*; import com.sk89q.jnbt.*;
import com.github.intellectualsites.plotsquared.plot.object.schematic.ItemType; import org.bukkit.Material;
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
@ -39,21 +38,14 @@ public class StateWrapper {
case "chest": case "chest":
List<Tag> itemsTag = this.tag.getListTag("Items").getValue(); List<Tag> itemsTag = this.tag.getListTag("Items").getValue();
int length = itemsTag.size(); int length = itemsTag.size();
short[] ids = new short[length]; String[] ids = new String[length];
byte[] datas = new byte[length];
byte[] amounts = new byte[length]; byte[] amounts = new byte[length];
byte[] slots = new byte[length]; byte[] slots = new byte[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
Tag itemTag = itemsTag.get(i); Tag itemTag = itemsTag.get(i);
CompoundTag itemComp = (CompoundTag) itemTag; CompoundTag itemComp = (CompoundTag) itemTag;
short id = itemComp.getShort("id"); String id = itemComp.getString("id");
String idStr = itemComp.getString("id");
if (idStr != null && !MathMan.isInteger(idStr)) {
idStr = idStr.split(":")[1].toLowerCase();
id = (short) ItemType.getId(idStr);
}
ids[i] = id; ids[i] = id;
datas[i] = (byte) itemComp.getShort("Damage");
amounts[i] = itemComp.getByte("Count"); amounts[i] = itemComp.getByte("Count");
slots[i] = itemComp.getByte("Slot"); slots[i] = itemComp.getByte("Slot");
} }
@ -67,7 +59,8 @@ public class StateWrapper {
InventoryHolder holder = (InventoryHolder) state; InventoryHolder holder = (InventoryHolder) state;
Inventory inv = holder.getInventory(); Inventory inv = holder.getInventory();
for (int i = 0; i < ids.length; i++) { for (int i = 0; i < ids.length; i++) {
ItemStack item = new ItemStack(ids[i], amounts[i], datas[i]); ItemStack item =
new ItemStack(Material.getMaterial(ids[i]), (int) amounts[i]);
inv.addItem(item); inv.addItem(item);
} }
state.update(true); state.update(true);
@ -85,8 +78,7 @@ public class StateWrapper {
InventoryHolder inv = (InventoryHolder) this.state; InventoryHolder inv = (InventoryHolder) this.state;
ItemStack[] contents = inv.getInventory().getContents(); ItemStack[] contents = inv.getInventory().getContents();
Map<String, Tag> values = new HashMap<>(); Map<String, Tag> values = new HashMap<>();
values.put("Items", values.put("Items", new ListTag(CompoundTag.class, serializeInventory(contents)));
new ListTag("Items", CompoundTag.class, serializeInventory(contents)));
return new CompoundTag(values); return new CompoundTag(values);
} }
return null; return null;
@ -101,41 +93,29 @@ public class StateWrapper {
for (int i = 0; i < items.length; ++i) { for (int i = 0; i < items.length; ++i) {
if (items[i] != null) { if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]); Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag("Slot", (byte) i)); tagData.put("Slot", new ByteTag((byte) i));
tags.add(new CompoundTag(tagData)); tags.add(new CompoundTag(tagData));
} }
} }
return tags; return tags;
} }
/*
* TODO: Move this into the sponge module!
*
public Map<String, Tag> serializeItem(final org.spongepowered.api.item.inventory.ItemStack item) {
final Map<String, Tag> data = new HashMap<String, Tag>();
// FIXME serialize sponge item
return data;
}
*/
public Map<String, Tag> serializeItem(ItemStack item) { public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<>(); Map<String, Tag> data = new HashMap<>();
data.put("id", new ShortTag("id", (short) item.getTypeId())); data.put("id", new StringTag(item.getType().name()));
data.put("Damage", new ShortTag("Damage", item.getDurability())); data.put("Damage", new ShortTag(item.getDurability()));
data.put("Count", new ByteTag("Count", (byte) item.getAmount())); data.put("Count", new ByteTag((byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) { if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<>(); List<CompoundTag> enchantmentList = new ArrayList<>();
for (Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) { for (Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<>(); Map<String, Tag> enchantment = new HashMap<>();
enchantment.put("id", new ShortTag("id", (short) entry.getKey().getId())); enchantment.put("id", new StringTag(entry.getKey().toString()));
enchantment.put("lvl", new ShortTag("lvl", entry.getValue().shortValue())); enchantment.put("lvl", new ShortTag(entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(enchantment)); enchantmentList.add(new CompoundTag(enchantment));
} }
Map<String, Tag> auxData = new HashMap<>(); Map<String, Tag> auxData = new HashMap<>();
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList)); auxData.put("ench", new ListTag(CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag("tag", auxData)); data.put("tag", new CompoundTag(auxData));
} }
return data; return data;
} }

View File

@ -5,20 +5,12 @@ import com.github.intellectualsites.plotsquared.plot.object.PlotBlock;
import com.github.intellectualsites.plotsquared.plot.object.StringPlotBlock; import com.github.intellectualsites.plotsquared.plot.object.StringPlotBlock;
import com.github.intellectualsites.plotsquared.plot.util.LegacyMappings; import com.github.intellectualsites.plotsquared.plot.util.LegacyMappings;
import com.github.intellectualsites.plotsquared.plot.util.StringComparison; import com.github.intellectualsites.plotsquared.plot.util.StringComparison;
import java.util.Arrays; import lombok.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.bukkit.Material; import org.bukkit.Material;
import java.util.*;
import java.util.stream.Collectors;
/** /**
* Borrowed from https://github.com/Phoenix616/IDConverter/blob/master/mappings/src/main/java/de/themoep/idconverter/IdMappings.java * Borrowed from https://github.com/Phoenix616/IDConverter/blob/master/mappings/src/main/java/de/themoep/idconverter/IdMappings.java
* Original License: * Original License:
@ -705,8 +697,10 @@ public class BukkitLegacyMappings extends LegacyMappings {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public StringComparison<PlotBlock>.ComparisonResult getClosestsMatch(@NonNull final String string) { public StringComparison<PlotBlock>.ComparisonResult getClosestsMatch(
final StringComparison<PlotBlock> comparison = new StringComparison<>(string, getPlotBlocks()); @NonNull final String string) {
final StringComparison<PlotBlock> comparison =
new StringComparison<>(string, getPlotBlocks());
return comparison.getBestMatchAdvanced(); return comparison.getBestMatchAdvanced();
} }
@ -812,8 +806,7 @@ public class BukkitLegacyMappings extends LegacyMappings {
return LegacyPlotBlock.get(numericalId, dataValue); return LegacyPlotBlock.get(numericalId, dataValue);
} }
@Override @Override public String toString() {
public String toString() {
return this.newName; return this.newName;
} }
} }

View File

@ -1,28 +1,29 @@
package com.github.intellectualsites.plotsquared.bukkit.util; package com.github.intellectualsites.plotsquared.bukkit.util;
import com.github.intellectualsites.plotsquared.bukkit.object.schematic.StateWrapper; import com.github.intellectualsites.plotsquared.bukkit.object.schematic.StateWrapper;
import com.github.intellectualsites.plotsquared.jnbt.*;
import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc; import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc;
import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
import com.github.intellectualsites.plotsquared.plot.util.LegacyMappings;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import java.io.ByteArrayOutputStream;
import java.util.*; import java.util.*;
/** /**
* Schematic Handler. * Schematic Handler.
*/ */
public class BukkitSchematicHandler extends SchematicHandler { public abstract class BukkitSchematicHandler extends SchematicHandler {
@Override public void getCompoundTag(final String world, final Set<RegionWrapper> regions, @Override public void getCompoundTag(final String world, final Set<RegionWrapper> regions,
final RunnableVal<CompoundTag> whenDone) { final RunnableVal<CompoundTag> whenDone) {
@ -34,25 +35,35 @@ public class BukkitSchematicHandler extends SchematicHandler {
final Location bot = corners[0]; final Location bot = corners[0];
Location top = corners[1]; Location top = corners[1];
CuboidRegion cuboidRegion =
new CuboidRegion(BukkitUtil.IMP.getWeWorld(world), bot.getBlockVector3(),
top.getBlockVector3());
final int width = top.getX() - bot.getX() + 1; final int width = top.getX() - bot.getX() + 1;
int height = top.getY() - bot.getY() + 1; int height = top.getY() - bot.getY() + 1;
final int length = top.getZ() - bot.getZ() + 1; final int length = top.getZ() - bot.getZ() + 1;
// Main Schematic tag Map<String, Tag> schematic = new HashMap<>();
final HashMap<String, Tag> schematic = new HashMap<>(); schematic.put("Version", new IntTag(1));
schematic.put("Width", new ShortTag("Width", (short) width));
schematic.put("Length", new ShortTag("Length", (short) length)); Map<String, Tag> metadata = new HashMap<>();
schematic.put("Height", new ShortTag("Height", (short) height)); metadata.put("WEOffsetX", new IntTag(0));
schematic.put("Materials", new StringTag("Materials", "Alpha")); metadata.put("WEOffsetY", new IntTag(0));
schematic.put("WEOriginX", new IntTag("WEOriginX", 0)); metadata.put("WEOffsetZ", new IntTag(0));
schematic.put("WEOriginY", new IntTag("WEOriginY", 0));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", 0)); schematic.put("Metadata", new CompoundTag(metadata));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0)); schematic.put("Width", new ShortTag((short) width));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0)); schematic.put("Height", new ShortTag((short) height));
// Arrays of data types schematic.put("Length", new ShortTag((short) length));
final List<CompoundTag> tileEntities = new ArrayList<>();
final byte[] blocks = new byte[width * height * length]; // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
final byte[] blockData = new byte[width * height * length]; 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<>();
ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length);
// Queue // Queue
final ArrayDeque<RegionWrapper> queue = new ArrayDeque<>(regions); final ArrayDeque<RegionWrapper> queue = new ArrayDeque<>(regions);
TaskManager.runTask(new Runnable() { TaskManager.runTask(new Runnable() {
@ -60,15 +71,18 @@ public class BukkitSchematicHandler extends SchematicHandler {
if (queue.isEmpty()) { if (queue.isEmpty()) {
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(new Runnable() {
@Override public void run() { @Override public void run() {
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks)); schematic.put("PaletteMax", new IntTag(paletteMax[0]));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", Map<String, Tag> paletteTag = new HashMap<>();
new ListTag("Entities", CompoundTag.class, palette.forEach(
new ArrayList<Tag>())); (key, value) -> paletteTag.put(key, new IntTag(value)));
schematic.put("Palette", new CompoundTag(paletteTag));
schematic
.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
schematic.put("TileEntities", schematic.put("TileEntities",
new ListTag("TileEntities", CompoundTag.class, new ListTag(CompoundTag.class, tileEntities));
tileEntities)); whenDone.value = new CompoundTag(schematic);
whenDone.value = new CompoundTag("Schematic", schematic);
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
System.gc(); System.gc();
System.gc(); System.gc();
@ -140,148 +154,48 @@ public class BukkitSchematicHandler extends SchematicHandler {
for (int x = xxb; x <= xxt; x++) { for (int x = xxb; x <= xxt; x++) {
int rx = x - bx; int rx = x - bx;
int index = i2 + rx; int index = i2 + rx;
Block block = worldObj.getBlockAt(x, y, z); BlockVector3 point = BlockVector3.at(x, y, z);
int id = LegacyMappings.fromNewName(block.getType().name()).getNumericalId(); BaseBlock block =
switch (id) { cuboidRegion.getWorld().getFullBlock(point);
case 0: if (block.getNbtData() != null) {
case 2: Map<String, Tag> values = new HashMap<>();
case 4: for (Map.Entry<String, Tag> entry : block
case 13: .getNbtData().getValue().entrySet()) {
case 14: values
case 15: .put(entry.getKey(), entry.getValue());
case 20: }
case 21:
case 22: values.remove(
case 24: "id"); // Remove 'id' if it exists. We want 'Id'
case 30:
case 32: // Positions are kept in NBT, we don't want that.
case 37: values.remove("x");
case 39: values.remove("y");
case 40: values.remove("z");
case 41:
case 42: values
case 45: .put("Id", new StringTag(block.getNbtId()));
case 46: values.put("Pos",
case 47: new IntArrayTag(new int[] {x, y, z}));
case 48:
case 49: tileEntities.add(new CompoundTag(values));
case 51:
case 55:
case 56:
case 57:
case 58:
case 60:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 121:
case 122:
case 129:
case 133:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
break;
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178:
// TODO implement fully
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<>(
rawTag.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);
}
}
default:
blockData[index] = block.getData();
} }
// For optimization reasons, we are not supporting custom data types String blockKey =
// Especially since the most likely reason beyond this range is modded servers in which the blocks block.toImmutableState().getAsString();
// have NBT int blockId;
// if (type > 255) { if (palette.containsKey(blockKey)) {
// if (addBlocks == null) { blockId = palette.get(blockKey);
// addBlocks = new byte[(blocks.length >> 1) + 1]; } else {
// } blockId = paletteMax[0];
// addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? palette.put(blockKey, blockId);
// (addBlocks[index >> 1] & 0xF0) | ((type >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((type paletteMax[0]++;
// >> 8) & 0xF) << 4)); }
// }
blocks[index] = (byte) id; while ((blockId & -128) != 0) {
buffer.write(blockId & 127 | 128);
blockId >>>= 7;
}
buffer.write(blockId);
} }
} }
} }

View File

@ -467,6 +467,10 @@ import org.bukkit.material.Wool;
} }
} }
public com.sk89q.worldedit.world.World getWeWorld(String world) {
return new BukkitWorld(Bukkit.getWorld(world));
}
@Override public PlotBlock getBlock(@NonNull final Location location) { @Override public PlotBlock getBlock(@NonNull final Location location) {
final World world = getWorld(location.getWorld()); final World world = getWorld(location.getWorld());
final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ()); final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ());

View File

@ -1,50 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Byte_Array} tag.
*/
public final class ByteArrayTag extends Tag {
private final byte[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteArrayTag(byte[] value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ByteArrayTag(String name, byte[] value) {
super(name);
this.value = value;
}
@Override public byte[] getValue() {
return this.value;
}
@Override public String toString() {
StringBuilder hex = new StringBuilder();
for (byte b : this.value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Byte_Array" + append + ": " + hex;
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Byte} tag.
*/
public final class ByteTag extends Tag {
private final byte value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ByteTag(byte value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ByteTag(String name, byte value) {
super(name);
this.value = value;
}
@Override public Byte getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Byte" + append + ": " + this.value;
}
}

View File

@ -1,370 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The {@code TAG_Compound} tag.
*/
public final class CompoundTag extends Tag {
private Map<String, Tag> value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public CompoundTag(Map<String, Tag> value) {
this.value = Collections.unmodifiableMap(value);
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public CompoundTag(String name, Map<String, Tag> value) {
super(name);
this.value = Collections.unmodifiableMap(value);
}
/**
* Returns whether this compound tag contains the given key.
*
* @param key the given key
* @return true if the tag contains the given key
*/
public boolean containsKey(String key) {
return this.value.containsKey(key);
}
@Override public Map<String, Tag> getValue() {
return this.value;
}
/**
* Return a new compound tag with the given values.
*
* @param value the value
* @return the new compound tag
*/
public CompoundTag setValue(Map<String, Tag> value) {
if (value == null) {
this.value = Collections.unmodifiableMap(new HashMap<String, Tag>());
} else {
this.value = Collections.unmodifiableMap(value);
}
return this;
}
/**
* Create a compound tag builder.
*
* @return the builder
*/
public CompoundTagBuilder createBuilder() {
return new CompoundTagBuilder(new HashMap<String, Tag>(this.value));
}
/**
* Get a byte array named with the given key.
* <p>
* <p> If the key does not exist or its value is not a byte array
* tag, then an empty byte array will be returned. </p>
*
* @param key the key
* @return a byte array
*/
public byte[] getByteArray(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given key. <p> If the key does not exist or its value is not a byte tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return a byte
*/
public byte getByte(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given key. <p> If the key does not exist or its value is not a double tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return a double
*/
public double getDouble(String key) {
Tag tag = this.value.get(key);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given key, even if it's another type of number. <p> If the key does not exist or
* its value is not a number, then {@code 0} will be returned. </p>
*
* @param key the key
* @return a double
*/
public double asDouble(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given key. <p> If the key does not exist or its value is not a float tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return a float
*/
public float getFloat(String key) {
Tag tag = this.value.get(key);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given key. <p> If the key does not exist or its value is not an int array
* tag, then an empty array will be returned. </p>
*
* @param key the key
* @return an int array
*/
public int[] getIntArray(String key) {
Tag tag = this.value.get(key);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given key. <p> If the key does not exist or its value is not an int tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return an int
*/
public int getInt(String key) {
Tag tag = this.value.get(key);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given key, even if it's another type of number. <p> If the key does not exist or
* its value is not a number, then {@code 0} will be returned. </p>
*
* @param key the key
* @return an int
*/
public int asInt(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given key. <p> If the key does not exist or its value is not a list tag,
* then an empty list will be returned. </p>
*
* @param key the key
* @return a list of tags
*/
public List<Tag> getList(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given key. <p> If the key does not exist or its value is not a list
* tag, then an empty tag list will be returned. </p>
*
* @param key the key
* @return a tag list instance
*/
public ListTag getListTag(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(key, StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given key. <p> If the key does not exist or its value is not a list tag,
* then an empty list will be returned. If the given key references a list but the list of of a different type, then
* an empty list will also be returned. </p>
*
* @param key the key
* @param listType the class of the contained type
* @param <T> the type of list
* @return a list of tags
*/
@SuppressWarnings("unchecked") public <T extends Tag> List<T> getList(String key,
Class<T> listType) {
Tag tag = this.value.get(key);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given key. <p> If the key does not exist or its value is not a long tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return a long
*/
public long getLong(String key) {
Tag tag = this.value.get(key);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given key, even if it's another type of number. <p> If the key does not exist or
* its value is not a number, then {@code 0} will be returned. </p>
*
* @param key the key
* @return a long
*/
public long asLong(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0L;
}
}
/**
* Get a short named with the given key. <p> If the key does not exist or its value is not a short tag, then
* {@code 0} will be returned. </p>
*
* @param key the key
* @return a short
*/
public short getShort(String key) {
Tag tag = this.value.get(key);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given key. <p> If the key does not exist or its value is not a string tag, then
* {@code ""} will be returned. </p>
*
* @param key the key
* @return a string
*/
public String getString(String key) {
Tag tag = this.value.get(key);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_Compound").append(append).append(": ").append(this.value.size())
.append(" entries\r\n{\r\n");
for (Map.Entry<String, Tag> entry : this.value.entrySet()) {
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n "))
.append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -1,186 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.util.HashMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create compound tags.
*/
public class CompoundTagBuilder {
private final Map<String, Tag> entries;
/**
* Create a new instance.
*/
CompoundTagBuilder() {
this.entries = new HashMap<>();
}
/**
* Create a new instance and use the given map (which will be modified).
*
* @param value the value
*/
CompoundTagBuilder(Map<String, Tag> value) {
checkNotNull(value);
this.entries = value;
}
/**
* Create a new builder instance.
*
* @return a new builder
*/
public static CompoundTagBuilder create() {
return new CompoundTagBuilder();
}
/**
* Put the given key and tag into the compound tag.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder put(String key, Tag value) {
checkNotNull(key);
checkNotNull(value);
this.entries.put(key, value);
return this;
}
/**
* Put the given key and value into the compound tag as a {@code ByteArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByteArray(String key, byte[] value) {
return put(key, new ByteArrayTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code ByteTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putByte(String key, byte value) {
return put(key, new ByteTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code DoubleTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putDouble(String key, double value) {
return put(key, new DoubleTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code FloatTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putFloat(String key, float value) {
return put(key, new FloatTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code IntArrayTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putIntArray(String key, int[] value) {
return put(key, new IntArrayTag(key, value));
}
/**
* Put the given key and value into the compound tag as an {@code IntTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putInt(String key, int value) {
return put(key, new IntTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code LongTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putLong(String key, long value) {
return put(key, new LongTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code ShortTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putShort(String key, short value) {
return put(key, new ShortTag(key, value));
}
/**
* Put the given key and value into the compound tag as a {@code StringTag}.
*
* @param key they key
* @param value the value
* @return this object
*/
public CompoundTagBuilder putString(String key, String value) {
return put(key, new StringTag(key, value));
}
/**
* Put all the entries from the given map into this map.
*
* @param value the map of tags
* @return this object
*/
public CompoundTagBuilder putAll(Map<String, ? extends Tag> value) {
checkNotNull(value);
for (Map.Entry<String, ? extends Tag> entry : value.entrySet()) {
put(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Build an unnamed compound tag with this builder's entries.
*
* @return the new compound tag
*/
public CompoundTag build() {
return new CompoundTag(new HashMap<String, Tag>(this.entries));
}
/**
* Build a new compound tag with this builder's entries.
*
* @param name the name of the tag
* @return the created compound tag
*/
public CompoundTag build(String name) {
return new CompoundTag(name, new HashMap<String, Tag>(this.entries));
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Double} tag.
*/
public final class DoubleTag extends Tag {
private final double value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public DoubleTag(double value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public DoubleTag(String name, double value) {
super(name);
this.value = value;
}
@Override public Double getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Double" + append + ": " + this.value;
}
}

View File

@ -1,21 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_End} tag.
*/
public final class EndTag extends Tag {
/**
* Creates the tag.
*/
public EndTag() {
}
@Override public Object getValue() {
return null;
}
@Override public String toString() {
return "TAG_End";
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Float} tag.
*/
public final class FloatTag extends Tag {
private final float value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public FloatTag(float value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public FloatTag(String name, float value) {
super(name);
this.value = value;
}
@Override public Float getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Float" + append + ": " + this.value;
}
}

View File

@ -1,54 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_Int_Array} tag.
*/
public final class IntArrayTag extends Tag {
private final int[] value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntArrayTag(int[] value) {
checkNotNull(value);
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public IntArrayTag(String name, int[] value) {
super(name);
checkNotNull(value);
this.value = value;
}
@Override public int[] getValue() {
return this.value;
}
@Override public String toString() {
StringBuilder hex = new StringBuilder();
for (int b : this.value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Int_Array" + append + ": " + hex;
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Int} tag.
*/
public final class IntTag extends Tag {
private final int value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public IntTag(int value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public IntTag(String name, int value) {
super(name);
this.value = value;
}
@Override public Integer getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Int" + append + ": " + this.value;
}
}

View File

@ -1,375 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_List} tag.
*/
public final class ListTag extends Tag {
private final Class<? extends Tag> type;
private final List<Tag> value;
/**
* Creates the tag with an empty name.
*
* @param type the type of tag
* @param value the value of the tag
*/
public ListTag(Class<? extends Tag> type, List<? extends Tag> value) {
checkNotNull(value);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param type the type of tag
* @param value the value of the tag
*/
public ListTag(String name, Class<? extends Tag> type, List<? extends Tag> value) {
super(name);
checkNotNull(value);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Gets the type of item in this list.
*
* @return The type of item in this list.
*/
public Class<? extends Tag> getType() {
return this.type;
}
@Override public List<Tag> getValue() {
return this.value;
}
/**
* Create a new list tag with this tag's name and type.
*
* @param list the new list
* @return a new list tag
*/
public ListTag setValue(List<Tag> list) {
return new ListTag(getName(), getType(), list);
}
/**
* Get the tag if it exists at the given index.
*
* @param index the index
* @return the tag or null
*/
public Tag getIfExists(int index) {
try {
return this.value.get(index);
} catch (NoSuchElementException ignored) {
return null;
}
}
/**
* Get a byte array named with the given index. <p> If the index does not exist or its value is not a byte
* array tag, then an empty byte array will be returned. </p>
*
* @param index the index
* @return a byte array
*/
public byte[] getByteArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteArrayTag) {
return ((ByteArrayTag) tag).getValue();
} else {
return new byte[0];
}
}
/**
* Get a byte named with the given index. <p> If the index does not exist or its value is not a byte tag, then
* {@code 0} will be returned. </p>
*
* @param index the index
* @return a byte
*/
public byte getByte(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else {
return (byte) 0;
}
}
/**
* Get a double named with the given index. <p> If the index does not exist or its value is not a double tag,
* then {@code 0} will be returned. </p>
*
* @param index the index
* @return a double
*/
public double getDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a double named with the given index, even if it's another type of number. <p> If the index does not
* exist or its value is not a number, then {@code 0} will be returned. </p>
*
* @param index the index
* @return a double
*/
public double asDouble(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a float named with the given index. <p> If the index does not exist or its value is not a float tag,
* then {@code 0} will be returned. </p>
*
* @param index the index
* @return a float
*/
public float getFloat(int index) {
Tag tag = getIfExists(index);
if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a {@code int[]} named with the given index. <p> If the index does not exist or its value is not an int
* array tag, then an empty array will be returned. </p>
*
* @param index the index
* @return an int array
*/
public int[] getIntArray(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntArrayTag) {
return ((IntArrayTag) tag).getValue();
} else {
return new int[0];
}
}
/**
* Get an int named with the given index. <p> If the index does not exist or its value is not an int tag, then
* {@code 0} will be returned. </p>
*
* @param index the index
* @return an int
*/
public int getInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get an int named with the given index, even if it's another type of number. <p> If the index does not exist
* or its value is not a number, then {@code 0} will be returned. </p>
*
* @param index the index
* @return an int
*/
public int asInt(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue().intValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().intValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().intValue();
} else {
return 0;
}
}
/**
* Get a list of tags named with the given index. <p> If the index does not exist or its value is not a list
* tag, then an empty list will be returned. </p>
*
* @param index the index
* @return a list of tags
*/
public List<Tag> getList(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return ((ListTag) tag).getValue();
} else {
return Collections.emptyList();
}
}
/**
* Get a {@code TagList} named with the given index. <p> If the index does not exist or its value is not a list
* tag, then an empty tag list will be returned. </p>
*
* @param index the index
* @return a tag list instance
*/
public ListTag getListTag(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
return (ListTag) tag;
} else {
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
}
}
/**
* Get a list of tags named with the given index. <p> If the index does not exist or its value is not a list
* tag, then an empty list will be returned. If the given index references a list but the list of of a different
* type, then an empty list will also be returned. </p>
*
* @param index the index
* @param listType the class of the contained type
* @param <T> the NBT type
* @return a list of tags
*/
@SuppressWarnings("unchecked") public <T extends Tag> List<T> getList(int index,
Class<T> listType) {
Tag tag = getIfExists(index);
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
if (listTag.getType().equals(listType)) {
return (List<T>) listTag.getValue();
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
}
/**
* Get a long named with the given index. <p> If the index does not exist or its value is not a long tag, then
* {@code 0} will be returned. </p>
*
* @param index the index
* @return a long
*/
public long getLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else {
return 0L;
}
}
/**
* Get a long named with the given index, even if it's another type of number. <p> If the index does not exist
* or its value is not a number, then {@code 0} will be returned. </p>
*
* @param index the index
* @return a long
*/
public long asLong(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ByteTag) {
return ((ByteTag) tag).getValue();
} else if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else if (tag instanceof IntTag) {
return ((IntTag) tag).getValue();
} else if (tag instanceof LongTag) {
return ((LongTag) tag).getValue();
} else if (tag instanceof FloatTag) {
return ((FloatTag) tag).getValue().longValue();
} else if (tag instanceof DoubleTag) {
return ((DoubleTag) tag).getValue().longValue();
} else {
return 0;
}
}
/**
* Get a short named with the given index. <p> If the index does not exist or its value is not a short tag,
* then {@code 0} will be returned. </p>
*
* @param index the index
* @return a short
*/
public short getShort(int index) {
Tag tag = getIfExists(index);
if (tag instanceof ShortTag) {
return ((ShortTag) tag).getValue();
} else {
return 0;
}
}
/**
* Get a string named with the given index. <p> If the index does not exist or its value is not a string tag,
* then {@code ""} will be returned. </p>
*
* @param index the index
* @return a string
*/
public String getString(int index) {
Tag tag = getIfExists(index);
if (tag instanceof StringTag) {
return ((StringTag) tag).getValue();
} else {
return "";
}
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_List").append(append).append(": ").append(this.value.size())
.append(" entries of type ").append(NBTUtils.getTypeName(this.type))
.append("\r\n{\r\n");
for (Tag t : this.value) {
bldr.append(" ").append(t.toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -1,111 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Helps create list tags.
*/
public class ListTagBuilder {
private final Class<? extends Tag> type;
private final List<Tag> entries;
/**
* Create a new instance.
*
* @param type of tag contained in this list
*/
ListTagBuilder(Class<? extends Tag> type) {
checkNotNull(type);
this.type = type;
this.entries = new ArrayList<>();
}
/**
* Create a new builder instance.
*
* @param type
* @return a new builder
*/
public static ListTagBuilder create(Class<? extends Tag> type) {
return new ListTagBuilder(type);
}
/**
* Create a new builder instance.
*
* @param entries
* @param <T>
* @return a new builder
*/
@SafeVarargs public static <T extends Tag> ListTagBuilder createWith(T... entries) {
checkNotNull(entries);
if (entries.length == 0) {
throw new IllegalArgumentException("This method needs an array of at least one entry");
}
Class<? extends Tag> type = entries[0].getClass();
for (int i = 1; i < entries.length; i++) {
if (!type.isInstance(entries[i])) {
throw new IllegalArgumentException("An array of different tag types was provided");
}
}
ListTagBuilder builder = new ListTagBuilder(type);
builder.addAll(Arrays.asList(entries));
return builder;
}
/**
* Add the given tag.
*
* @param value the tag
* @return this object
*/
public ListTagBuilder add(Tag value) {
checkNotNull(value);
if (!this.type.isInstance(value)) {
throw new IllegalArgumentException(
value.getClass().getCanonicalName() + " is not of expected type " + this.type
.getCanonicalName());
}
this.entries.add(value);
return this;
}
/**
* Add all the tags in the given list.
*
* @param value a list of tags
* @return this object
*/
public ListTagBuilder addAll(Collection<? extends Tag> value) {
checkNotNull(value);
for (Tag v : value) {
add(v);
}
return this;
}
/**
* Build an unnamed list tag with this builder's entries.
*
* @return the new list tag
*/
public ListTag build() {
return new ListTag(this.type, new ArrayList<Tag>(this.entries));
}
/**
* Build a new list tag with this builder's entries.
*
* @param name the name of the tag
* @return the created list tag
*/
public ListTag build(String name) {
return new ListTag(name, this.type, new ArrayList<Tag>(this.entries));
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Long} tag.
*/
public final class LongTag extends Tag {
private final long value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public LongTag(long value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public LongTag(String name, long value) {
super(name);
this.value = value;
}
@Override public Long getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Long" + append + ": " + this.value;
}
}

View File

@ -1,59 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* A class which holds constant values.
*/
public final class NBTConstants {
public static final Charset CHARSET = StandardCharsets.UTF_8;
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2, TYPE_INT = 3, TYPE_LONG =
4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6, TYPE_BYTE_ARRAY = 7, TYPE_STRING = 8, TYPE_LIST = 9,
TYPE_COMPOUND = 10, TYPE_INT_ARRAY = 11;
/**
* Default private constructor.
*/
private NBTConstants() {
}
/**
* Convert a type ID to its corresponding {@link Tag} class.
*
* @param id type ID
* @return tag class
* @throws IllegalArgumentException thrown if the tag ID is not valid
*/
public static Class<? extends Tag> getClassFromType(int id) {
switch (id) {
case TYPE_END:
return EndTag.class;
case TYPE_BYTE:
return ByteTag.class;
case TYPE_SHORT:
return ShortTag.class;
case TYPE_INT:
return IntTag.class;
case TYPE_LONG:
return LongTag.class;
case TYPE_FLOAT:
return FloatTag.class;
case TYPE_DOUBLE:
return DoubleTag.class;
case TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case TYPE_STRING:
return StringTag.class;
case TYPE_LIST:
return ListTag.class;
case TYPE_COMPOUND:
return CompoundTag.class;
case TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Unknown tag type ID of " + id);
}
}
}

View File

@ -1,185 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong> streams, and produces an object graph of
* subclasses of the {@code Tag} object. The NBT format was created by Markus Persson, and the specification
* may be found at @linktourl http://www.minecraft.net/docs/NBT.txt"> http://www.minecraft.net/docs/NBT.txt.
*/
public final class NBTInputStream implements Closeable {
private final DataInputStream is;
private int count;
/**
* Creates a new {@code NBTInputStream}, which will source its data from the specified input stream.
*
* @param is the input stream
* @throws IOException if an I/O error occurs
*/
public NBTInputStream(InputStream is) {
this.is = new DataInputStream(is);
}
/**
* Reads an NBT tag from the stream.
*
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
public Tag readTag() throws IOException {
return readTag(0, Integer.MAX_VALUE);
}
/**
* Reads an NBT tag from the stream.
*
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
public Tag readTag(int maxDepth) throws IOException {
return readTag(0, maxDepth);
}
/**
* Reads an NBT from the stream.
*
* @param depth the depth of this tag
* @return The tag that was read.
* @throws IOException if an I/O error occurs.
*/
private Tag readTag(int depth, int maxDepth) throws IOException {
if (this.count++ > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
}
int type = this.is.readByte() & 0xFF;
String name;
if (type != NBTConstants.TYPE_END) {
int nameLength = this.is.readShort() & 0xFFFF;
byte[] nameBytes = new byte[nameLength];
this.is.readFully(nameBytes);
name = new String(nameBytes, NBTConstants.CHARSET);
} else {
name = "";
}
return readTagPayload(type, name, depth, maxDepth);
}
/**
* Reads the payload of a tag, given the name and type.
*
* @param type the type
* @param name the name
* @param depth the depth
* @return the tag
* @throws IOException if an I/O error occurs.
*/
private Tag readTagPayload(int type, String name, int depth, int maxDepth) throws IOException {
if (this.count++ > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
}
this.count++;
switch (type) {
case NBTConstants.TYPE_END:
if (depth == 0) {
throw new IOException(
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
} else {
return new EndTag();
}
case NBTConstants.TYPE_BYTE:
return new ByteTag(name, this.is.readByte());
case NBTConstants.TYPE_SHORT:
return new ShortTag(name, this.is.readShort());
case NBTConstants.TYPE_INT:
return new IntTag(name, this.is.readInt());
case NBTConstants.TYPE_LONG:
return new LongTag(name, this.is.readLong());
case NBTConstants.TYPE_FLOAT:
return new FloatTag(name, this.is.readFloat());
case NBTConstants.TYPE_DOUBLE:
return new DoubleTag(name, this.is.readDouble());
case NBTConstants.TYPE_BYTE_ARRAY:
int length = this.is.readInt();
// Max depth
if ((this.count += length) > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
//
}
byte[] bytes = new byte[length];
this.is.readFully(bytes);
return new ByteArrayTag(name, bytes);
case NBTConstants.TYPE_STRING:
length = this.is.readShort();
// Max depth
if ((this.count += length) > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
//
}
bytes = new byte[length];
this.is.readFully(bytes);
return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
case NBTConstants.TYPE_LIST:
int childType = this.is.readByte();
length = this.is.readInt();
// Max depth
if ((this.count += length) > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
//
}
List<Tag> tagList = new ArrayList<Tag>();
for (int i = 0; i < length; ++i) {
Tag tag = readTagPayload(childType, "", depth + 1, maxDepth);
if (tag instanceof EndTag) {
throw new IOException("TAG_End not permitted in a list.");
}
tagList.add(tag);
}
return new ListTag(name, NBTUtils.getTypeClass(childType), tagList);
case NBTConstants.TYPE_COMPOUND:
Map<String, Tag> tagMap = new HashMap<String, Tag>();
while (true) {
Tag tag = readTag(depth + 1, maxDepth);
if (tag instanceof EndTag) {
break;
} else {
tagMap.put(tag.getName(), tag);
}
}
return new CompoundTag(name, tagMap);
case NBTConstants.TYPE_INT_ARRAY:
length = this.is.readInt();
// Max depth
if ((this.count += length) > maxDepth) {
throw new IOException("Exceeds max depth: " + this.count);
}
//
int[] data = new int[length];
for (int i = 0; i < length; i++) {
data[i] = this.is.readInt();
}
return new IntArrayTag(name, data);
default:
throw new IOException("Invalid tag type: " + type + '.');
}
}
@Override public void close() throws IOException {
this.is.close();
}
}

View File

@ -1,249 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* {@code Tag} objects to an underlying {@code OutputStream}.
* <p>
* <p> The NBT format was created by Markus Persson, and the specification may
* be found at @linktourl http://www.minecraft.net/docs/NBT.txt
* </p>
*
* @author Graham Edgecombe
*/
public final class NBTOutputStream implements Closeable {
/**
* The output stream.
*/
private final DataOutputStream os;
/**
* Creates a new {@code NBTOutputStream}, which will write data to the
* specified underlying output stream.
*
* @param os The output stream.
* @throws IOException if an I/O error occurs.
*/
public NBTOutputStream(OutputStream os) {
this.os = new DataOutputStream(os);
}
/**
* Writes a tag.
*
* @param tag The tag to write.
* @throws IOException if an I/O error occurs.
*/
public void writeTag(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
String name = tag.getName();
byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
this.os.writeByte(type);
this.os.writeShort(nameBytes.length);
this.os.write(nameBytes);
if (type == NBTConstants.TYPE_END) {
throw new IOException("Named TAG_End not permitted.");
}
writeTagPayload(tag);
}
/**
* Writes tag payload.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeTagPayload(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
switch (type) {
case NBTConstants.TYPE_END:
writeEndTagPayload((EndTag) tag);
break;
case NBTConstants.TYPE_BYTE:
writeByteTagPayload((ByteTag) tag);
break;
case NBTConstants.TYPE_SHORT:
writeShortTagPayload((ShortTag) tag);
break;
case NBTConstants.TYPE_INT:
writeIntTagPayload((IntTag) tag);
break;
case NBTConstants.TYPE_LONG:
writeLongTagPayload((LongTag) tag);
break;
case NBTConstants.TYPE_FLOAT:
writeFloatTagPayload((FloatTag) tag);
break;
case NBTConstants.TYPE_DOUBLE:
writeDoubleTagPayload((DoubleTag) tag);
break;
case NBTConstants.TYPE_BYTE_ARRAY:
writeByteArrayTagPayload((ByteArrayTag) tag);
break;
case NBTConstants.TYPE_STRING:
writeStringTagPayload((StringTag) tag);
break;
case NBTConstants.TYPE_LIST:
writeListTagPayload((ListTag) tag);
break;
case NBTConstants.TYPE_COMPOUND:
writeCompoundTagPayload((CompoundTag) tag);
break;
case NBTConstants.TYPE_INT_ARRAY:
writeIntArrayTagPayload((IntArrayTag) tag);
break;
default:
throw new IOException("Invalid tag type: " + type + '.');
}
}
/**
* Writes a {@code TAG_Byte} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeByteTagPayload(ByteTag tag) throws IOException {
this.os.writeByte(tag.getValue());
}
/**
* Writes a {@code TAG_Byte_Array} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
byte[] bytes = tag.getValue();
this.os.writeInt(bytes.length);
this.os.write(bytes);
}
/**
* Writes a {@code TAG_Compound} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeCompoundTagPayload(CompoundTag tag) throws IOException {
for (Tag childTag : tag.getValue().values()) {
writeTag(childTag);
}
this.os.writeByte((byte) 0); // end tag - better way?
}
/**
* Writes a {@code TAG_List} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeListTagPayload(ListTag tag) throws IOException {
Class<? extends Tag> clazz = tag.getType();
List<Tag> tags = tag.getValue();
int size = tags.size();
this.os.writeByte(NBTUtils.getTypeCode(clazz));
this.os.writeInt(size);
for (Tag tag1 : tags) {
writeTagPayload(tag1);
}
}
/**
* Writes a {@code TAG_String} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeStringTagPayload(StringTag tag) throws IOException {
byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
this.os.writeShort(bytes.length);
this.os.write(bytes);
}
/**
* Writes a {@code TAG_Double} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
this.os.writeDouble(tag.getValue());
}
/**
* Writes a {@code TAG_Float} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeFloatTagPayload(FloatTag tag) throws IOException {
this.os.writeFloat(tag.getValue());
}
/**
* Writes a {@code TAG_Long} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeLongTagPayload(LongTag tag) throws IOException {
this.os.writeLong(tag.getValue());
}
/**
* Writes a {@code TAG_Int} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeIntTagPayload(IntTag tag) throws IOException {
this.os.writeInt(tag.getValue());
}
/**
* Writes a {@code TAG_Short} tag.
*
* @param tag The tag.
* @throws IOException if an I/O error occurs.
*/
private void writeShortTagPayload(ShortTag tag) throws IOException {
this.os.writeShort(tag.getValue());
}
/**
* Writes a {@code TAG_Empty} tag.
*
* @param tag The tag.
*/
private void writeEndTagPayload(EndTag tag) {
/* empty */
}
private void writeIntArrayTagPayload(IntArrayTag tag) throws IOException {
int[] data = tag.getValue();
this.os.writeInt(data.length);
for (int element : data) {
this.os.writeInt(element);
}
}
@Override public void close() throws IOException {
this.os.close();
}
/**
* Flush output.
*
* @throws IOException
*/
public void flush() throws IOException {
this.os.flush();
}
}

View File

@ -1,148 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import java.util.Map;
/**
* A class which contains NBT-related utility methods.
*/
public final class NBTUtils {
/**
* Default private constructor.
*/
private NBTUtils() {
}
/**
* Gets the type name of a tag.
*
* @param clazz the tag class
* @return The type name.
*/
public static String getTypeName(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte";
} else if (clazz.equals(CompoundTag.class)) {
return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double";
} else if (clazz.equals(EndTag.class)) {
return "TAG_End";
} else if (clazz.equals(FloatTag.class)) {
return "TAG_Float";
} else if (clazz.equals(IntTag.class)) {
return "TAG_Int";
} else if (clazz.equals(ListTag.class)) {
return "TAG_List";
} else if (clazz.equals(LongTag.class)) {
return "TAG_Long";
} else if (clazz.equals(ShortTag.class)) {
return "TAG_Short";
} else if (clazz.equals(StringTag.class)) {
return "TAG_String";
} else if (clazz.equals(IntArrayTag.class)) {
return "TAG_Int_Array";
} else {
throw new IllegalArgumentException("Invalid tag class (" + clazz.getName() + ").");
}
}
/**
* Gets the type code of a tag class.
*
* @param clazz the tag class
* @return The type code.
* @throws IllegalArgumentException if the tag class is invalid.
*/
public static int getTypeCode(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE;
} else if (clazz.equals(CompoundTag.class)) {
return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE;
} else if (clazz.equals(EndTag.class)) {
return NBTConstants.TYPE_END;
} else if (clazz.equals(FloatTag.class)) {
return NBTConstants.TYPE_FLOAT;
} else if (clazz.equals(IntTag.class)) {
return NBTConstants.TYPE_INT;
} else if (clazz.equals(ListTag.class)) {
return NBTConstants.TYPE_LIST;
} else if (clazz.equals(LongTag.class)) {
return NBTConstants.TYPE_LONG;
} else if (clazz.equals(ShortTag.class)) {
return NBTConstants.TYPE_SHORT;
} else if (clazz.equals(StringTag.class)) {
return NBTConstants.TYPE_STRING;
} else if (clazz.equals(IntArrayTag.class)) {
return NBTConstants.TYPE_INT_ARRAY;
} else {
throw new IllegalArgumentException("Invalid tag class (" + clazz.getName() + ").");
}
}
/**
* Gets the class of a type of tag.
*
* @param type the type
* @return The class.
* @throws IllegalArgumentException if the tag type is invalid.
*/
public static Class<? extends Tag> getTypeClass(int type) {
switch (type) {
case NBTConstants.TYPE_END:
return EndTag.class;
case NBTConstants.TYPE_BYTE:
return ByteTag.class;
case NBTConstants.TYPE_SHORT:
return ShortTag.class;
case NBTConstants.TYPE_INT:
return IntTag.class;
case NBTConstants.TYPE_LONG:
return LongTag.class;
case NBTConstants.TYPE_FLOAT:
return FloatTag.class;
case NBTConstants.TYPE_DOUBLE:
return DoubleTag.class;
case NBTConstants.TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case NBTConstants.TYPE_STRING:
return StringTag.class;
case NBTConstants.TYPE_LIST:
return ListTag.class;
case NBTConstants.TYPE_COMPOUND:
return CompoundTag.class;
case NBTConstants.TYPE_INT_ARRAY:
return IntArrayTag.class;
default:
throw new IllegalArgumentException("Invalid tag type : " + type + ".");
}
}
/**
* Get child tag of a NBT structure.
*
* @param items the map to read from
* @param key the key to look for
* @param expected the expected NBT class type
* @param <T>
* @return child tag
*/
public static <T extends Tag> T getChildTag(Map<String, Tag> items, String key,
Class<T> expected) throws IllegalArgumentException {
if (!items.containsKey(key)) {
throw new IllegalArgumentException("Missing a \"" + key + "\" tag");
}
Tag tag = items.get(key);
if (!expected.isInstance(tag)) {
throw new IllegalArgumentException(
key + " tag is not of tag type " + expected.getName());
}
return expected.cast(tag);
}
}

View File

@ -1,42 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* The {@code TAG_Short} tag.
*/
public final class ShortTag extends Tag {
private final short value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public ShortTag(short value) {
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public ShortTag(String name, short value) {
super(name);
this.value = value;
}
@Override public Short getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_Short" + append + ": " + this.value;
}
}

View File

@ -1,46 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The {@code TAG_String} tag.
*/
public final class StringTag extends Tag {
private final String value;
/**
* Creates the tag with an empty name.
*
* @param value the value of the tag
*/
public StringTag(String value) {
checkNotNull(value);
this.value = value;
}
/**
* Creates the tag.
*
* @param name the name of the tag
* @param value the value of the tag
*/
public StringTag(String name, String value) {
super(name);
checkNotNull(value);
this.value = value;
}
@Override public String getValue() {
return this.value;
}
@Override public String toString() {
String name = getName();
String append = "";
if (name != null && !name.isEmpty()) {
append = "(\"" + getName() + "\")";
}
return "TAG_String" + append + ": " + this.value;
}
}

View File

@ -1,44 +0,0 @@
package com.github.intellectualsites.plotsquared.jnbt;
/**
* Represents a NBT tag.
*/
public abstract class Tag {
private final String name;
/**
* Create a new tag with an empty name.
*/
Tag() {
this("");
}
/**
* Creates the tag with the specified name.
*
* @param name the name
*/
Tag(String name) {
if (name == null) {
name = "";
}
this.name = name;
}
/**
* Gets the name of this tag.
*
* @return the name of this tag
*/
public final String getName() {
return this.name;
}
/**
* Gets the value of this tag.
*
* @return the value
*/
public abstract Object getValue();
}

View File

@ -1939,7 +1939,7 @@ import java.util.zip.ZipInputStream;
* *
* @param alias to search plots * @param alias to search plots
* @param worldname to filter alias to a specific world [optional] null means all worlds * @param worldname to filter alias to a specific world [optional] null means all worlds
* @return Set<{ @ link Plot }> empty if nothing found * @return Set<{ @ link Plot }> empty if nothing found
*/ */
public Set<Plot> getPlotsByAlias(@Nullable final String alias, public Set<Plot> getPlotsByAlias(@Nullable final String alias,
@NonNull final String worldname) { @NonNull final String worldname) {

View File

@ -1,7 +1,6 @@
package com.github.intellectualsites.plotsquared.plot.commands; package com.github.intellectualsites.plotsquared.plot.commands;
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
@ -10,6 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
import com.github.intellectualsites.plotsquared.plot.util.*; import com.github.intellectualsites.plotsquared.plot.util.*;
import com.sk89q.jnbt.CompoundTag;
import java.net.URL; import java.net.URL;

View File

@ -5,6 +5,7 @@ import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.object.*; 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.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.Permissions; import com.github.intellectualsites.plotsquared.plot.util.Permissions;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
@ -70,8 +71,7 @@ public class Load extends SubCommand {
MainUtil.sendMessage(player, C.GENERATING_COMPONENT); MainUtil.sendMessage(player, C.GENERATING_COMPONENT);
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(new Runnable() {
@Override public void run() { @Override public void run() {
SchematicHandler.Schematic schematic = Schematic schematic = SchematicHandler.manager.getSchematic(url);
SchematicHandler.manager.getSchematic(url);
if (schematic == null) { if (schematic == null) {
plot.removeRunning(); plot.removeRunning();
sendMessage(player, C.SCHEMATIC_INVALID, sendMessage(player, C.SCHEMATIC_INVALID,

View File

@ -1,7 +1,6 @@
package com.github.intellectualsites.plotsquared.plot.commands; package com.github.intellectualsites.plotsquared.plot.commands;
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
@ -9,6 +8,7 @@ import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.Permissions; import com.github.intellectualsites.plotsquared.plot.util.Permissions;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;

View File

@ -5,8 +5,8 @@ import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.schematic.Schematic;
import com.github.intellectualsites.plotsquared.plot.util.*; import com.github.intellectualsites.plotsquared.plot.util.*;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler.Schematic;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
@ -57,7 +57,7 @@ public class SchematicCmd extends SubCommand {
this.running = true; this.running = true;
TaskManager.runTaskAsync(new Runnable() { TaskManager.runTaskAsync(new Runnable() {
@Override public void run() { @Override public void run() {
Schematic schematic; Schematic schematic = null;
if (location.startsWith("url:")) { if (location.startsWith("url:")) {
try { try {
UUID uuid = UUID.fromString(location.substring(4)); UUID uuid = UUID.fromString(location.substring(4));
@ -72,7 +72,11 @@ public class SchematicCmd extends SubCommand {
return; return;
} }
} else { } else {
schematic = SchematicHandler.manager.getSchematic(location); try {
schematic = SchematicHandler.manager.getSchematic(location);
} catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
}
} }
if (schematic == null) { if (schematic == null) {
SchematicCmd.this.running = false; SchematicCmd.this.running = false;
@ -212,9 +216,11 @@ public class SchematicCmd extends SubCommand {
MainUtil.sendMessage(player, C.NO_PERMISSION, C.PERMISSION_SCHEMATIC_LIST); MainUtil.sendMessage(player, C.NO_PERMISSION, C.PERMISSION_SCHEMATIC_LIST);
return false; return false;
} }
final String string = StringMan.join(SchematicHandler.manager.getShematicNames(), "$2, $1"); final String string =
StringMan.join(SchematicHandler.manager.getShematicNames(), "$2, $1");
C.SCHEMATIC_LIST.send(player, string); C.SCHEMATIC_LIST.send(player, string);
} break; }
break;
default: default:
sendMessage(player, C.SCHEMATIC_MISSING_ARG); sendMessage(player, C.SCHEMATIC_MISSING_ARG);
break; break;

View File

@ -31,8 +31,7 @@ public enum C {
"static.flags"), FLAG_PLAYER_INTERACT("player-interact", "static.flags"), FLAG_PLAYER_INTERACT("player-interact",
"static.flags"), FLAG_TAMED_INTERACT("tamed-interact", "static.flags"), FLAG_TAMED_INTERACT("tamed-interact",
"static.flags"), FLAG_DISABLE_PHYSICS("disable-physics", "static.flags"), FLAG_MOB_PLACE( "static.flags"), FLAG_DISABLE_PHYSICS("disable-physics", "static.flags"), FLAG_MOB_PLACE(
"mob-place", "static.flags"), "mob-place", "static.flags"), /*
/*
* Static permission * Static permission
*/ */
PERMISSION_STAR("*", "static.permissions"), PERMISSION_ADMIN("plots.admin", PERMISSION_STAR("*", "static.permissions"), PERMISSION_ADMIN("plots.admin",
@ -833,7 +832,9 @@ public enum C {
HELP_INFO_ITEM("$1/plot help %category% $3- $2%category_desc%", "Help"), HELP_ITEM( HELP_INFO_ITEM("$1/plot help %category% $3- $2%category_desc%", "Help"), HELP_ITEM(
"$1%usage% [%alias%]&- $3- $2%desc%&-", "Help"), "$1%usage% [%alias%]&- $3- $2%desc%&-", "Help"),
BUCKET_ENTRIES_IGNORED("$2Total bucket values add up to 1 or more. Blocks without a spcified chance will be ignored", "Generator_Bucket"), BUCKET_ENTRIES_IGNORED(
"$2Total bucket values add up to 1 or more. Blocks without a spcified chance will be ignored",
"Generator_Bucket"),
/* /*
* Direction * Direction
@ -1047,4 +1048,5 @@ public enum C {
} else { } else {
caller.sendMessage(msg); caller.sendMessage(msg);
} }
}} }
}

View File

@ -1,6 +1,5 @@
package com.github.intellectualsites.plotsquared.plot.generator; package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.MathMan;
@ -8,6 +7,7 @@ import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
import com.sk89q.jnbt.CompoundTag;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -21,7 +21,7 @@ public class HybridGen extends IndependentPlotGenerator {
private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX, private void placeSchem(HybridPlotWorld world, ScopedLocalBlockQueue result, short relativeX,
short relativeZ, int x, int z) { short relativeZ, int x, int z) {
int minY = Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); int minY = Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT);
char[] blocks = world.G_SCH.get(MathMan.pair(relativeX, relativeZ)); String[] blocks = world.G_SCH.get(MathMan.pair(relativeX, relativeZ));
if (blocks != null) { if (blocks != null) {
for (int y = 0; y < blocks.length; y++) { for (int y = 0; y < blocks.length; y++) {
PlotBlock block = PlotBlock.get(blocks[y]); PlotBlock block = PlotBlock.get(blocks[y]);
@ -92,7 +92,7 @@ public class HybridGen extends IndependentPlotGenerator {
} }
} }
// generation // generation
HashMap<Integer, char[]> sch = hpw.G_SCH; HashMap<Integer, String[]> sch = hpw.G_SCH;
for (short x = 0; x < 16; x++) { for (short x = 0; x < 16; x++) {
if (gx[x]) { if (gx[x]) {
for (short z = 0; z < 16; z++) { for (short z = 0; z < 16; z++) {
@ -149,11 +149,9 @@ public class HybridGen extends IndependentPlotGenerator {
} else { } else {
// plot // plot
for (int y = 1; y < hpw.PLOT_HEIGHT; y++) { for (int y = 1; y < hpw.PLOT_HEIGHT; y++) {
result.setBlock(x, y, z, result.setBlock(x, y, z, hpw.MAIN_BLOCK.getBlock());
hpw.MAIN_BLOCK.getBlock());
} }
result.setBlock(x, hpw.PLOT_HEIGHT, z, result.setBlock(x, hpw.PLOT_HEIGHT, z, hpw.TOP_BLOCK.getBlock());
hpw.TOP_BLOCK.getBlock());
if (hpw.PLOT_SCHEMATIC) { if (hpw.PLOT_SCHEMATIC) {
placeSchem(hpw, result, rx[x], rz[z], x, z); placeSchem(hpw, result, rx[x], rz[z], x, z);
} }

View File

@ -89,7 +89,7 @@ public class HybridPlotManager extends ClassicPlotManager {
if (absZ < 0) { if (absZ < 0) {
absZ += size; absZ += size;
} }
char[] blocks = hpw.G_SCH.get(MathMan.pair(absX, absZ)); String[] blocks = hpw.G_SCH.get(MathMan.pair(absX, absZ));
if (blocks != null) { if (blocks != null) {
for (int y = 0; y < blocks.length; y++) { for (int y = 0; y < blocks.length; y++) {
PlotBlock block = PlotBlock.get(blocks[y]); PlotBlock block = PlotBlock.get(blocks[y]);

View File

@ -1,27 +1,37 @@
package com.github.intellectualsites.plotsquared.plot.generator; package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection; import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.jnbt.Tag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.object.*; 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.schematic.Schematic;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.internal.helper.MCDirections;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
public class HybridPlotWorld extends ClassicPlotWorld { public class HybridPlotWorld extends ClassicPlotWorld {
private static AffineTransform transform = new AffineTransform().rotateY(-90);
public boolean ROAD_SCHEMATIC_ENABLED; public boolean ROAD_SCHEMATIC_ENABLED;
public boolean PLOT_SCHEMATIC = false; public boolean PLOT_SCHEMATIC = false;
public short PATH_WIDTH_LOWER; public short PATH_WIDTH_LOWER;
public short PATH_WIDTH_UPPER; public short PATH_WIDTH_UPPER;
public HashMap<Integer, char[]> G_SCH; public HashMap<Integer, String[]> G_SCH;
public HashMap<Integer, HashMap<Integer, CompoundTag>> G_SCH_STATE; public HashMap<Integer, HashMap<Integer, CompoundTag>> G_SCH_STATE;
private Location SIGN_LOCATION; private Location SIGN_LOCATION;
@ -46,98 +56,34 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// FIXME depends on block ids // FIXME depends on block ids
// Possibly make abstract? // Possibly make abstract?
public static byte rotate(short id, byte data) { public static BaseBlock rotate(BaseBlock id) {
switch (id) { CompoundTag tag = id.toBaseBlock().getNbtData();
case 162:
case 17:
if (data >= 4 && data < 12) {
if (data >= 8) {
return (byte) (data - 4);
}
return (byte) (data + 4);
}
return data;
case 26: // bed
case 86: // pumpkin
case 91:
case 183: // fence gate
case 184:
case 185:
case 186:
case 187:
case 107:
data = wrap2(data, 0);
data = wrap2(data, 2);
data = wrap2(data, 4);
data = wrap2(data, 6);
return data;
case 53:
case 67:
case 108:
case 109:
case 114:
case 128:
case 134:
case 135:
case 136:
case 156:
case 163:
case 164:
case 180:
case 64:
case 71:
case 193:
case 194:
case 195:
case 196:
case 197:
case 93:
case 94:
case 131:
case 145:
case 149:
case 150:
case 96:
case 167:
data = wrap(data, 0);
data = wrap(data, 4);
data = wrap(data, 8);
data = wrap(data, 12);
return data;
case 28:
case 66:
case 157:
case 27:
data = wrap2(data, 0);
data = wrap2(data, 3);
if (data == 2) {
data = 5;
} else if (data == 5) {
data = 2;
}
return data;
case 23: if (tag != null) {
case 29: // Handle blocks which store their rotation in NBT
case 33: if (tag.containsKey("Rot")) {
case 158: int rot = tag.asInt("Rot");
case 54:
case 130: Direction direction = MCDirections.fromRotation(rot);
case 146:
case 61: if (direction != null) {
case 62: Vector3 vector = transform.apply(direction.toVector())
case 65: .subtract(transform.apply(Vector3.ZERO)).normalize();
case 68: Direction newDirection = Direction.findClosest(vector,
case 144: Direction.Flag.CARDINAL | Direction.Flag.ORDINAL
data = wrap(data, 2); | Direction.Flag.SECONDARY_ORDINAL);
return data;
case 143: if (newDirection != null) {
case 77: CompoundTagBuilder builder = tag.createBuilder();
data = wrap(data, 1);
return data; builder.putByte("Rot", (byte) MCDirections.toRotation(newDirection));
default:
return data; return id.toBaseBlock(builder.build());
}
}
}
} }
return id;
} }
public Location getSignLocation(Plot plot) { public Location getSignLocation(Plot plot) {
@ -184,7 +130,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
return ((SquarePlotWorld) plotArea).PLOT_WIDTH == this.PLOT_WIDTH; return ((SquarePlotWorld) plotArea).PLOT_WIDTH == this.PLOT_WIDTH;
} }
public void setupSchematics() { public void setupSchematics() throws SchematicHandler.UnsupportedFormatException {
this.G_SCH = new HashMap<>(); this.G_SCH = new HashMap<>();
File schematic1File = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), File schematic1File = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
"schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/sideroad.schematic"); "schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/sideroad.schematic");
@ -192,19 +138,15 @@ public class HybridPlotWorld extends ClassicPlotWorld {
"schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/intersection.schematic"); "schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/intersection.schematic");
File schem3File = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), File schem3File = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
"schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/plot.schematic"); "schematics/GEN_ROAD_SCHEMATIC/" + this.worldname + "/plot.schematic");
SchematicHandler.Schematic schematic1 = Schematic schematic1 = SchematicHandler.manager.getSchematic(schematic1File);
SchematicHandler.manager.getSchematic(schematic1File); Schematic schematic2 = SchematicHandler.manager.getSchematic(schematic2File);
SchematicHandler.Schematic schematic2 = Schematic schematic3 = SchematicHandler.manager.getSchematic(schem3File);
SchematicHandler.manager.getSchematic(schematic2File);
SchematicHandler.Schematic schematic3 = SchematicHandler.manager.getSchematic(schem3File);
int shift = this.ROAD_WIDTH / 2; int shift = this.ROAD_WIDTH / 2;
int oddshift = (this.ROAD_WIDTH & 1) == 0 ? 0 : 1; int oddshift = (this.ROAD_WIDTH & 1) == 0 ? 0 : 1;
int minY = Math.min(PLOT_HEIGHT, ROAD_HEIGHT); int minY = Math.min(PLOT_HEIGHT, ROAD_HEIGHT);
if (schematic3 != null) { if (schematic3 != null) {
this.PLOT_SCHEMATIC = true; this.PLOT_SCHEMATIC = true;
short[] ids = schematic3.getIds(); BlockVector3 d3 = schematic3.getClipboard().getDimensions();
byte[] datas = schematic3.getDatas();
SchematicHandler.Dimension d3 = schematic3.getSchematicDimension();
short w3 = (short) d3.getX(); short w3 = (short) d3.getX();
short l3 = (short) d3.getZ(); short l3 = (short) d3.getZ();
short h3 = (short) d3.getY(); short h3 = (short) d3.getY();
@ -225,51 +167,52 @@ public class HybridPlotWorld extends ClassicPlotWorld {
} }
int startY = minY - PLOT_HEIGHT; 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(); // for (short x = 0; x < w3; x++) {
Map<String, Tag> map = ReflectionUtils.getMap(tag.getValue()); // for (short z = 0; z < l3; z++) {
for (int i = 1; i <= 4; i++) { // for (short y = 0; y < h3; y++) {
String ln = tag.getString("Line" + i); // int index = (y * w3 * l3) + (z * w3) + x;
if (ln == null || ln.length() > 11) // short id = ids[index];
continue outer; // byte data = datas[index];
} // if (id != 0) {
SIGN_LOCATION = // addOverlayBlock((short) (x + shift + oddshift + centerShiftX),
new Location(worldname, loc.x + centerShiftX, this.PLOT_HEIGHT + loc.y, // (short) (y + startY), (short) (z + shift + oddshift + centerShiftZ),
loc.z + centerShiftZ); // id, data, false, h3);
ALLOW_SIGNS = true; // }
continue outer; // }
} // }
} // }
// 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) { if (schematic1 == null || schematic2 == null || this.ROAD_WIDTH == 0) {
PlotSquared.debug(C.PREFIX + "&3 - schematic: &7false"); PlotSquared.debug(C.PREFIX + "&3 - schematic: &7false");
@ -279,17 +222,14 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// Do not populate road if using schematic population // Do not populate road if using schematic population
// TODO: What? this.ROAD_BLOCK = BlockBucket.empty(); // PlotBlock.getEmptyData(this.ROAD_BLOCK); // PlotBlock.get(this.ROAD_BLOCK.id, (byte) 0); // TODO: What? this.ROAD_BLOCK = BlockBucket.empty(); // PlotBlock.getEmptyData(this.ROAD_BLOCK); // PlotBlock.get(this.ROAD_BLOCK.id, (byte) 0);
short[] ids1 = schematic1.getIds(); BlockArrayClipboard blockArrayClipboard1 = schematic1.getClipboard();
byte[] datas1 = schematic1.getDatas(); BlockArrayClipboard blockArrayClipboard2 = schematic2.getClipboard();
short[] ids2 = schematic2.getIds(); BlockVector3 d1 = blockArrayClipboard1.getDimensions();
byte[] datas2 = schematic2.getDatas();
SchematicHandler.Dimension d1 = schematic1.getSchematicDimension();
short w1 = (short) d1.getX(); short w1 = (short) d1.getX();
short l1 = (short) d1.getZ(); short l1 = (short) d1.getZ();
short h1 = (short) d1.getY(); short h1 = (short) d1.getY();
SchematicHandler.Dimension d2 = schematic2.getSchematicDimension(); BlockVector3 d2 = blockArrayClipboard2.getDimensions();
short w2 = (short) d2.getX(); short w2 = (short) d2.getX();
short l2 = (short) d2.getZ(); short l2 = (short) d2.getZ();
short h2 = (short) d2.getY(); short h2 = (short) d2.getY();
@ -297,14 +237,13 @@ public class HybridPlotWorld extends ClassicPlotWorld {
for (short x = 0; x < w1; x++) { for (short x = 0; x < w1; x++) {
for (short z = 0; z < l1; z++) { for (short z = 0; z < l1; z++) {
for (short y = 0; y < h1; y++) { for (short y = 0; y < h1; y++) {
int index = (y * w1 * l1) + (z * w1) + x; BaseBlock id =
short id = ids1[index]; blockArrayClipboard1.getFullBlock(BlockVector3.at(x, y, z)).toBaseBlock();
byte data = datas1[index]; if (!id.getBlockType().getId().toLowerCase().contains("air")) {
if (id != 0) {
addOverlayBlock((short) (x - shift), (short) (y + startY), addOverlayBlock((short) (x - shift), (short) (y + startY),
(short) (z + shift + oddshift), id, data, false, h1); (short) (z + shift + oddshift), id, false, h1);
addOverlayBlock((short) (z + shift + oddshift), (short) (y + startY), addOverlayBlock((short) (z + shift + oddshift), (short) (y + startY),
(short) (x - shift), id, data, true, h1); (short) (x - shift), id, true, h1);
} }
} }
} }
@ -312,19 +251,17 @@ public class HybridPlotWorld extends ClassicPlotWorld {
for (short x = 0; x < w2; x++) { for (short x = 0; x < w2; x++) {
for (short z = 0; z < l2; z++) { for (short z = 0; z < l2; z++) {
for (short y = 0; y < h2; y++) { for (short y = 0; y < h2; y++) {
int index = (y * w2 * l2) + (z * w2) + x; BaseBlock id = blockArrayClipboard2.getFullBlock(BlockVector3.at(x, y, z));
short id = ids2[index]; if (!id.getBlockType().getId().toLowerCase().contains("air")) {
byte data = datas2[index];
if (id != 0) {
addOverlayBlock((short) (x - shift), (short) (y + startY), addOverlayBlock((short) (x - shift), (short) (y + startY),
(short) (z - shift), id, data, false, h2); (short) (z - shift), id, false, h2);
} }
} }
} }
} }
} }
public void addOverlayBlock(short x, short y, short z, short id, byte data, boolean rotate, public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate,
int height) { int height) {
if (z < 0) { if (z < 0) {
z += this.SIZE; z += this.SIZE;
@ -337,20 +274,14 @@ public class HybridPlotWorld extends ClassicPlotWorld {
x -= this.SIZE; x -= this.SIZE;
} }
if (rotate) { if (rotate) {
byte newData = rotate(id, data); id = rotate(id);
if (data != 0 || newData != 0) {
data = newData;
}
} }
int pair = MathMan.pair(x, z); int pair = MathMan.pair(x, z);
char[] existing = this.G_SCH.get(pair); String[] existing = this.G_SCH.get(pair);
if (existing == null) { if (existing == null) {
existing = new char[height]; existing = new String[height];
this.G_SCH.put(pair, existing); this.G_SCH.put(pair, existing);
} }
if (id == 0) { existing[y] = id.getBlockType().getId();
data = 1;
}
existing[y] = (char) ((id << 4) + data);
} }
} }

View File

@ -1,6 +1,5 @@
package com.github.intellectualsites.plotsquared.plot.generator; package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.flag.FlagManager; import com.github.intellectualsites.plotsquared.plot.flag.FlagManager;
@ -10,6 +9,7 @@ import com.github.intellectualsites.plotsquared.plot.util.*;
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.expiry.PlotAnalysis; import com.github.intellectualsites.plotsquared.plot.util.expiry.PlotAnalysis;
import com.sk89q.jnbt.CompoundTag;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
@ -257,7 +257,11 @@ public abstract class HybridUtils {
@Override public void run(CompoundTag value) { @Override public void run(CompoundTag value) {
SchematicHandler.manager.save(value, dir + "intersection.schematic"); SchematicHandler.manager.save(value, dir + "intersection.schematic");
plotworld.ROAD_SCHEMATIC_ENABLED = true; plotworld.ROAD_SCHEMATIC_ENABLED = true;
plotworld.setupSchematics(); try {
plotworld.setupSchematics();
} catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
}
} }
}); });
} }
@ -348,7 +352,7 @@ public abstract class HybridUtils {
condition = !gx || !gz || !lx || !lz; condition = !gx || !gz || !lx || !lz;
} }
if (condition) { if (condition) {
char[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); String[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ));
int minY = Math.min(plotWorld.PLOT_HEIGHT, plotWorld.ROAD_HEIGHT); int minY = Math.min(plotWorld.PLOT_HEIGHT, plotWorld.ROAD_HEIGHT);
if (blocks != null) { if (blocks != null) {
for (int y = 0; y < blocks.length; y++) { for (int y = 0; y < blocks.length; y++) {

View File

@ -4,17 +4,19 @@ import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent; import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashSet; import java.util.HashSet;
@ -44,52 +46,59 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
this.parent = parent; this.parent = parent;
} }
@Override public BaseBlock getBlock(Vector location) { @Override public BlockState getBlock(BlockVector3 location) {
if (WEManager.maskContains(this.mask, location.getBlockX(), location.getBlockY(), if (WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
location.getBlockZ())) {
return super.getBlock(location); return super.getBlock(location);
} }
return WEManager.AIR; return WEManager.AIR;
} }
@Override public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { @Override public BaseBlock getFullBlock(BlockVector3 location) {
int id = block.getType(); if (WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
return super.getFullBlock(location);
}
return WEManager.AIR.toBaseBlock();
}
@Override public boolean setBlock(BlockVector3 location, BlockStateHolder block)
throws WorldEditException {
String id = block.getBlockType().getId();
switch (id) { switch (id) {
case 54: case "54":
case 130: case "130":
case 142: case "142":
case 27: case "27":
case 137: case "137":
case 52: case "52":
case 154: case "154":
case 84: case "84":
case 25: case "25":
case 144: case "144":
case 138: case "138":
case 176: case "176":
case 177: case "177":
case 63: case "63":
case 68: case "68":
case 323: case "323":
case 117: case "117":
case 116: case "116":
case 28: case "28":
case 66: case "66":
case 157: case "157":
case 61: case "61":
case 62: case "62":
case 140: case "140":
case 146: case "146":
case 149: case "149":
case 150: case "150":
case 158: case "158":
case 23: case "23":
case 123: case "123":
case 124: case "124":
case 29: case "29":
case 33: case "33":
case 151: case "151":
case 178: case "178":
if (this.BSblocked) { if (this.BSblocked) {
return false; return false;
} }
@ -97,11 +106,11 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
if (this.BScount > Settings.Chunk_Processor.MAX_TILES) { if (this.BScount > Settings.Chunk_Processor.MAX_TILES) {
this.BSblocked = true; this.BSblocked = true;
PlotSquared.debug( PlotSquared.debug(
C.PREFIX + "&cdetected unsafe WorldEdit: " + location.getBlockX() + "," C.PREFIX + "&cdetected unsafe WorldEdit: " + location.getX() + ","
+ location.getBlockZ()); + location.getZ());
} }
if (WEManager.maskContains(this.mask, location.getBlockX(), location.getBlockY(), if (WEManager
location.getBlockZ())) { .maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
if (this.count++ > this.max) { if (this.count++ > this.max) {
if (this.parent != null) { if (this.parent != null) {
try { try {
@ -120,11 +129,8 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
} }
break; break;
default: default:
int x = location.getBlockX(); if (WEManager
int y = location.getBlockY(); .maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
int z = location.getBlockZ();
if (WEManager.maskContains(this.mask, location.getBlockX(), location.getBlockY(),
location.getBlockZ())) {
if (this.count++ > this.max) { if (this.count++ > this.max) {
if (this.parent != null) { if (this.parent != null) {
try { try {
@ -139,99 +145,9 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
} }
return false; return false;
} }
switch (id) { super.setBlock(location, block);
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 24:
case 25:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 51:
case 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192: {
super.setBlock(location, block);
}
break;
default: {
super.setBlock(location, block);
}
break;
}
return true;
} }
return true;
} }
return false; return false;
@ -255,8 +171,8 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
return null; return null;
} }
@Override public boolean setBiome(Vector2D position, BaseBiome biome) { @Override public boolean setBiome(BlockVector2 position, BaseBiome biome) {
return WEManager.maskContains(this.mask, position.getBlockX(), position.getBlockZ()) return WEManager.maskContains(this.mask, position.getX(), position.getZ()) && super
&& super.setBiome(position, biome); .setBiome(position, biome);
} }
} }

View File

@ -1,16 +1,18 @@
package com.github.intellectualsites.plotsquared.plot.listener; package com.github.intellectualsites.plotsquared.plot.listener;
import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.HashSet; import java.util.HashSet;
@ -23,9 +25,10 @@ public class WEExtent extends AbstractDelegateExtent {
this.mask = mask; this.mask = mask;
} }
@Override public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { @Override public boolean setBlock(BlockVector3 location, BlockStateHolder block)
return WEManager.maskContains(this.mask, location.getBlockX(), location.getBlockY(), throws WorldEditException {
location.getBlockZ()) && super.setBlock(location, block); return WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())
&& super.setBlock(location, block);
} }
@Override public Entity createEntity(Location location, BaseEntity entity) { @Override public Entity createEntity(Location location, BaseEntity entity) {
@ -36,16 +39,22 @@ public class WEExtent extends AbstractDelegateExtent {
return null; return null;
} }
@Override public boolean setBiome(Vector2D position, BaseBiome biome) { @Override public boolean setBiome(BlockVector2 position, BaseBiome biome) {
return WEManager.maskContains(this.mask, position.getBlockX(), position.getBlockZ()) return WEManager.maskContains(this.mask, position.getX(), position.getZ()) && super
&& super.setBiome(position, biome); .setBiome(position, biome);
} }
@Override public BaseBlock getBlock(Vector location) { @Override public BlockState getBlock(BlockVector3 location) {
if (WEManager.maskContains(this.mask, location.getBlockX(), location.getBlockY(), if (WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
location.getBlockZ())) {
return super.getBlock(location); return super.getBlock(location);
} }
return WEManager.AIR; return WEManager.AIR;
} }
@Override public BaseBlock getFullBlock(BlockVector3 location) {
if (WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
return super.getFullBlock(location);
}
return WEManager.AIR.toBaseBlock();
}
} }

View File

@ -4,14 +4,16 @@ import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.flag.Flags; import com.github.intellectualsites.plotsquared.plot.flag.Flags;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import java.util.HashSet; import java.util.HashSet;
import java.util.UUID; import java.util.UUID;
public class WEManager { public class WEManager {
public static BaseBlock AIR = new BaseBlock(0, 0);
public static BlockState AIR = new BlockType("AIR").getDefaultState();
public static boolean maskContains(HashSet<RegionWrapper> mask, int x, int y, int z) { public static boolean maskContains(HashSet<RegionWrapper> mask, int x, int y, int z) {
for (RegionWrapper region : mask) { for (RegionWrapper region : mask) {
@ -31,6 +33,30 @@ public class WEManager {
return false; return false;
} }
public static boolean maskContains(HashSet<RegionWrapper> mask, double dx, double dy,
double dz) {
int x = Math.toIntExact(Math.round(dx >= 0 ? dx - 0.5 : dx + 0.5));
int y = Math.toIntExact(Math.round(dy - 0.5));
int z = Math.toIntExact(Math.round(dz >= 0 ? dz - 0.5 : dz + 0.5));
for (RegionWrapper region : mask) {
if (region.isIn(x, y, z)) {
return true;
}
}
return false;
}
public static boolean maskContains(HashSet<RegionWrapper> mask, double dx, double dz) {
int x = Math.toIntExact(Math.round(dx >= 0 ? dx - 0.5 : dx + 0.5));
int z = Math.toIntExact(Math.round(dz >= 0 ? dz - 0.5 : dz + 0.5));
for (RegionWrapper region : mask) {
if (region.isIn(x, z)) {
return true;
}
}
return false;
}
public static HashSet<RegionWrapper> getMask(PlotPlayer player) { public static HashSet<RegionWrapper> getMask(PlotPlayer player) {
HashSet<RegionWrapper> regions = new HashSet<>(); HashSet<RegionWrapper> regions = new HashSet<>();
UUID uuid = player.getUUID(); UUID uuid = player.getUUID();

View File

@ -2,15 +2,19 @@ package com.github.intellectualsites.plotsquared.plot.object;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import com.sk89q.worldedit.math.BlockVector3;
import lombok.Getter;
import lombok.Setter;
public class Location implements Cloneable, Comparable<Location> { public class Location implements Cloneable, Comparable<Location> {
private int x; @Getter private int x;
private int y; @Getter private int y;
private int z; @Getter private int z;
private float yaw; @Getter @Setter private float yaw;
private float pitch; @Getter @Setter private float pitch;
private String world; @Getter @Setter private String world;
@Getter private BlockVector3 blockVector3;
public Location(String world, int x, int y, int z, float yaw, float pitch) { public Location(String world, int x, int y, int z, float yaw, float pitch) {
this.world = world; this.world = world;
@ -19,6 +23,7 @@ public class Location implements Cloneable, Comparable<Location> {
this.z = z; this.z = z;
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch; this.pitch = pitch;
this.blockVector3 = BlockVector3.at(x, y, z);
} }
public Location() { public Location() {
@ -29,40 +34,30 @@ public class Location implements Cloneable, Comparable<Location> {
this(world, x, y, z, 0f, 0f); this(world, x, y, z, 0f, 0f);
} }
@Override public Location clone() {
return new Location(this.world, this.x, this.y, this.z, this.yaw, this.pitch);
}
public int getX() {
return this.x;
}
public void setX(int x) { public void setX(int x) {
this.x = x; this.x = x;
} this.blockVector3 = BlockVector3.at(x, y, z);
public int getY() {
return this.y;
} }
public void setY(int y) { public void setY(int y) {
this.y = y; this.y = y;
} this.blockVector3 = BlockVector3.at(x, y, z);
public int getZ() {
return this.z;
} }
public void setZ(int z) { public void setZ(int z) {
this.z = z; this.z = z;
this.blockVector3 = BlockVector3.at(x, y, z);
} }
public String getWorld() { public void setBlockVector3(BlockVector3 blockVector3) {
return this.world; this.blockVector3 = blockVector3;
this.x = blockVector3.getX();
this.y = blockVector3.getY();
this.z = blockVector3.getZ();
} }
public void setWorld(String world) { @Override public Location clone() {
this.world = world; return new Location(this.world, this.x, this.y, this.z, this.yaw, this.pitch);
} }
public PlotArea getPlotArea() { public PlotArea getPlotArea() {
@ -132,22 +127,6 @@ public class Location implements Cloneable, Comparable<Location> {
return new ChunkLoc(this.x >> 4, this.z >> 4); return new ChunkLoc(this.x >> 4, this.z >> 4);
} }
public float getYaw() {
return this.yaw;
}
public void setYaw(float yaw) {
this.yaw = yaw;
}
public float getPitch() {
return this.pitch;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public Location add(int x, int y, int z) { public Location add(int x, int y, int z) {
this.x += x; this.x += x;
this.y += y; this.y += y;

View File

@ -1,6 +1,5 @@
package com.github.intellectualsites.plotsquared.plot.object; package com.github.intellectualsites.plotsquared.plot.object;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.C; import com.github.intellectualsites.plotsquared.plot.config.C;
import com.github.intellectualsites.plotsquared.plot.config.Configuration; import com.github.intellectualsites.plotsquared.plot.config.Configuration;
@ -11,6 +10,7 @@ import com.github.intellectualsites.plotsquared.plot.flag.FlagManager;
import com.github.intellectualsites.plotsquared.plot.flag.Flags; import com.github.intellectualsites.plotsquared.plot.flag.Flags;
import com.github.intellectualsites.plotsquared.plot.generator.SquarePlotWorld; import com.github.intellectualsites.plotsquared.plot.generator.SquarePlotWorld;
import com.github.intellectualsites.plotsquared.plot.listener.PlotListener; import com.github.intellectualsites.plotsquared.plot.listener.PlotListener;
import com.github.intellectualsites.plotsquared.plot.object.schematic.Schematic;
import com.github.intellectualsites.plotsquared.plot.util.*; import com.github.intellectualsites.plotsquared.plot.util.*;
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
@ -19,6 +19,7 @@ import com.github.intellectualsites.plotsquared.plot.util.expiry.PlotAnalysis;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.sk89q.jnbt.CompoundTag;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.geom.PathIterator; import java.awt.geom.PathIterator;
@ -1422,14 +1423,19 @@ public class Plot {
} }
PlotArea plotworld = getArea(); PlotArea plotworld = getArea();
if (plotworld.SCHEMATIC_ON_CLAIM) { if (plotworld.SCHEMATIC_ON_CLAIM) {
SchematicHandler.Schematic sch; Schematic sch = null;
if (schematic == null || schematic.isEmpty()) { try {
sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE); if (schematic == null || schematic.isEmpty()) {
} else {
sch = SchematicHandler.manager.getSchematic(schematic);
if (sch == null) {
sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE); sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
} else {
sch = SchematicHandler.manager.getSchematic(schematic);
if (sch == null) {
sch = SchematicHandler.manager.getSchematic(plotworld.SCHEMATIC_FILE);
}
} }
} catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace();
return true;
} }
SchematicHandler.manager.paste(sch, this, 0, 0, 0, true, new RunnableVal<Boolean>() { SchematicHandler.manager.paste(sch, this, 0, 0, 0, true, new RunnableVal<Boolean>() {
@Override public void run(Boolean value) { @Override public void run(Boolean value) {

View File

@ -4,15 +4,20 @@ import com.github.intellectualsites.plotsquared.configuration.serialization.Conf
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.NonNull;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import lombok.NonNull;
public abstract class PlotBlock implements ConfigurationSerializable { public abstract class PlotBlock implements ConfigurationSerializable {
private static Class<?> conversionType; private static Class<?> conversionType;
private static BlockRegistry blockRegistry; private static BlockRegistry blockRegistry;
protected PlotBlock() {
}
public static boolean isEverything(@NonNull final PlotBlock block) { public static boolean isEverything(@NonNull final PlotBlock block) {
return block.equals(LegacyPlotBlock.EVERYTHING) || block.equals(StringPlotBlock.EVERYTHING); return block.equals(LegacyPlotBlock.EVERYTHING) || block.equals(StringPlotBlock.EVERYTHING);
} }
@ -26,9 +31,6 @@ public abstract class PlotBlock implements ConfigurationSerializable {
return false; return false;
} }
protected PlotBlock() {
}
public static PlotBlock get(char combinedId) { public static PlotBlock get(char combinedId) {
switch (combinedId) { switch (combinedId) {
case 0: case 0:
@ -48,27 +50,6 @@ public abstract class PlotBlock implements ConfigurationSerializable {
return null; return null;
} }
@Override public Map<String, Object> serialize() {
return ImmutableMap.of("material", this.getRawId());
}
public <T> T to(@NonNull final Class<T> clazz) {
if (blockRegistry == null) {
blockRegistry = PlotSquared.imp().getBlockRegistry();
if (blockRegistry == null) {
throw new UnsupportedOperationException("The PlotSquared implementation has not registered a custom block registry."
+ " This method can't be used.");
}
conversionType = blockRegistry.getType();
}
if (!clazz.equals(conversionType)) {
throw new UnsupportedOperationException("The PlotSquared implementation has not registered a block registry for this object type");
}
return clazz.cast(blockRegistry.getItem(this));
}
public abstract boolean isAir();
public static StringPlotBlock get(@NonNull final String itemId) { public static StringPlotBlock get(@NonNull final String itemId) {
if (Settings.Enabled_Components.BLOCK_CACHE) { if (Settings.Enabled_Components.BLOCK_CACHE) {
return StringPlotBlock.getOrAdd(itemId); return StringPlotBlock.getOrAdd(itemId);
@ -89,21 +70,52 @@ public abstract class PlotBlock implements ConfigurationSerializable {
return get(((LegacyPlotBlock) plotBlock).getId(), (byte) 0); return get(((LegacyPlotBlock) plotBlock).getId(), (byte) 0);
} }
public static PlotBlock get(@NonNull final BaseBlock baseBlock) {
StringPlotBlock plotBlock = get(baseBlock.getBlockType().getId());
plotBlock.setBaseBlock(baseBlock);
return plotBlock;
}
public static PlotBlock get(@NonNull final Object type) { public static PlotBlock get(@NonNull final Object type) {
if (blockRegistry == null) { if (blockRegistry == null) {
blockRegistry = PlotSquared.imp().getBlockRegistry(); blockRegistry = PlotSquared.imp().getBlockRegistry();
if (blockRegistry == null) { if (blockRegistry == null) {
throw new UnsupportedOperationException("The PlotSquared implementation has not registered a custom block registry." throw new UnsupportedOperationException(
+ " This method can't be used."); "The PlotSquared implementation has not registered a custom block registry."
+ " This method can't be used.");
} }
conversionType = blockRegistry.getType(); conversionType = blockRegistry.getType();
} }
if (!type.getClass().equals(conversionType)) { if (!type.getClass().equals(conversionType)) {
throw new UnsupportedOperationException("The PlotSquared implementation has not registered a block registry for this object type"); throw new UnsupportedOperationException(
"The PlotSquared implementation has not registered a block registry for this object type");
} }
return blockRegistry.getPlotBlock(type); return blockRegistry.getPlotBlock(type);
} }
@Override public Map<String, Object> serialize() {
return ImmutableMap.of("material", this.getRawId());
}
public <T> T to(@NonNull final Class<T> clazz) {
if (blockRegistry == null) {
blockRegistry = PlotSquared.imp().getBlockRegistry();
if (blockRegistry == null) {
throw new UnsupportedOperationException(
"The PlotSquared implementation has not registered a custom block registry."
+ " This method can't be used.");
}
conversionType = blockRegistry.getType();
}
if (!clazz.equals(conversionType)) {
throw new UnsupportedOperationException(
"The PlotSquared implementation has not registered a block registry for this object type");
}
return clazz.cast(blockRegistry.getItem(this));
}
public abstract boolean isAir();
public final boolean equalsAny(final int id, @NonNull final String stringId) { public final boolean equalsAny(final int id, @NonNull final String stringId) {
if (this instanceof StringPlotBlock) { if (this instanceof StringPlotBlock) {
final StringPlotBlock stringPlotBlock = (StringPlotBlock) this; final StringPlotBlock stringPlotBlock = (StringPlotBlock) this;

View File

@ -1,7 +1,9 @@
package com.github.intellectualsites.plotsquared.plot.object; package com.github.intellectualsites.plotsquared.plot.object;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -11,25 +13,10 @@ public class StringPlotBlock extends PlotBlock {
public static final PlotBlock EVERYTHING = new StringPlotBlock(""); public static final PlotBlock EVERYTHING = new StringPlotBlock("");
private static final Map<String, StringPlotBlock> STRING_PLOT_BLOCK_CACHE = new HashMap<>(); private static final Map<String, StringPlotBlock> STRING_PLOT_BLOCK_CACHE = new HashMap<>();
@Getter private final String nameSpace;
public static StringPlotBlock getOrAdd(@NonNull final String itemId) { @Getter private final String itemId;
// final String id = itemId.toLowerCase(Locale.ENGLISH); @Getter @Setter private BaseBlock baseBlock = null;
StringPlotBlock plotBlock = STRING_PLOT_BLOCK_CACHE.get(itemId);
if (plotBlock == null) {
plotBlock = new StringPlotBlock(itemId);
STRING_PLOT_BLOCK_CACHE.put(itemId, plotBlock);
}
return plotBlock;
}
@Getter
private final String nameSpace;
@Getter
private final String itemId;
private boolean isForeign = false; private boolean isForeign = false;
public StringPlotBlock(@NonNull final String nameSpace, @NonNull final String itemId) { public StringPlotBlock(@NonNull final String nameSpace, @NonNull final String itemId) {
this.nameSpace = nameSpace.toLowerCase(Locale.ENGLISH); this.nameSpace = nameSpace.toLowerCase(Locale.ENGLISH);
this.itemId = itemId.toLowerCase(Locale.ENGLISH); this.itemId = itemId.toLowerCase(Locale.ENGLISH);
@ -51,6 +38,18 @@ public class StringPlotBlock extends PlotBlock {
this.determineForeign(); this.determineForeign();
} }
public static StringPlotBlock getOrAdd(@NonNull final String itemId) {
// final String id = itemId.toLowerCase(Locale.ENGLISH);
StringPlotBlock plotBlock = STRING_PLOT_BLOCK_CACHE.get(itemId);
if (plotBlock == null) {
plotBlock = new StringPlotBlock(itemId);
STRING_PLOT_BLOCK_CACHE.put(itemId, plotBlock);
}
return plotBlock;
}
private void determineForeign() { private void determineForeign() {
this.isForeign = !this.nameSpace.equals("minecraft"); this.isForeign = !this.nameSpace.equals("minecraft");
} }

View File

@ -0,0 +1,47 @@
package com.github.intellectualsites.plotsquared.plot.object.schematic;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.Getter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Schematic {
// Lossy but fast
@Getter private final BlockArrayClipboard clipboard;
@Getter private Map<String, Tag> flags = new HashMap<>();
public Schematic(BlockArrayClipboard clip) {
this.clipboard = clip;
}
public void setFlags(Map<String, Tag> flags) {
this.flags = flags == null ? new HashMap<>() : flags;
}
public boolean setBlock(BlockVector3 position, BaseBlock block) throws WorldEditException {
if (clipboard.getRegion().contains(position)) {
BlockVector3 v = position.subtract(clipboard.getRegion().getMinimumPoint());
clipboard.setBlock(v, block);
return true;
} else {
return false;
}
}
public void save(File file) throws IOException {
SpongeSchematicWriter ssw =
new SpongeSchematicWriter(new NBTOutputStream(new FileOutputStream(file)));
ssw.write(clipboard);
ssw.close();
}
}

View File

@ -0,0 +1,54 @@
package com.github.intellectualsites.plotsquared.plot.object.schematic;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An implementation of {@link Entity} that stores a {@link BaseEntity} with it.
*
* <p>Calls to {@link #getState()} return a clone.</p>
*/
abstract class StoredEntity implements Entity {
private final Location location;
private final BaseEntity entity;
/**
* Create a new instance.
*
* @param location the location
* @param entity the entity (which will be copied)
*/
StoredEntity(Location location, BaseEntity entity) {
checkNotNull(location);
checkNotNull(entity);
this.location = location;
this.entity = new BaseEntity(entity);
}
/**
* Get the entity state. This is not a copy.
*
* @return the entity
*/
BaseEntity getEntity() {
return entity;
}
@Override public BaseEntity getState() {
return new BaseEntity(entity);
}
@Override public Location getLocation() {
return location;
}
@Override public Extent getExtent() {
return location.getExtent();
}
}

View File

@ -1,14 +1,24 @@
package com.github.intellectualsites.plotsquared.plot.util; package com.github.intellectualsites.plotsquared.plot.util;
import com.github.intellectualsites.plotsquared.jnbt.*;
import com.github.intellectualsites.plotsquared.json.JSONArray; import com.github.intellectualsites.plotsquared.json.JSONArray;
import com.github.intellectualsites.plotsquared.json.JSONException; import com.github.intellectualsites.plotsquared.json.JSONException;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
import com.github.intellectualsites.plotsquared.plot.flag.Flag; import com.github.intellectualsites.plotsquared.plot.flag.Flag;
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
import com.github.intellectualsites.plotsquared.plot.generator.ClassicPlotWorld; import com.github.intellectualsites.plotsquared.plot.generator.ClassicPlotWorld;
import com.github.intellectualsites.plotsquared.plot.object.*; 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.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.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
@ -45,7 +55,7 @@ public abstract class SchematicHandler {
Iterator<Plot> i = plots.iterator(); Iterator<Plot> i = plots.iterator();
final Plot plot = i.next(); final Plot plot = i.next();
i.remove(); i.remove();
String o = UUIDHandler.getName(plot.owner); String o = UUIDHandler.getName(plot.guessOwner());
if (o == null) { if (o == null) {
o = "unknown"; o = "unknown";
} }
@ -108,13 +118,13 @@ public abstract class SchematicHandler {
* @return boolean true if succeeded * @return boolean true if succeeded
*/ */
public void paste(final Schematic schematic, final Plot plot, final int xOffset, public void paste(final Schematic schematic, final Plot plot, final int xOffset,
final int yOffset, final int zOffset, final boolean autoHeight, final int yOffset, final int zOffset, final boolean autoHeight, final Runnable whenDone) {
final RunnableVal<Boolean> whenDone) {
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(WorldUtil.IMP.getWeWorld(plot.getWorldName()), -1);
TaskManager.runTask(new Runnable() { TaskManager.runTask(new Runnable() {
@Override public void run() { @Override public void run() {
if (whenDone != null) {
whenDone.value = false;
}
if (schematic == null) { if (schematic == null) {
PlotSquared.debug("Schematic == null :|"); PlotSquared.debug("Schematic == null :|");
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
@ -126,13 +136,14 @@ public abstract class SchematicHandler {
Map<String, Tag> flags = schematic.getFlags(); Map<String, Tag> flags = schematic.getFlags();
if (!flags.isEmpty()) { if (!flags.isEmpty()) {
for (Map.Entry<String, Tag> entry : flags.entrySet()) { for (Map.Entry<String, Tag> entry : flags.entrySet()) {
//plot.setFlag(entry.getKey(), StringTag.class.cast(entry.getValue()).getValue()); plot.setFlag(Flags.getFlag(entry.getKey()),
StringTag.class.cast(entry.getValue()).getValue());
} }
} }
} }
final LocalBlockQueue queue = plot.getArea().getQueue(false); final LocalBlockQueue queue = plot.getArea().getQueue(false);
Dimension dimension = schematic.getSchematicDimension(); BlockVector3 dimension = schematic.getClipboard().getDimensions();
final int WIDTH = dimension.getX(); final int WIDTH = dimension.getX();
final int LENGTH = dimension.getZ(); final int LENGTH = dimension.getZ();
final int HEIGHT = dimension.getY(); final int HEIGHT = dimension.getY();
@ -149,8 +160,7 @@ public abstract class SchematicHandler {
return; return;
} }
// block type and data arrays // block type and data arrays
final short[] ids = schematic.ids; final BlockArrayClipboard blockArrayClipboard = schematic.getClipboard();
final byte[] datas = schematic.datas;
// Calculate the optimal height to paste the schematic at // Calculate the optimal height to paste the schematic at
final int y_offset_actual; final int y_offset_actual;
if (autoHeight) { if (autoHeight) {
@ -173,7 +183,6 @@ public abstract class SchematicHandler {
new Location(plot.getWorldName(), region.minX + xOffset, y_offset_actual, new Location(plot.getWorldName(), region.minX + xOffset, y_offset_actual,
region.minZ + zOffset); region.minZ + zOffset);
Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1); Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1);
// TODO switch to ChunkManager.chunkTask(pos1, pos2, task, whenDone, allocate);
final int p1x = pos1.getX(); final int p1x = pos1.getX();
final int p1z = pos1.getZ(); final int p1z = pos1.getZ();
final int p2x = pos2.getX(); final int p2x = pos2.getX();
@ -182,14 +191,14 @@ public abstract class SchematicHandler {
final int bcz = p1z >> 4; final int bcz = p1z >> 4;
final int tcx = p2x >> 4; final int tcx = p2x >> 4;
final int tcz = p2z >> 4; final int tcz = p2z >> 4;
final ArrayList<ChunkLoc> chunks = new ArrayList<ChunkLoc>(); final ArrayList<ChunkLoc> chunks = new ArrayList<>();
for (int x = bcx; x <= tcx; x++) { for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) { for (int z = bcz; z <= tcz; z++) {
chunks.add(new ChunkLoc(x, z)); chunks.add(new ChunkLoc(x, z));
} }
} }
TaskManager.runTaskAsync(new Runnable() { ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@Override public void run() { @Override public void run(int[] value) {
int count = 0; int count = 0;
while (!chunks.isEmpty() && count < 256) { while (!chunks.isEmpty() && count < 256) {
count++; count++;
@ -226,82 +235,9 @@ public abstract class SchematicHandler {
int i = i2 + rx; int i = i2 + rx;
int xx = p1x + rx; int xx = p1x + rx;
int zz = p1z + rz; int zz = p1z + rz;
int id = ids[i]; BaseBlock id = blockArrayClipboard
switch (id) { .getFullBlock(BlockVector3.at(rx, ry, rz));
case 0: queue.setBlock(xx, yy, zz, id);
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 51:
case 55:
case 56:
case 57:
case 58:
case 60:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 121:
case 122:
case 129:
case 133:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
queue.setBlock(xx, yy, zz, id);
break;
default:
queue.setBlock(xx, yy, zz,
PlotBlock.get((short) id, datas[i]));
break;
}
} }
} }
} }
@ -310,7 +246,7 @@ public abstract class SchematicHandler {
this.run(); this.run();
} else { } else {
queue.flush(); queue.flush();
HashMap<BlockLoc, CompoundTag> tiles = schematic.getTiles(); /*HashMap<BlockLoc, CompoundTag> tiles = schematic.getClipboard().getTiles();
if (!tiles.isEmpty()) { if (!tiles.isEmpty()) {
TaskManager.IMP.sync(new RunnableVal<Object>() { TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override public void run(Object value) { @Override public void run(Object value) {
@ -323,14 +259,10 @@ public abstract class SchematicHandler {
} }
} }
}); });
} }*/
if (whenDone != null) {
whenDone.value = true;
whenDone.run();
}
} }
} }
}); }, whenDone, 10);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
@ -339,85 +271,6 @@ public abstract class SchematicHandler {
}); });
} }
public Schematic getSchematic(CompoundTag tag) {
Map<String, Tag> tagMap = tag.getValue();
byte[] addBlocks = null;
if (tagMap.containsKey("AddBlocks")) {
addBlocks = ByteArrayTag.class.cast(tagMap.get("AddBlocks")).getValue();
}
short width = ShortTag.class.cast(tagMap.get("Width")).getValue();
short length = ShortTag.class.cast(tagMap.get("Length")).getValue();
short height = ShortTag.class.cast(tagMap.get("Height")).getValue();
byte[] block_sml = ByteArrayTag.class.cast(tagMap.get("Blocks")).getValue();
byte[] data = ByteArrayTag.class.cast(tagMap.get("Data")).getValue();
Map<String, Tag> flags;
if (tagMap.containsKey("Flags")) {
flags = CompoundTag.class.cast(tagMap.get("Flags")).getValue();
} else {
flags = null;
}
short[] block = new short[block_sml.length];
for (int i = 0; i < block.length; i++) {
short id = block_sml[i];
if (id < 0) {
id = (short) (id & 0xFF);
}
block[i] = id;
}
if (addBlocks != null) {
if (addBlocks.length == block.length) {
for (int i = 0; i < addBlocks.length; i++) {
byte val = addBlocks[i];
if (val != 0) {
block[i] |= (val << 8);
}
}
} else {
for (int index = 0; index < block.length; index++) {
if ((index & 1) == 0) {
block[index] =
(short) (((addBlocks[index >> 1] & 0x0F) << 8) + (block[index]));
} else {
block[index] =
(short) (((addBlocks[index >> 1] & 0xF0) << 4) + (block[index]));
}
}
}
}
// Slow as wrapper for each block
// final DataCollection[] collection = new DataCollection[b.length];
// for (int x = 0; x < b.length; x++) {
// collection[x] = new DataCollection(blocks[x], d[x]);
// }
// Schematic schem = new Schematic(collection, dimension, file);
Dimension dimensions = new Dimension(width, height, length);
Schematic schem = new Schematic(block, data, dimensions, flags);
// Slow
try {
List<Tag> blockStates = ListTag.class.cast(tagMap.get("TileEntities")).getValue();
for (Tag stateTag : blockStates) {
try {
CompoundTag ct = (CompoundTag) stateTag;
Map<String, Tag> state = ct.getValue();
short x = IntTag.class.cast(state.get("x")).getValue().shortValue();
short y = IntTag.class.cast(state.get("y")).getValue().shortValue();
short z = IntTag.class.cast(state.get("z")).getValue().shortValue();
schem.addTile(new BlockLoc(x, y, z), ct);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return schem;
}
public abstract boolean restoreTile(LocalBlockQueue queue, CompoundTag tag, int x, int y, public abstract boolean restoreTile(LocalBlockQueue queue, CompoundTag tag, int x, int y,
int z); int z);
@ -427,7 +280,7 @@ public abstract class SchematicHandler {
* @param name to check * @param name to check
* @return schematic if found, else null * @return schematic if found, else null
*/ */
public Schematic getSchematic(String name) { public Schematic getSchematic(String name) throws UnsupportedFormatException {
File parent = File parent =
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS); MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS);
if (!parent.exists()) { if (!parent.exists()) {
@ -436,7 +289,7 @@ public abstract class SchematicHandler {
} }
} }
File file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), File file = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(),
Settings.Paths.SCHEMATICS + File.separator + name + (name.endsWith(".schematic") ? Settings.Paths.SCHEMATICS + File.separator + name + (name.endsWith(".schem") ?
"" : "" :
".schematic")); ".schematic"));
return getSchematic(file); return getSchematic(file);
@ -448,12 +301,14 @@ public abstract class SchematicHandler {
* @return Immutable collection with schematic names * @return Immutable collection with schematic names
*/ */
public Collection<String> getShematicNames() { public Collection<String> getShematicNames() {
final File parent = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS); final File parent =
MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), Settings.Paths.SCHEMATICS);
final List<String> names = new ArrayList<>(); final List<String> names = new ArrayList<>();
if (parent.exists()) { if (parent.exists()) {
final String[] rawNames = parent.list((dir, name) -> name.endsWith(".schematic")); final String[] rawNames = parent.list((dir, name) -> name.endsWith(".schematic"));
if (rawNames != null) { if (rawNames != null) {
final List<String> transformed = Arrays.stream(rawNames).map(rawName -> rawName.substring(0, rawName.length() - 10)) final List<String> transformed = Arrays.stream(rawNames)
.map(rawName -> rawName.substring(0, rawName.length() - 10))
.collect(Collectors.toList()); .collect(Collectors.toList());
names.addAll(transformed); names.addAll(transformed);
} }
@ -467,13 +322,26 @@ public abstract class SchematicHandler {
* @param file to check * @param file to check
* @return schematic if found, else null * @return schematic if found, else null
*/ */
public Schematic getSchematic(File file) { public Schematic getSchematic(File file) throws UnsupportedFormatException {
if (!file.exists()) { if (!file.exists()) {
return null; return null;
} }
try { try {
return getSchematic(new FileInputStream(file)); if (BuiltInClipboardFormat.SPONGE_SCHEMATIC.isFormat(file)) {
} catch (FileNotFoundException e) { SpongeSchematicReader ssr =
new SpongeSchematicReader(new NBTInputStream(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)));
BlockArrayClipboard clip = (BlockArrayClipboard) msr.read();
return new Schematic(clip);
} else {
throw new UnsupportedFormatException(
"This schematic format is not recognised or supported.");
}
} catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
@ -495,15 +363,21 @@ public abstract class SchematicHandler {
return null; return null;
} }
try { try {
NBTInputStream stream = new NBTInputStream(new GZIPInputStream(is)); SpongeSchematicReader ssr =
CompoundTag tag = (CompoundTag) stream.readTag(1073741824); new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
is.close(); BlockArrayClipboard clip = (BlockArrayClipboard) ssr.read();
stream.close(); return new Schematic(clip);
return getSchematic(tag); } catch (IOException ignored) {
} catch (IOException e) { try {
e.printStackTrace(); MCEditSchematicReader msr =
PlotSquared.debug(is.toString() + " | " + is.getClass().getCanonicalName() new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
+ " is not in GZIP format : " + e.getMessage()); BlockArrayClipboard clip = (BlockArrayClipboard) msr.read();
return new Schematic(clip);
} catch (IOException e) {
e.printStackTrace();
PlotSquared.debug(is.toString() + " | " + is.getClass().getCanonicalName()
+ " is not in GZIP format : " + e.getMessage());
}
} }
return null; return null;
} }
@ -547,7 +421,7 @@ public abstract class SchematicHandler {
try { try {
try (GZIPOutputStream gzip = new GZIPOutputStream(output, true)) { try (GZIPOutputStream gzip = new GZIPOutputStream(output, true)) {
try (NBTOutputStream nos = new NBTOutputStream(gzip)) { try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
nos.writeTag(tag); nos.writeNamedTag("Schematic", tag);
} }
} }
} catch (IOException e) { } catch (IOException e) {
@ -574,7 +448,7 @@ public abstract class SchematicHandler {
tmp.getParentFile().mkdirs(); tmp.getParentFile().mkdirs();
try (OutputStream stream = new FileOutputStream(tmp); try (OutputStream stream = new FileOutputStream(tmp);
NBTOutputStream output = new NBTOutputStream(new GZIPOutputStream(stream))) { NBTOutputStream output = new NBTOutputStream(new GZIPOutputStream(stream))) {
output.writeTag(tag); output.writeNamedTag("Schematic", tag);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
@ -585,35 +459,6 @@ public abstract class SchematicHandler {
return true; return true;
} }
/**
* Create a compound tag from blocks
* - Untested
*
* @param blocks
* @param blockData
* @param dimension
* @return
*/
public CompoundTag createTag(byte[] blocks, byte[] blockData, Dimension dimension) {
HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag("Width", (short) dimension.getX()));
schematic.put("Length", new ShortTag("Length", (short) dimension.getZ()));
schematic.put("Height", new ShortTag("Height", (short) dimension.getY()));
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));
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>()));
return new CompoundTag("Schematic", schematic);
}
public abstract void getCompoundTag(String world, Set<RegionWrapper> regions, public abstract void getCompoundTag(String world, Set<RegionWrapper> regions,
RunnableVal<CompoundTag> whenDone); RunnableVal<CompoundTag> whenDone);
@ -625,9 +470,9 @@ public abstract class SchematicHandler {
for (Map.Entry<Flag<?>, Object> entry : plot.getFlags().entrySet()) { for (Map.Entry<Flag<?>, Object> entry : plot.getFlags().entrySet()) {
String key = entry.getKey().getName(); String key = entry.getKey().getName();
flagMap.put(key, flagMap.put(key,
new StringTag(key, entry.getKey().valueToString(entry.getValue()))); new StringTag(entry.getKey().valueToString(entry.getValue())));
} }
CompoundTag tag = new CompoundTag("Flags", flagMap); CompoundTag tag = new CompoundTag(flagMap);
HashMap<String, Tag> map = new HashMap<>(value.getValue()); HashMap<String, Tag> map = new HashMap<>(value.getValue());
map.put("Flags", tag); map.put("Flags", tag);
value.setValue(map); value.setValue(map);
@ -637,160 +482,26 @@ public abstract class SchematicHandler {
}); });
} }
/** public class UnsupportedFormatException extends Exception {
* Schematic Dimensions. /**
*/ * Throw with a message.
public static class Dimension { *
* @param message the message
private final int x; */
private final int y; public UnsupportedFormatException(String message) {
private final int z; super(message);
public Dimension(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getZ() {
return this.z;
}
}
/**
* Schematic Class
*/
public class Schematic {
// Lossy but fast
private final short[] ids;
private final byte[] datas;
private final Dimension schematicDimension;
private Map<String, Tag> flags;
private HashMap<BlockLoc, CompoundTag> tiles;
public Schematic(short[] i, byte[] b, Dimension d, Map<String, Tag> flags) {
this.ids = i;
this.datas = b;
this.schematicDimension = d;
setFlags(flags);
}
public Map<String, Tag> getFlags() {
return this.flags;
}
public void setFlags(Map<String, Tag> flags) {
this.flags = flags == null ? new HashMap<String, Tag>() : flags;
} }
/** /**
* Add a tile entity * Throw with a message and a cause.
* *
* @param loc * @param message the message
* @param tag * @param cause the cause
*/ */
public void addTile(BlockLoc loc, CompoundTag tag) { public UnsupportedFormatException(String message, Throwable cause) {
if (this.tiles == null) { super(message, cause);
this.tiles = new HashMap<>();
}
this.tiles.put(loc, tag);
} }
/**
* Get the tile entities
*
* @return Map of block location to tag
*/
public HashMap<BlockLoc, CompoundTag> getTiles() {
return this.tiles == null ? new HashMap<BlockLoc, CompoundTag>() : this.tiles;
}
/**
* Get the schematic dimensions.
*
* @return
*/
public Dimension getSchematicDimension() {
return this.schematicDimension;
}
/**
* Get the block type array.
*
* @return
*/
public short[] getIds() {
return this.ids;
}
/**
* Get the block data array.
*
* @return
*/
public byte[] getDatas() {
return this.datas;
}
public Schematic copySection(RegionWrapper region) {
int x1 = region.minX;
int x2 = region.maxX;
int z1 = region.minZ;
int z2 = region.maxZ;
int y1 = region.minY;
int y2 = Math.min(region.maxY, 255);
int width = x2 - x1 + 1;
int length = z2 - z1 + 1;
int height = y2 - y1 + 1;
short[] ids2 = new short[width * length * height];
byte[] datas2 = new byte[width * length * height];
int dx = this.schematicDimension.getX();
int dy = this.schematicDimension.getY();
int dz = this.schematicDimension.getZ();
for (int y = y1; y <= y2; y++) {
int yy = y >= 0 ? y < dy ? y : y - dy : y + dy;
int i1 = yy * dx * dz;
int j1 = (y - y1) * width * length;
for (int z = z1; z <= z2; z++) {
int zz = z >= 0 ? z < dz ? z : z - dz : z + dz;
int i2 = i1 + zz * dx;
int j2 = j1 + (z - z1) * width;
for (int x = x1; x <= x2; x++) {
int xx = x >= 0 ? x < dx ? x : x - dx : x + dx;
int i3 = i2 + xx;
int j3 = j2 + (x - x1);
ids2[j3] = this.ids[i3];
datas2[j3] = this.datas[i3];
}
}
}
return new Schematic(ids2, datas2, new Dimension(width, height, length), null);
}
public void save(File file) {
byte[] ids2 = new byte[this.ids.length];
for (int i = 0; i < this.ids.length; i++) {
ids2[i] = (byte) this.ids[i];
}
CompoundTag tag = createTag(ids2, this.datas, this.schematicDimension);
SchematicHandler.this.save(tag, file.getAbsolutePath());
}
} }
} }

View File

@ -1,9 +1,9 @@
package com.github.intellectualsites.plotsquared.plot.util; package com.github.intellectualsites.plotsquared.plot.util;
import com.github.intellectualsites.plotsquared.jnbt.*;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.schematic.PlotItem; import com.github.intellectualsites.plotsquared.plot.object.schematic.PlotItem;
import com.sk89q.jnbt.*;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
@ -54,6 +54,8 @@ public abstract class WorldUtil {
public abstract void setBiomes(String world, RegionWrapper region, String biome); public abstract void setBiomes(String world, RegionWrapper region, String biome);
public abstract com.sk89q.worldedit.world.World getWeWorld(String world);
public void upload(final Plot plot, UUID uuid, String file, RunnableVal<URL> whenDone) { public void upload(final Plot plot, UUID uuid, String file, RunnableVal<URL> whenDone) {
if (plot == null) { if (plot == null) {
throw new IllegalArgumentException("Plot may not be null!"); throw new IllegalArgumentException("Plot may not be null!");
@ -70,16 +72,17 @@ public abstract class WorldUtil {
zos.putNextEntry(ze); zos.putNextEntry(ze);
try (NBTInputStream nis = new NBTInputStream( try (NBTInputStream nis = new NBTInputStream(
new GZIPInputStream(new FileInputStream(dat)))) { new GZIPInputStream(new FileInputStream(dat)))) {
CompoundTag tag = (CompoundTag) nis.readTag(); CompoundTag tag = (CompoundTag) nis.readNamedTag().getTag();
CompoundTag data = (CompoundTag) tag.getValue().get("Data"); CompoundTag data = (CompoundTag) tag.getValue().get("Data");
Map<String, Tag> map = ReflectionUtils.getMap(data.getValue()); Map<String, Tag> map = ReflectionUtils.getMap(data.getValue());
map.put("SpawnX", new IntTag("SpawnX", home.getX())); map.put("SpawnX", new IntTag(home.getX()));
map.put("SpawnY", new IntTag("SpawnY", home.getY())); map.put("SpawnY", new IntTag(home.getY()));
map.put("SpawnZ", new IntTag("SpawnZ", home.getZ())); map.put("SpawnZ", new IntTag(home.getZ()));
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (NBTOutputStream out = new NBTOutputStream( try (NBTOutputStream out = new NBTOutputStream(
new GZIPOutputStream(baos, true))) { new GZIPOutputStream(baos, true))) {
out.writeTag(tag); //TODO Find what this should be called
out.writeNamedTag("Schematic????", tag);
} }
zos.write(baos.toByteArray()); zos.write(baos.toByteArray());
} }

View File

@ -5,6 +5,7 @@ import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.MathMan; import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.NonNull; import lombok.NonNull;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -85,6 +86,33 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
this.modified = modified; this.modified = modified;
} }
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
if ((y > 255) || (y < 0)) {
return false;
}
int cx = x >> 4;
int cz = z >> 4;
if (cx != lastX || cz != lastZ) {
lastX = cx;
lastZ = cz;
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
lastWrappedChunk = this.blocks.get(pair);
if (lastWrappedChunk == null) {
lastWrappedChunk = this.getLocalChunk(x >> 4, z >> 4);
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
LocalChunk previous = this.blocks.put(pair, lastWrappedChunk);
if (previous == null) {
chunks.add(lastWrappedChunk);
return true;
}
this.blocks.put(pair, previous);
lastWrappedChunk = previous;
}
}
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
return true;
}
@Override public boolean setBlock(int x, int y, int z, String id) { @Override public boolean setBlock(int x, int y, int z, String id) {
if ((y > 255) || (y < 0)) { if ((y > 255) || (y < 0)) {
return false; return false;
@ -249,6 +277,8 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
} }
} }
public abstract void setBlock(final int x, final int y, final int z, final BaseBlock id);
public abstract void setBlock(final int x, final int y, final int z, final String id); public abstract void setBlock(final int x, final int y, final int z, final String id);
public abstract void setBlock(final int x, final int y, final int z, final int id, public abstract void setBlock(final int x, final int y, final int z, final int id,
@ -281,11 +311,27 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
blocks = new PlotBlock[16][]; blocks = new PlotBlock[16][];
} }
@Override public void setBlock(final int x, final int y, final int z, @NonNull final String id) { @Override
public void setBlock(final int x, final int y, final int z, @NonNull final BaseBlock id) {
this.setInternal(x, y, z, id);
}
@Override
public void setBlock(final int x, final int y, final int z, @NonNull final String id) {
final PlotBlock block = PlotBlock.get(id); final PlotBlock block = PlotBlock.get(id);
this.setInternal(x, y, z, block); this.setInternal(x, y, z, block);
} }
private void setInternal(final int x, final int y, final int z, final BaseBlock bsh) {
final int i = MainUtil.CACHE_I[y][x][z];
final int j = MainUtil.CACHE_J[y][x][z];
PlotBlock[] array = blocks[i];
if (array == null) {
array = (blocks[i] = new PlotBlock[4096]);
}
array[j] = PlotBlock.get(bsh);
}
private void setInternal(final int x, final int y, final int z, final PlotBlock plotBlock) { private void setInternal(final int x, final int y, final int z, final PlotBlock plotBlock) {
final int i = MainUtil.CACHE_I[y][x][z]; final int i = MainUtil.CACHE_I[y][x][z];
final int j = MainUtil.CACHE_J[y][x][z]; final int j = MainUtil.CACHE_J[y][x][z];

View File

@ -1,6 +1,7 @@
package com.github.intellectualsites.plotsquared.plot.util.block; package com.github.intellectualsites.plotsquared.plot.util.block;
import com.github.intellectualsites.plotsquared.plot.object.PlotBlock; import com.github.intellectualsites.plotsquared.plot.object.PlotBlock;
import com.sk89q.worldedit.world.block.BaseBlock;
public class DelegateLocalBlockQueue extends LocalBlockQueue { public class DelegateLocalBlockQueue extends LocalBlockQueue {
@ -57,6 +58,10 @@ public class DelegateLocalBlockQueue extends LocalBlockQueue {
} }
} }
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
return parent.setBlock(x, y, z, id);
}
@Override public boolean setBlock(int x, int y, int z, String id) { @Override public boolean setBlock(int x, int y, int z, String id) {
return parent.setBlock(x, y, z, id); return parent.setBlock(x, y, z, id);
} }

View File

@ -1,11 +1,12 @@
package com.github.intellectualsites.plotsquared.plot.util.block; package com.github.intellectualsites.plotsquared.plot.util.block;
import com.github.intellectualsites.plotsquared.jnbt.CompoundTag;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
import com.github.intellectualsites.plotsquared.plot.util.StringMan; import com.github.intellectualsites.plotsquared.plot.util.StringMan;
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil; import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.block.BaseBlock;
import lombok.NonNull; import lombok.NonNull;
import java.util.Map; import java.util.Map;
@ -46,6 +47,8 @@ public abstract class LocalBlockQueue {
public abstract boolean setBlock(final int x, final int y, final int z, final String id); public abstract boolean setBlock(final int x, final int y, final int z, final String id);
public abstract boolean setBlock(final int x, final int y, final int z, final BaseBlock id);
public final boolean setBlock(int x, int y, int z, @NonNull final PlotBlock block) { public final boolean setBlock(int x, int y, int z, @NonNull final PlotBlock block) {
if (block instanceof LegacyPlotBlock) { if (block instanceof LegacyPlotBlock) {
final LegacyPlotBlock legacyPlotBlock = (LegacyPlotBlock) block; final LegacyPlotBlock legacyPlotBlock = (LegacyPlotBlock) block;

View File

@ -1,5 +1,7 @@
package com.github.intellectualsites.plotsquared.plot.util.block; package com.github.intellectualsites.plotsquared.plot.util.block;
import com.sk89q.worldedit.world.block.BaseBlock;
public class OffsetLocalBlockQueue extends DelegateLocalBlockQueue { public class OffsetLocalBlockQueue extends DelegateLocalBlockQueue {
private final int ox; private final int ox;
private final int oy; private final int oy;
@ -16,7 +18,7 @@ public class OffsetLocalBlockQueue extends DelegateLocalBlockQueue {
return super.setBiome(ox + x, oy + y, biome); return super.setBiome(ox + x, oy + y, biome);
} }
@Override public boolean setBlock(int x, int y, int z, int id, int data) { @Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
return super.setBlock(ox + x, oy + y, oz + z, id, data); return super.setBlock(ox + x, oy + y, oz + z, id);
} }
} }

View File

@ -2,6 +2,7 @@ package com.github.intellectualsites.plotsquared.plot.util.block;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.sk89q.worldedit.world.block.BaseBlock;
public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue { public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
private final int minX; private final int minX;
@ -44,9 +45,14 @@ public class ScopedLocalBlockQueue extends DelegateLocalBlockQueue {
} }
} }
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super
.setBlock(x + minX, y + minY, z + minZ, id);
}
@Override public boolean setBlock(int x, int y, int z, String id) { @Override public boolean setBlock(int x, int y, int z, String id) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super
super.setBlock(x + minX, y + minY, z + minZ, id); .setBlock(x + minX, y + minY, z + minZ, id);
} }
@Override public boolean setBlock(int x, int y, int z, int id, int data) { @Override public boolean setBlock(int x, int y, int z, int id, int data) {

View File

@ -57,7 +57,7 @@ subprojects {
} }
dependencies { dependencies {
compile(group: 'com.sk89q.worldedit', name: 'worldedit-core', version: '6.1.3-SNAPSHOT') { compile(group: 'com.sk89q.worldedit', name: 'worldedit-core', version: '7.0.0-SNAPSHOT') {
exclude(module: 'bukkit-classloader-check') exclude(module: 'bukkit-classloader-check')
exclude(module: 'mockito-core') exclude(module: 'mockito-core')
exclude(module: 'dummypermscompat') exclude(module: 'dummypermscompat')