mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-12-22 09:08:03 +01:00
Added schematic loading and pasting.
Player can create an island using /island create Only the default island is supported right now. No GUI. Uses NMS to paste. Only supported on 1.12.
This commit is contained in:
parent
2a9ddd6579
commit
dcda604e6c
1
lib/.gitignore
vendored
Normal file
1
lib/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/spigot-1.12.jar
|
18
plugin.yml
18
plugin.yml
@ -8,4 +8,20 @@ depend: [Vault]
|
||||
softdepend: [Herochat, DeluxeChat, PlaceholderAPI, MVdWPlaceholderAPI]
|
||||
|
||||
load: startup
|
||||
loadbefore: [Multiverse-Core]
|
||||
loadbefore: [Multiverse-Core]
|
||||
|
||||
commands:
|
||||
island:
|
||||
description: Main player command
|
||||
aliases: [is, island]
|
||||
usage: |
|
||||
/island help
|
||||
asadmin:
|
||||
description: Admin commands
|
||||
usage: |
|
||||
/asadmin
|
||||
asc:
|
||||
description: Game challenges
|
||||
aliases: [c, challenge, aschallenge, challenges]
|
||||
usage: |
|
||||
/challenge
|
8
pom.xml
8
pom.xml
@ -9,6 +9,7 @@
|
||||
<description>The next generation of ASkyBlock</description>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<server.jars>${project.basedir}/lib</server.jars>
|
||||
</properties>
|
||||
<build>
|
||||
<defaultGoal>clean package install</defaultGoal>
|
||||
@ -72,6 +73,13 @@
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>LATEST</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>spigotmc.org</groupId>
|
||||
<artifactId>spigot-1.12</artifactId>
|
||||
<scope>system</scope>
|
||||
<systemPath>${server.jars}/spigot-1.12.jar</systemPath>
|
||||
<version>1.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
BIN
schematics/double.schematic
Normal file
BIN
schematics/double.schematic
Normal file
Binary file not shown.
BIN
schematics/harder.schematic
Normal file
BIN
schematics/harder.schematic
Normal file
Binary file not shown.
BIN
schematics/island.schematic
Normal file
BIN
schematics/island.schematic
Normal file
Binary file not shown.
BIN
schematics/nether.schematic
Normal file
BIN
schematics/nether.schematic
Normal file
Binary file not shown.
@ -3,10 +3,13 @@ package us.tastybento.bskyblock;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import us.tastybento.bskyblock.commands.IslandCommand;
|
||||
import us.tastybento.bskyblock.config.BSBLocale;
|
||||
import us.tastybento.bskyblock.config.PluginConfig;
|
||||
import us.tastybento.bskyblock.config.Settings;
|
||||
@ -15,6 +18,7 @@ import us.tastybento.bskyblock.database.managers.IslandsManager;
|
||||
import us.tastybento.bskyblock.database.managers.OfflineHistoryMessages;
|
||||
import us.tastybento.bskyblock.database.managers.PlayersManager;
|
||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||
import us.tastybento.bskyblock.schematics.SchematicsMgr;
|
||||
import us.tastybento.bskyblock.util.VaultHelper;
|
||||
|
||||
/**
|
||||
@ -31,6 +35,9 @@ public class BSkyBlock extends JavaPlugin{
|
||||
private PlayersManager playersManager;
|
||||
private IslandsManager islandsManager;
|
||||
private OfflineHistoryMessages offlineHistoryMessages;
|
||||
|
||||
// Schematics
|
||||
private SchematicsMgr schematicsManager;
|
||||
|
||||
// Metrics
|
||||
private Metrics metrics;
|
||||
@ -67,6 +74,8 @@ public class BSkyBlock extends JavaPlugin{
|
||||
getLogger().warning("Could not set up economy! - Running without an economy.");
|
||||
Settings.useEconomy = false;
|
||||
}
|
||||
|
||||
VaultHelper.setupPermissions();
|
||||
|
||||
// These items have to be loaded when the server has done 1 tick.
|
||||
// Note Worlds are not loaded this early, so any Locations or World reference will be null
|
||||
@ -117,6 +126,12 @@ public class BSkyBlock extends JavaPlugin{
|
||||
|
||||
playersManager.load();
|
||||
islandsManager.load();
|
||||
|
||||
// Load schematics
|
||||
Settings.chestItems = new ItemStack[] {new ItemStack(Material.LAVA_BUCKET,1)};
|
||||
schematicsManager = new SchematicsMgr(plugin);
|
||||
|
||||
getCommand("island").setExecutor(new IslandCommand(plugin));
|
||||
/*
|
||||
*DEBUG CODE
|
||||
Island loadedIsland = islandsManager.getIsland(owner);
|
||||
@ -260,4 +275,16 @@ public class BSkyBlock extends JavaPlugin{
|
||||
public IslandsManager getIslands(){
|
||||
return islandsManager;
|
||||
}
|
||||
|
||||
public static BSkyBlock getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the schematics
|
||||
*/
|
||||
public SchematicsMgr getSchematics() {
|
||||
return schematicsManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@ package us.tastybento.bskyblock.config;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -18,7 +19,36 @@ import us.tastybento.bskyblock.database.managers.OfflineHistoryMessages.HistoryM
|
||||
public class Settings {
|
||||
/* The settings variables should follow the config order */
|
||||
|
||||
public static final String PERMPREFIX = "bskyblock.";
|
||||
|
||||
// Constants
|
||||
// Game Type BSKYBLOCK or ACIDISLAND
|
||||
public enum GameType {
|
||||
BSKYBLOCK, ACIDISLAND
|
||||
}
|
||||
/*
|
||||
public final static GameType GAMETYPE = GameType.ACIDISLAND;
|
||||
// The spawn command (Essentials spawn for example)
|
||||
public final static String SPAWNCOMMAND = "spawn";
|
||||
// Permission prefix
|
||||
public final static String PERMPREFIX = "acidisland.";
|
||||
// The island command
|
||||
public final static String ISLANDCOMMAND = "ai";
|
||||
// The challenge command
|
||||
public static final String CHALLENGECOMMAND = "aic";
|
||||
// Admin command
|
||||
public static final String ADMINCOMMAND = "acid";
|
||||
*/
|
||||
public final static GameType GAMETYPE = GameType.BSKYBLOCK;
|
||||
// Permission prefix
|
||||
public final static String PERMPREFIX = "bskyblock.";
|
||||
// The island command
|
||||
public final static String ISLANDCOMMAND = "island";
|
||||
// The challenge command
|
||||
public static final String CHALLENGECOMMAND = "asc";
|
||||
// The spawn command (Essentials spawn for example)
|
||||
public final static String SPAWNCOMMAND = "spawn";
|
||||
// Admin command
|
||||
public static final String ADMINCOMMAND = "asadmin";
|
||||
|
||||
/* GENERAL */
|
||||
public static boolean metrics;
|
||||
@ -149,9 +179,13 @@ public class Settings {
|
||||
public static boolean acidFullArmorProtection;
|
||||
|
||||
/* SCHEMATICS */
|
||||
public static EntityType companionType;
|
||||
public static List<String> companionNames;
|
||||
public static List<ItemStack> chestItems;
|
||||
public static ItemStack[] chestItems;
|
||||
public static Biome defaultBiome;
|
||||
public static boolean usePhysics;
|
||||
public static EntityType companionType;
|
||||
public static boolean useSchematicPanel;
|
||||
public static boolean chooseIslandRandomly;
|
||||
|
||||
// TODO added this just to avoid compilation errors, but will be changed in the future
|
||||
public static List<HistoryMessageType> historyMessagesTypes;
|
||||
@ -173,4 +207,11 @@ public class Settings {
|
||||
public static boolean createEnd;
|
||||
|
||||
public static boolean islandEnd;
|
||||
public static boolean resetMoney;
|
||||
public static double acidDamage;
|
||||
public static int islandXOffset;
|
||||
public static int islandStartX;
|
||||
public static int islandZOffset;
|
||||
public static int islandStartZ;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package us.tastybento.bskyblock.database.managers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
@ -8,12 +7,31 @@ import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.material.SimpleAttachableMaterialData;
|
||||
import org.bukkit.material.TrapDoor;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.config.Settings;
|
||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||
import us.tastybento.bskyblock.database.objects.Island;
|
||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||
import us.tastybento.bskyblock.schematics.Schematic;
|
||||
import us.tastybento.bskyblock.schematics.Schematic.PasteReason;
|
||||
import us.tastybento.bskyblock.util.SafeSpotTeleport;
|
||||
import us.tastybento.bskyblock.util.Util;
|
||||
|
||||
/**
|
||||
* The job of this class is manage all island related data.
|
||||
@ -40,6 +58,7 @@ public class IslandsManager {
|
||||
// Metrics data
|
||||
private int metrics_createdcount = 0;
|
||||
private AbstractDatabaseHandler<Island> handler;
|
||||
private Location last;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public IslandsManager(BSkyBlock plugin){
|
||||
@ -352,4 +371,512 @@ public class IslandsManager {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This teleports player to their island. If not safe place can be found
|
||||
* then the player is sent to spawn via /spawn command
|
||||
*
|
||||
* @param player
|
||||
* @return true if the home teleport is successful
|
||||
*/
|
||||
public boolean homeTeleport(final Player player) {
|
||||
return homeTeleport(player, 1);
|
||||
}
|
||||
/**
|
||||
* Teleport player to a home location. If one cannot be found a search is done to
|
||||
* find a safe place.
|
||||
* @param player
|
||||
* @param number - home location to do to
|
||||
* @return true if successful, false if not
|
||||
*/
|
||||
public boolean homeTeleport(final Player player, int number) {
|
||||
Location home = null;
|
||||
//plugin.getLogger().info("home teleport called for #" + number);
|
||||
home = getSafeHomeLocation(player.getUniqueId(), number);
|
||||
//plugin.getLogger().info("home get safe loc = " + home);
|
||||
// Check if the player is a passenger in a boat
|
||||
if (player.isInsideVehicle()) {
|
||||
Entity boat = player.getVehicle();
|
||||
if (boat instanceof Boat) {
|
||||
player.leaveVehicle();
|
||||
// Remove the boat so they don't lie around everywhere
|
||||
boat.remove();
|
||||
player.getInventory().addItem(new ItemStack(Material.BOAT, 1));
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
||||
if (home == null) {
|
||||
//plugin.getLogger().info("Fixing home location using safe spot teleport");
|
||||
// Try to fix this teleport location and teleport the player if possible
|
||||
new SafeSpotTeleport(plugin, player, plugin.getPlayers().getHomeLocation(player.getUniqueId(), number), number);
|
||||
return true;
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: home loc = " + home + " teleporting");
|
||||
//home.getChunk().load();
|
||||
player.teleport(home);
|
||||
//player.sendBlockChange(home, Material.GLOWSTONE, (byte)0);
|
||||
if (number ==1 ) {
|
||||
Util.sendMessage(player, ChatColor.GREEN + "Teleported");
|
||||
} else {
|
||||
Util.sendMessage(player, ChatColor.GREEN + "teleported to #" + number);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines a safe teleport spot on player's island or the team island
|
||||
* they belong to.
|
||||
*
|
||||
* @param playerUUID UUID of player
|
||||
* @param number - starting home location e.g., 1
|
||||
* @return Location of a safe teleport spot or null if one cannot be found
|
||||
*/
|
||||
public Location getSafeHomeLocation(final UUID playerUUID, int number) {
|
||||
// Try the numbered home location first
|
||||
Location l = plugin.getPlayers().getHomeLocation(playerUUID, number);
|
||||
if (l == null) {
|
||||
// Get the default home, which may be null too, but that's okay
|
||||
number = 1;
|
||||
l = plugin.getPlayers().getHomeLocation(playerUUID, number);
|
||||
}
|
||||
// Check if it is safe
|
||||
//plugin.getLogger().info("DEBUG: Home location " + l);
|
||||
if (l != null) {
|
||||
// Homes are stored as integers and need correcting to be more central
|
||||
if (isSafeLocation(l)) {
|
||||
return l.clone().add(new Vector(0.5D,0,0.5D));
|
||||
}
|
||||
// To cover slabs, stairs and other half blocks, try one block above
|
||||
Location lPlusOne = l.clone();
|
||||
lPlusOne.add(new Vector(0, 1, 0));
|
||||
if (lPlusOne != null) {
|
||||
if (isSafeLocation(lPlusOne)) {
|
||||
// Adjust the home location accordingly
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, lPlusOne, number);
|
||||
return lPlusOne.clone().add(new Vector(0.5D,0,0.5D));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//plugin.getLogger().info("DEBUG: Home location either isn't safe, or does not exist so try the island");
|
||||
// Home location either isn't safe, or does not exist so try the island
|
||||
// location
|
||||
if (plugin.getPlayers().inTeam(playerUUID)) {
|
||||
l = plugin.getIslands().getIslandLocation(playerUUID);
|
||||
if (isSafeLocation(l)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, l, number);
|
||||
return l.clone().add(new Vector(0.5D,0,0.5D));
|
||||
} else {
|
||||
// try team leader's home
|
||||
Location tlh = plugin.getPlayers().getHomeLocation(plugin.getIslands().getTeamLeader(playerUUID));
|
||||
if (tlh != null) {
|
||||
if (isSafeLocation(tlh)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, tlh, number);
|
||||
return tlh.clone().add(new Vector(0.5D,0,0.5D));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
l = plugin.getIslands().getIslandLocation(playerUUID);
|
||||
if (isSafeLocation(l)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, l, number);
|
||||
return l.clone().add(new Vector(0.5D,0,0.5D));
|
||||
}
|
||||
}
|
||||
if (l == null) {
|
||||
plugin.getLogger().warning(plugin.getPlayers().getName(playerUUID) + " player has no island!");
|
||||
return null;
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: If these island locations are not safe, then we need to get creative");
|
||||
// If these island locations are not safe, then we need to get creative
|
||||
// Try the default location
|
||||
//plugin.getLogger().info("DEBUG: default");
|
||||
Location dl = new Location(l.getWorld(), l.getX() + 0.5D, l.getY() + 5D, l.getZ() + 2.5D, 0F, 30F);
|
||||
if (isSafeLocation(dl)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, dl, number);
|
||||
return dl;
|
||||
}
|
||||
// Try just above the bedrock
|
||||
//plugin.getLogger().info("DEBUG: above bedrock");
|
||||
dl = new Location(l.getWorld(), l.getX() + 0.5D, l.getY() + 5D, l.getZ() + 0.5D, 0F, 30F);
|
||||
if (isSafeLocation(dl)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, dl, number);
|
||||
return dl;
|
||||
}
|
||||
// Try all the way up to the sky
|
||||
//plugin.getLogger().info("DEBUG: try all the way to the sky");
|
||||
for (int y = l.getBlockY(); y < 255; y++) {
|
||||
final Location n = new Location(l.getWorld(), l.getX() + 0.5D, y, l.getZ() + 0.5D);
|
||||
if (isSafeLocation(n)) {
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, n, number);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: unsuccessful");
|
||||
// Unsuccessful
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a generic scan that can work in the overworld or the nether
|
||||
* @param l - location around which to scan
|
||||
* @param i - the range to scan for a location < 0 means the full island.
|
||||
* @return - safe location, or null if none can be found
|
||||
*/
|
||||
public Location bigScan(Location l, int i) {
|
||||
final int height;
|
||||
final int depth;
|
||||
if (i > 0) {
|
||||
height = i;
|
||||
depth = i;
|
||||
} else {
|
||||
Island island = getIslandAt(l);
|
||||
if (island == null) {
|
||||
return null;
|
||||
}
|
||||
i = island.getProtectionRange();
|
||||
height = l.getWorld().getMaxHeight() - l.getBlockY();
|
||||
depth = l.getBlockY();
|
||||
}
|
||||
|
||||
|
||||
//plugin.getLogger().info("DEBUG: ranges i = " + i);
|
||||
//plugin.getLogger().info(" " + minX + "," + minZ + " " + maxX + " " + maxZ);
|
||||
//plugin.getLogger().info("DEBUG: height = " + height);
|
||||
//plugin.getLogger().info("DEBUG: depth = " + depth);
|
||||
//plugin.getLogger().info("DEBUG: trying to find a safe spot at " + l.toString());
|
||||
|
||||
// Work outwards from l until the closest safe location is found.
|
||||
int minXradius = 0;
|
||||
int maxXradius = 0;
|
||||
int minZradius = 0;
|
||||
int maxZradius = 0;
|
||||
int minYradius = 0;
|
||||
int maxYradius = 0;
|
||||
|
||||
do {
|
||||
int minX = l.getBlockX()-minXradius;
|
||||
int minZ = l.getBlockZ()-minZradius;
|
||||
int minY = l.getBlockY()-minYradius;
|
||||
int maxX = l.getBlockX()+maxXradius;
|
||||
int maxZ = l.getBlockZ()+maxZradius;
|
||||
int maxY = l.getBlockY()+maxYradius;
|
||||
for (int x = minX; x<= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ) && (y > minY && y < maxY))) {
|
||||
//plugin.getLogger().info("DEBUG: checking " + x + "," + y + "," + z);
|
||||
Location ultimate = new Location(l.getWorld(), x + 0.5D, y, z + 0.5D);
|
||||
if (isSafeLocation(ultimate)) {
|
||||
//plugin.getLogger().info("DEBUG: Found! " + ultimate);
|
||||
return ultimate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minXradius < i) {
|
||||
minXradius++;
|
||||
}
|
||||
if (maxXradius < i) {
|
||||
maxXradius++;
|
||||
}
|
||||
if (minZradius < i) {
|
||||
minZradius++;
|
||||
}
|
||||
if (maxZradius < i) {
|
||||
maxZradius++;
|
||||
}
|
||||
if (minYradius < depth) {
|
||||
minYradius++;
|
||||
}
|
||||
if (maxYradius < height) {
|
||||
maxYradius++;
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: Radii " + minXradius + "," + minYradius + "," + minZradius +
|
||||
// "," + maxXradius + "," + maxYradius + "," + maxZradius);
|
||||
} while (minXradius < i || maxXradius < i || minZradius < i || maxZradius < i || minYradius < depth
|
||||
|| maxYradius < height);
|
||||
// Nothing worked
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this location is safe for a player to teleport to. Used by
|
||||
* warps and boat exits Unsafe is any liquid or air and also if there's no
|
||||
* space
|
||||
*
|
||||
* @param l
|
||||
* - Location to be checked
|
||||
* @return true if safe, otherwise false
|
||||
*/
|
||||
public static boolean isSafeLocation(final Location l) {
|
||||
if (l == null) {
|
||||
return false;
|
||||
}
|
||||
// TODO: improve the safe location finding.
|
||||
//Bukkit.getLogger().info("DEBUG: " + l.toString());
|
||||
final Block ground = l.getBlock().getRelative(BlockFace.DOWN);
|
||||
final Block space1 = l.getBlock();
|
||||
final Block space2 = l.getBlock().getRelative(BlockFace.UP);
|
||||
//Bukkit.getLogger().info("DEBUG: ground = " + ground.getType());
|
||||
//Bukkit.getLogger().info("DEBUG: space 1 = " + space1.getType());
|
||||
//Bukkit.getLogger().info("DEBUG: space 2 = " + space2.getType());
|
||||
// Portals are not "safe"
|
||||
if (space1.getType() == Material.PORTAL || ground.getType() == Material.PORTAL || space2.getType() == Material.PORTAL
|
||||
|| space1.getType() == Material.ENDER_PORTAL || ground.getType() == Material.ENDER_PORTAL || space2.getType() == Material.ENDER_PORTAL) {
|
||||
return false;
|
||||
}
|
||||
// If ground is AIR, then this is either not good, or they are on slab,
|
||||
// stair, etc.
|
||||
if (ground.getType() == Material.AIR) {
|
||||
// Bukkit.getLogger().info("DEBUG: air");
|
||||
return false;
|
||||
}
|
||||
// In BSkyBlock, liquid may be unsafe
|
||||
if (ground.isLiquid() || space1.isLiquid() || space2.isLiquid()) {
|
||||
// Check if acid has no damage
|
||||
if (Settings.acidDamage > 0D) {
|
||||
// Bukkit.getLogger().info("DEBUG: acid");
|
||||
return false;
|
||||
} else if (ground.getType().equals(Material.STATIONARY_LAVA) || ground.getType().equals(Material.LAVA)
|
||||
|| space1.getType().equals(Material.STATIONARY_LAVA) || space1.getType().equals(Material.LAVA)
|
||||
|| space2.getType().equals(Material.STATIONARY_LAVA) || space2.getType().equals(Material.LAVA)) {
|
||||
// Lava check only
|
||||
// Bukkit.getLogger().info("DEBUG: lava");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MaterialData md = ground.getState().getData();
|
||||
if (md instanceof SimpleAttachableMaterialData) {
|
||||
//Bukkit.getLogger().info("DEBUG: trapdoor/button/tripwire hook etc.");
|
||||
if (md instanceof TrapDoor) {
|
||||
TrapDoor trapDoor = (TrapDoor)md;
|
||||
if (trapDoor.isOpen()) {
|
||||
//Bukkit.getLogger().info("DEBUG: trapdoor open");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
//Bukkit.getLogger().info("DEBUG: trapdoor closed");
|
||||
}
|
||||
if (ground.getType().equals(Material.CACTUS) || ground.getType().equals(Material.BOAT) || ground.getType().equals(Material.FENCE)
|
||||
|| ground.getType().equals(Material.NETHER_FENCE) || ground.getType().equals(Material.SIGN_POST) || ground.getType().equals(Material.WALL_SIGN)) {
|
||||
// Bukkit.getLogger().info("DEBUG: cactus");
|
||||
return false;
|
||||
}
|
||||
// Check that the space is not solid
|
||||
// The isSolid function is not fully accurate (yet) so we have to
|
||||
// check
|
||||
// a few other items
|
||||
// isSolid thinks that PLATEs and SIGNS are solid, but they are not
|
||||
if (space1.getType().isSolid() && !space1.getType().equals(Material.SIGN_POST) && !space1.getType().equals(Material.WALL_SIGN)) {
|
||||
return false;
|
||||
}
|
||||
if (space2.getType().isSolid()&& !space2.getType().equals(Material.SIGN_POST) && !space2.getType().equals(Material.WALL_SIGN)) {
|
||||
return false;
|
||||
}
|
||||
// Safe
|
||||
//Bukkit.getLogger().info("DEBUG: safe!");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an island using schematic. No permission checks are made. They have to be decided
|
||||
* before this method is called.
|
||||
* @param player
|
||||
* @param schematic
|
||||
*/
|
||||
public void newIsland(final Player player, final Schematic schematic) {
|
||||
//long time = System.nanoTime();
|
||||
final UUID playerUUID = player.getUniqueId();
|
||||
boolean firstTime = false;
|
||||
if (!plugin.getPlayers().hasIsland(playerUUID)) {
|
||||
firstTime = true;
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: finding island location");
|
||||
Location next = getNextIsland(player.getUniqueId());
|
||||
//plugin.getLogger().info("DEBUG: found " + next);
|
||||
// Clear any old home locations (they should be clear, but just in case)
|
||||
plugin.getPlayers().clearHomeLocations(playerUUID);
|
||||
|
||||
// Set the biome
|
||||
//BiomesPanel.setIslandBiome(next, schematic.getBiome());
|
||||
// Teleport to the new home
|
||||
if (schematic.isPlayerSpawn()) {
|
||||
// Set home and teleport
|
||||
plugin.getPlayers().setHomeLocation(playerUUID, schematic.getPlayerSpawn(next), 1);
|
||||
}
|
||||
|
||||
// Create island based on schematic
|
||||
if (schematic != null) {
|
||||
//plugin.getLogger().info("DEBUG: pasting schematic " + schematic.getName() + " " + schematic.getPerm());
|
||||
//plugin.getLogger().info("DEBUG: nether world is " + BSkyBlock.getNetherWorld());
|
||||
// Paste the starting island. If it is a HELL biome, then we start in the Nether
|
||||
if (Settings.createNether && schematic.isInNether() && Settings.islandNether && IslandWorld.getNetherWorld() != null) {
|
||||
// Nether start
|
||||
// Paste the overworld if it exists
|
||||
if (!schematic.getPartnerName().isEmpty()) {
|
||||
// A partner schematic is available
|
||||
pastePartner(plugin.getSchematics().getSchematic(schematic.getPartnerName()),next, player);
|
||||
}
|
||||
// Switch home location to the Nether
|
||||
next = next.toVector().toLocation(IslandWorld.getNetherWorld());
|
||||
// Set the player's island location to this new spot
|
||||
//plugin.getPlayers().setIslandLocation(playerUUID, next);
|
||||
schematic.pasteSchematic(next, player, true, firstTime ? PasteReason.NEW_ISLAND: PasteReason.RESET);
|
||||
} else {
|
||||
// Over world start
|
||||
//plugin.getLogger().info("DEBUG: pasting");
|
||||
//long timer = System.nanoTime();
|
||||
// Paste the island and teleport the player home
|
||||
schematic.pasteSchematic(next, player, true, firstTime ? PasteReason.NEW_ISLAND: PasteReason.RESET);
|
||||
//double diff = (System.nanoTime() - timer)/1000000;
|
||||
//plugin.getLogger().info("DEBUG: nano time = " + diff + " ms");
|
||||
//plugin.getLogger().info("DEBUG: pasted overworld");
|
||||
if (Settings.createNether && Settings.islandNether && IslandWorld.getNetherWorld() != null) {
|
||||
// Paste the other world schematic
|
||||
final Location netherLoc = next.toVector().toLocation(IslandWorld.getNetherWorld());
|
||||
if (schematic.getPartnerName().isEmpty()) {
|
||||
// This will paste the over world schematic again
|
||||
//plugin.getLogger().info("DEBUG: pasting nether");
|
||||
pastePartner(schematic, netherLoc, player);
|
||||
//plugin.getLogger().info("DEBUG: pasted nether");
|
||||
} else {
|
||||
if (plugin.getSchematics().getAll().containsKey(schematic.getPartnerName())) {
|
||||
//plugin.getLogger().info("DEBUG: pasting partner");
|
||||
// A partner schematic is available
|
||||
pastePartner(plugin.getSchematics().getAll().get(schematic.getPartnerName()),netherLoc, player);
|
||||
} else {
|
||||
plugin.getLogger().severe("Partner schematic heading '" + schematic.getPartnerName() + "' does not exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add to the grid
|
||||
Island myIsland = plugin.getIslands().createIsland(next, playerUUID);
|
||||
myIsland.setLevelHandicap(schematic.getLevelHandicap());
|
||||
// Save the player so that if the server is reset weird things won't happen
|
||||
plugin.getPlayers().save(true);
|
||||
|
||||
// Start the reset cooldown
|
||||
//if (!firstTime) {
|
||||
// setResetWaitTime(player);
|
||||
//}
|
||||
// Set the custom protection range if appropriate
|
||||
// Dynamic island range sizes with permissions
|
||||
int range = Settings.islandProtectionRange;
|
||||
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
|
||||
if (perms.getPermission().startsWith(Settings.PERMPREFIX + "island.range.")) {
|
||||
if (perms.getPermission().contains(Settings.PERMPREFIX + "island.range.*")) {
|
||||
range = Settings.islandProtectionRange;
|
||||
break;
|
||||
} else {
|
||||
String[] spl = perms.getPermission().split(Settings.PERMPREFIX + "island.range.");
|
||||
if (spl.length > 1) {
|
||||
if (!NumberUtils.isDigits(spl[1])) {
|
||||
plugin.getLogger().severe("Player " + player.getName() + " has permission: " + perms.getPermission() + " <-- the last part MUST be a number! Ignoring...");
|
||||
} else {
|
||||
range = Math.max(range, Integer.valueOf(spl[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do some sanity checking
|
||||
if (range % 2 != 0) {
|
||||
range--;
|
||||
plugin.getLogger().warning("Protection range must be even, using " + range + " for " + player.getName());
|
||||
}
|
||||
if (range > Settings.islandDistance) {
|
||||
plugin.getLogger().warning("Player has " + Settings.PERMPREFIX + "island.range." + range);
|
||||
range = Settings.islandDistance;
|
||||
plugin.getLogger().warning(
|
||||
"Island protection range must be " + Settings.islandDistance + " or less. Setting to: " + range);
|
||||
}
|
||||
myIsland.setProtectionRange(range);
|
||||
|
||||
// Save grid just in case there's a crash
|
||||
plugin.getIslands().save(true);
|
||||
// Done - fire event
|
||||
//final IslandNewEvent event = new IslandNewEvent(player,schematic, myIsland);
|
||||
//plugin.getServer().getPluginManager().callEvent(event);
|
||||
//plugin.getLogger().info("DEBUG: Done! " + (System.nanoTime()- time) * 0.000001);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a delayed pasting of the partner island
|
||||
* @param schematic
|
||||
* @param player
|
||||
*/
|
||||
private void pastePartner(final Schematic schematic, final Location loc, final Player player) {
|
||||
plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
schematic.pasteSchematic(loc, player, false, PasteReason.PARTNER);
|
||||
|
||||
}}, 60L);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of next free island spot
|
||||
* @param playerUUID
|
||||
* @return Location of island spot
|
||||
*/
|
||||
private Location getNextIsland(UUID playerUUID) {
|
||||
// Find the next free spot
|
||||
if (last == null) {
|
||||
last = new Location(IslandWorld.getIslandWorld(), Settings.islandXOffset + Settings.islandStartX, Settings.islandHeight, Settings.islandZOffset + Settings.islandStartZ);
|
||||
}
|
||||
Location next = last.clone();
|
||||
|
||||
while (plugin.getIslands().isIsland(next)) {
|
||||
next = nextGridLocation(next);
|
||||
}
|
||||
// Make the last next, last
|
||||
last = next.clone();
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the next free island spot based off the last known island Uses
|
||||
* island_distance setting from the config file Builds up in a grid fashion
|
||||
*
|
||||
* @param lastIsland
|
||||
* @return Location of next free island
|
||||
*/
|
||||
private Location nextGridLocation(final Location lastIsland) {
|
||||
// plugin.getLogger().info("DEBUG nextIslandLocation");
|
||||
final int x = lastIsland.getBlockX();
|
||||
final int z = lastIsland.getBlockZ();
|
||||
final Location nextPos = lastIsland;
|
||||
if (x < z) {
|
||||
if (-1 * x < z) {
|
||||
nextPos.setX(nextPos.getX() + Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
nextPos.setZ(nextPos.getZ() + Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
if (x > z) {
|
||||
if (-1 * x >= z) {
|
||||
nextPos.setX(nextPos.getX() - Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
nextPos.setZ(nextPos.getZ() - Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
if (x <= 0) {
|
||||
nextPos.setZ(nextPos.getZ() + Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
nextPos.setZ(nextPos.getZ() - Settings.islandDistance);
|
||||
return nextPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package us.tastybento.bskyblock.database.managers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Location;
|
||||
@ -19,6 +21,7 @@ public class PlayersManager{
|
||||
private BSBDatabase database;
|
||||
|
||||
private HashMap<UUID, Players> playerCache;
|
||||
private Set<UUID> inTeleport;
|
||||
|
||||
/**
|
||||
* Provides a memory cache of online player information
|
||||
@ -31,6 +34,7 @@ public class PlayersManager{
|
||||
this.plugin = plugin;
|
||||
database = BSBDatabase.getDatabase();
|
||||
playerCache = new HashMap<UUID, Players>();
|
||||
inTeleport = new HashSet<UUID>();
|
||||
}
|
||||
|
||||
public void load(){
|
||||
@ -488,4 +492,38 @@ public class PlayersManager{
|
||||
return playerCache.get(playerUUID).getDeaths();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if a player is mid-teleport or not
|
||||
* @param uniqueId
|
||||
*/
|
||||
public void setInTeleport(UUID uniqueId) {
|
||||
inTeleport.add(uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes player from in-teleport
|
||||
* @param uniqueId
|
||||
*/
|
||||
public void removeInTeleport(UUID uniqueId) {
|
||||
inTeleport.remove(uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uniqueId
|
||||
* @return true if a player is mid-teleport
|
||||
*/
|
||||
public boolean isInTeleport(UUID uniqueId) {
|
||||
return inTeleport.contains(uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets everything to do with a player that needs to be reset
|
||||
* @param player
|
||||
*/
|
||||
public void resetPlayer(Player player) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -349,6 +349,8 @@ public class Island extends DataObject {
|
||||
//// Protection ////
|
||||
private HashMap<SettingsFlag, Boolean> flags = new HashMap<SettingsFlag, Boolean>();
|
||||
|
||||
private int levelHandicap;
|
||||
|
||||
public Island() {};
|
||||
|
||||
public Island(Location location, UUID owner, int protectionRange) {
|
||||
@ -817,4 +819,18 @@ public class Island extends DataObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the levelHandicap
|
||||
*/
|
||||
public int getLevelHandicap() {
|
||||
return levelHandicap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param levelHandicap the levelHandicap to set
|
||||
*/
|
||||
public void setLevelHandicap(int levelHandicap) {
|
||||
this.levelHandicap = levelHandicap;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of ASkyBlock.
|
||||
*
|
||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ASkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.banner.Pattern;
|
||||
import org.bukkit.block.banner.PatternType;
|
||||
|
||||
import us.tastybento.org.jnbt.CompoundTag;
|
||||
import us.tastybento.org.jnbt.IntTag;
|
||||
import us.tastybento.org.jnbt.ListTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* This class describes banners and is used in schematic importing
|
||||
*
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class BannerBlock {
|
||||
private DyeColor bannerBaseColor;
|
||||
private List<Pattern> bannerPattern;
|
||||
|
||||
private static HashMap<String, PatternType> patternKey;
|
||||
// bs, mc, cr, drs, dls, hhb, mr, hh, sc, gru, ss, gra, ts, ms, tt
|
||||
// bts, tr, tts, sku, cre, tl, vhr, vh, bo, cbo, bri
|
||||
|
||||
// ss, tt
|
||||
static {
|
||||
patternKey = new HashMap<String, PatternType>();
|
||||
patternKey.put("", PatternType.BASE);
|
||||
patternKey.put("bo", PatternType.BORDER);
|
||||
patternKey.put("bri", PatternType.BRICKS);
|
||||
patternKey.put("mc", PatternType.CIRCLE_MIDDLE);
|
||||
patternKey.put("cre", PatternType.CREEPER);
|
||||
patternKey.put("cr", PatternType.CROSS);
|
||||
patternKey.put("cbo", PatternType.CURLY_BORDER);
|
||||
patternKey.put("ld", PatternType.DIAGONAL_LEFT);
|
||||
patternKey.put("lud", PatternType.DIAGONAL_LEFT_MIRROR);
|
||||
patternKey.put("rd", PatternType.DIAGONAL_RIGHT);
|
||||
patternKey.put("rud", PatternType.DIAGONAL_RIGHT_MIRROR);
|
||||
patternKey.put("flo", PatternType.FLOWER);
|
||||
patternKey.put("gra", PatternType.GRADIENT);
|
||||
patternKey.put("gru", PatternType.GRADIENT_UP);
|
||||
patternKey.put("hh", PatternType.HALF_HORIZONTAL);
|
||||
patternKey.put("hhb", PatternType.HALF_HORIZONTAL_MIRROR);
|
||||
patternKey.put("vh", PatternType.HALF_VERTICAL);
|
||||
patternKey.put("vhr", PatternType.HALF_VERTICAL_MIRROR);
|
||||
patternKey.put("moj", PatternType.MOJANG);
|
||||
patternKey.put("mr", PatternType.RHOMBUS_MIDDLE);
|
||||
patternKey.put("sku", PatternType.SKULL);
|
||||
patternKey.put("bl", PatternType.SQUARE_BOTTOM_LEFT);
|
||||
patternKey.put("br", PatternType.SQUARE_BOTTOM_RIGHT);
|
||||
patternKey.put("tl", PatternType.SQUARE_TOP_LEFT);
|
||||
patternKey.put("tr", PatternType.SQUARE_TOP_RIGHT);
|
||||
patternKey.put("sc", PatternType.STRAIGHT_CROSS);
|
||||
patternKey.put("bs", PatternType.STRIPE_BOTTOM);
|
||||
patternKey.put("ms", PatternType.STRIPE_CENTER);
|
||||
patternKey.put("dls", PatternType.STRIPE_DOWNLEFT);
|
||||
patternKey.put("drs", PatternType.STRIPE_DOWNRIGHT);
|
||||
patternKey.put("ls", PatternType.STRIPE_LEFT);
|
||||
patternKey.put("ms", PatternType.STRIPE_MIDDLE);
|
||||
patternKey.put("rs", PatternType.STRIPE_RIGHT);
|
||||
patternKey.put("ss", PatternType.STRIPE_SMALL);
|
||||
patternKey.put("ts", PatternType.STRIPE_TOP);
|
||||
patternKey.put("bt", PatternType.TRIANGLE_BOTTOM);
|
||||
patternKey.put("tt", PatternType.TRIANGLE_TOP);
|
||||
patternKey.put("bts", PatternType.TRIANGLES_BOTTOM);
|
||||
patternKey.put("tts", PatternType.TRIANGLES_TOP);
|
||||
}
|
||||
|
||||
public boolean set(Block block) {
|
||||
Banner banner = (Banner) block.getState();
|
||||
banner.setBaseColor(bannerBaseColor);
|
||||
banner.setPatterns(bannerPattern);
|
||||
banner.update();
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean prep(Map<String, Tag> tileData) {
|
||||
// Format for banner is:
|
||||
// Patterns = List of patterns
|
||||
// id = String "BannerBlock"
|
||||
// Base = Int color
|
||||
// Then the location
|
||||
// z = Int
|
||||
// y = Int
|
||||
// x = Int
|
||||
try {
|
||||
// Do the base color
|
||||
int baseColor = 15 - ((IntTag) tileData.get("Base")).getValue();
|
||||
// //ASkyBlock.getPlugin().getLogger().info("Base value = " +
|
||||
// baseColor);
|
||||
// baseColor green = 10
|
||||
bannerBaseColor = DyeColor.getByDyeData((byte) baseColor);
|
||||
// Do the patterns (no idea if this will work or not)
|
||||
bannerPattern = new ArrayList<Pattern>();
|
||||
ListTag patterns = (ListTag) tileData.get("Patterns");
|
||||
if (patterns != null) {
|
||||
for (Tag pattern : patterns.getValue()) {
|
||||
// ASkyBlock.getPlugin().getLogger().info("pattern = " +
|
||||
// pattern);
|
||||
// Translate pattern to PatternType
|
||||
if (pattern instanceof CompoundTag) {
|
||||
CompoundTag patternColor = (CompoundTag) pattern;
|
||||
// The tag is made up of pattern (String) and color
|
||||
// (int)
|
||||
Map<String, Tag> patternValue = patternColor.getValue();
|
||||
StringTag mark = (StringTag) patternValue.get("Pattern");
|
||||
Integer markColor = 15 - ((IntTag) patternValue.get("Color")).getValue();
|
||||
// ASkyBlock.getPlugin().getLogger().info("mark = " +
|
||||
// mark.getValue());
|
||||
// ASkyBlock.getPlugin().getLogger().info("color = " +
|
||||
// markColor);
|
||||
DyeColor dColor = DyeColor.getByDyeData(markColor.byteValue());
|
||||
// ASkyBlock.getPlugin().getLogger().info(" dye color = "
|
||||
// + dColor.toString());
|
||||
if (patternKey.containsKey(mark.getValue())) {
|
||||
Pattern newPattern = new Pattern(dColor, patternKey.get(mark.getValue()));
|
||||
bannerPattern.add(newPattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,364 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of ASkyBlock.
|
||||
*
|
||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ASkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.util.BlockVector;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class EntityObject {
|
||||
private EntityType type;
|
||||
private BlockVector location;
|
||||
private byte color;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
private boolean sheared;
|
||||
private Vector motion;
|
||||
private int age;
|
||||
private int rabbitType;
|
||||
private int catType;
|
||||
private boolean sitting;
|
||||
private int profession;
|
||||
private boolean carryingChest;
|
||||
private boolean owned;
|
||||
private byte collarColor;
|
||||
// Paintings
|
||||
private byte facing;
|
||||
private String motive;
|
||||
// Item Frames
|
||||
private float itemDropChance;
|
||||
private byte itemRotation;
|
||||
// Coordinates for tiles
|
||||
private Double tileX = null;
|
||||
private Double tileY = null;
|
||||
private Double tileZ = null;
|
||||
// Items informations
|
||||
private Byte count = null;
|
||||
private Short damage = null;
|
||||
private String id = null;
|
||||
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EntityType type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* @return the location
|
||||
*/
|
||||
public BlockVector getLocation() {
|
||||
return location;
|
||||
}
|
||||
/**
|
||||
* @param location the location to set
|
||||
*/
|
||||
public void setLocation(BlockVector location) {
|
||||
this.location = location;
|
||||
}
|
||||
/**
|
||||
* @return the color
|
||||
*/
|
||||
public byte getColor() {
|
||||
return color;
|
||||
}
|
||||
/**
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setColor(byte color) {
|
||||
this.color = color;
|
||||
}
|
||||
/**
|
||||
* @return the yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
/**
|
||||
* @param yaw the yaw to set
|
||||
*/
|
||||
public void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pitch
|
||||
*/
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
/**
|
||||
* @return the sheared
|
||||
*/
|
||||
public boolean isSheared() {
|
||||
return sheared;
|
||||
}
|
||||
/**
|
||||
* @param sheared the sheared to set
|
||||
*/
|
||||
public void setSheared(boolean sheared) {
|
||||
this.sheared = sheared;
|
||||
}
|
||||
/**
|
||||
* @return the motion
|
||||
*/
|
||||
public Vector getMotion() {
|
||||
return motion;
|
||||
}
|
||||
/**
|
||||
* @param motion the motion to set
|
||||
*/
|
||||
public void setMotion(Vector motion) {
|
||||
this.motion = motion;
|
||||
}
|
||||
/**
|
||||
* @return the age
|
||||
*/
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
/**
|
||||
* @param age the age to set
|
||||
*/
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
/**
|
||||
* @return the profession
|
||||
*/
|
||||
public int getProfession() {
|
||||
return profession;
|
||||
}
|
||||
/**
|
||||
* @param profession the profession to set
|
||||
*/
|
||||
public void setProfession(int profession) {
|
||||
this.profession = profession;
|
||||
}
|
||||
/**
|
||||
* @return the rabbitType
|
||||
*/
|
||||
public int getRabbitType() {
|
||||
return rabbitType;
|
||||
}
|
||||
/**
|
||||
* @param rabbitType the rabbitType to set
|
||||
*/
|
||||
public void setRabbitType(int rabbitType) {
|
||||
this.rabbitType = rabbitType;
|
||||
}
|
||||
/**
|
||||
* @return the carryingChest
|
||||
*/
|
||||
public boolean isCarryingChest() {
|
||||
return carryingChest;
|
||||
}
|
||||
/**
|
||||
* @param carryingChest the carryingChest to set
|
||||
*/
|
||||
public void setCarryingChest(byte carryingChest) {
|
||||
if (carryingChest > (byte)0) {
|
||||
this.carryingChest = true;
|
||||
}
|
||||
this.carryingChest = false;
|
||||
}
|
||||
/**
|
||||
* @return the catType
|
||||
*/
|
||||
public int getCatType() {
|
||||
return catType;
|
||||
}
|
||||
/**
|
||||
* @param catType the catType to set
|
||||
*/
|
||||
public void setCatType(int catType) {
|
||||
this.catType = catType;
|
||||
}
|
||||
/**
|
||||
* @return the sitting
|
||||
*/
|
||||
public boolean isSitting() {
|
||||
return sitting;
|
||||
}
|
||||
/**
|
||||
* @param sitting the sitting to set
|
||||
*/
|
||||
public void setSitting(byte sitting) {
|
||||
if (sitting > (byte)0) {
|
||||
this.sitting = true;
|
||||
}
|
||||
this.sitting = false;
|
||||
}
|
||||
/**
|
||||
* @return the owned
|
||||
*/
|
||||
public boolean isOwned() {
|
||||
return owned;
|
||||
}
|
||||
/**
|
||||
* @param owned the owned to set
|
||||
*/
|
||||
public void setOwned(boolean owned) {
|
||||
this.owned = owned;
|
||||
}
|
||||
/**
|
||||
* @return the collarColor
|
||||
*/
|
||||
public byte getCollarColor() {
|
||||
return collarColor;
|
||||
}
|
||||
/**
|
||||
* @param collarColor the collarColor to set
|
||||
*/
|
||||
public void setCollarColor(byte collarColor) {
|
||||
this.collarColor = collarColor;
|
||||
}
|
||||
/**
|
||||
* @return the facing
|
||||
*/
|
||||
public byte getFacing() {
|
||||
return facing;
|
||||
}
|
||||
/**
|
||||
* @param facing the facing to set
|
||||
*/
|
||||
public void setFacing(byte facing) {
|
||||
this.facing = facing;
|
||||
}
|
||||
/**
|
||||
* @return the motive
|
||||
*/
|
||||
public String getMotive() {
|
||||
return motive;
|
||||
}
|
||||
/**
|
||||
* @param motive the motive to set
|
||||
*/
|
||||
public void setMotive(String motive) {
|
||||
this.motive = motive;
|
||||
}
|
||||
/**
|
||||
* @return the itemDropChance
|
||||
*/
|
||||
public float getItemDropChance() {
|
||||
return itemDropChance;
|
||||
}
|
||||
/**
|
||||
* @param itemDropChance the itemDropChance to set
|
||||
*/
|
||||
public void setItemDropChance(float itemDropChance) {
|
||||
this.itemDropChance = itemDropChance;
|
||||
}
|
||||
/**
|
||||
* @return the itemRotation
|
||||
*/
|
||||
public byte getItemRotation() {
|
||||
return itemRotation;
|
||||
}
|
||||
/**
|
||||
* @param itemRotation the itemRotation to set
|
||||
*/
|
||||
public void setItemRotation(byte itemRotation) {
|
||||
this.itemRotation = itemRotation;
|
||||
}
|
||||
/**
|
||||
* @return the tileX
|
||||
*/
|
||||
public Double getTileX() {
|
||||
return tileX;
|
||||
}
|
||||
/**
|
||||
* @param tileX the tileX to set
|
||||
*/
|
||||
public void setTileX(Double tileX) {
|
||||
this.tileX = tileX;
|
||||
}
|
||||
/**
|
||||
* @return the tileX
|
||||
*/
|
||||
public Double getTileY() {
|
||||
return tileY;
|
||||
}
|
||||
/**
|
||||
* @param tileY the tileY to set
|
||||
*/
|
||||
public void setTileY(Double tileY) {
|
||||
this.tileY = tileY;
|
||||
}
|
||||
/**
|
||||
* @return the tileX
|
||||
*/
|
||||
public Double getTileZ() {
|
||||
return tileZ;
|
||||
}
|
||||
/**
|
||||
* @param tileZ the tileZ to set
|
||||
*/
|
||||
public void setTileZ(Double tileZ) {
|
||||
this.tileZ = tileZ;
|
||||
}
|
||||
/**
|
||||
* @return the count
|
||||
*/
|
||||
public Byte getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param count the count to set
|
||||
*/
|
||||
public void setCount(Byte count) {
|
||||
this.count = count;
|
||||
}
|
||||
/**
|
||||
* @return the damage
|
||||
*/
|
||||
public Short getDamage() {
|
||||
return damage;
|
||||
}
|
||||
/**
|
||||
* @param damage the damage to set
|
||||
*/
|
||||
public void setDamage(Short damage) {
|
||||
this.damage = damage;
|
||||
}
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -0,0 +1,600 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of ASkyBlock.
|
||||
*
|
||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ASkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ContainerFactory;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
import us.tastybento.org.jnbt.CompoundTag;
|
||||
import us.tastybento.org.jnbt.ListTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
public class IslandBlock {
|
||||
private short typeId;
|
||||
private byte data;
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private List<String> signText;
|
||||
private BannerBlock banner;
|
||||
private SkullBlock skull;
|
||||
private PotBlock pot;
|
||||
private EntityType spawnerBlockType;
|
||||
// Chest contents
|
||||
private HashMap<Byte,ItemStack> chestContents = new HashMap<Byte,ItemStack>();
|
||||
public static final HashMap<String, Material> WEtoM = new HashMap<String, Material>();
|
||||
public static final HashMap<String, EntityType> WEtoME = new HashMap<String, EntityType>();
|
||||
|
||||
static {
|
||||
// Establish the World Edit to Material look up
|
||||
// V1.8 items
|
||||
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
|
||||
|
||||
WEtoM.put("ARMORSTAND",Material.ARMOR_STAND);
|
||||
WEtoM.put("ACACIA_DOOR",Material.ACACIA_DOOR_ITEM);
|
||||
WEtoM.put("BIRCH_DOOR",Material.BIRCH_DOOR_ITEM);
|
||||
WEtoM.put("BIRCH_STAIRS",Material.BIRCH_WOOD_STAIRS);
|
||||
WEtoM.put("DARK_OAK_DOOR",Material.DARK_OAK_DOOR_ITEM);
|
||||
WEtoM.put("JUNGLE_DOOR",Material.JUNGLE_DOOR_ITEM);
|
||||
WEtoM.put("SLIME",Material.SLIME_BLOCK);
|
||||
WEtoM.put("SPRUCE_DOOR",Material.SPRUCE_DOOR_ITEM);
|
||||
}
|
||||
WEtoM.put("BREWING_STAND",Material.BREWING_STAND_ITEM);
|
||||
WEtoM.put("CARROT_ON_A_STICK",Material.CARROT_STICK);
|
||||
WEtoM.put("CARROT",Material.CARROT_ITEM);
|
||||
WEtoM.put("CAULDRON", Material.CAULDRON_ITEM);
|
||||
WEtoM.put("CLOCK", Material.WATCH);
|
||||
WEtoM.put("COBBLESTONE_WALL",Material.COBBLE_WALL);
|
||||
WEtoM.put("COMMAND_BLOCK",Material.COMMAND);
|
||||
WEtoM.put("COMMANDBLOCK_MINECART",Material.COMMAND_MINECART);
|
||||
WEtoM.put("COMPARATOR",Material.REDSTONE_COMPARATOR);
|
||||
WEtoM.put("COOKED_PORKCHOP", Material.GRILLED_PORK);
|
||||
WEtoM.put("CLOCK", Material.WATCH);
|
||||
WEtoM.put("CRAFTING_TABLE", Material.WORKBENCH);
|
||||
WEtoM.put("DIAMOND_HORSE_ARMOR",Material.DIAMOND_BARDING);
|
||||
WEtoM.put("DIAMOND_SHOVEL",Material.DIAMOND_SPADE);
|
||||
WEtoM.put("DYE",Material.INK_SACK);
|
||||
WEtoM.put("ENCHANTING_TABLE", Material.ENCHANTMENT_TABLE); //1.11 rename
|
||||
WEtoM.put("END_PORTAL_FRAME",Material.ENDER_PORTAL_FRAME);
|
||||
WEtoM.put("END_PORTAL", Material.ENDER_PORTAL); // 1.11 rename
|
||||
WEtoM.put("END_STONE", Material.ENDER_STONE);
|
||||
WEtoM.put("EXPERIENCE_BOTTLE",Material.EXP_BOTTLE);
|
||||
WEtoM.put("FILLED_MAP",Material.MAP);
|
||||
WEtoM.put("FIRE_CHARGE",Material.FIREBALL);
|
||||
WEtoM.put("FIREWORKS",Material.FIREWORK);
|
||||
WEtoM.put("FLOWER_POT", Material.FLOWER_POT_ITEM);
|
||||
WEtoM.put("GLASS_PANE",Material.THIN_GLASS);
|
||||
WEtoM.put("GOLDEN_CHESTPLATE",Material.GOLD_CHESTPLATE);
|
||||
WEtoM.put("GOLDEN_HORSE_ARMOR",Material.GOLD_BARDING);
|
||||
WEtoM.put("GOLDEN_LEGGINGS",Material.GOLD_LEGGINGS);
|
||||
WEtoM.put("GOLDEN_PICKAXE",Material.GOLD_PICKAXE);
|
||||
WEtoM.put("GOLDEN_RAIL",Material.POWERED_RAIL);
|
||||
WEtoM.put("GOLDEN_SHOVEL",Material.GOLD_SPADE);
|
||||
WEtoM.put("GOLDEN_SWORD", Material.GOLD_SWORD);
|
||||
WEtoM.put("GOLDEN_HELMET", Material.GOLD_HELMET);
|
||||
WEtoM.put("GOLDEN_HOE", Material.GOLD_HOE);
|
||||
WEtoM.put("GOLDEN_AXE", Material.GOLD_AXE);
|
||||
WEtoM.put("GOLDEN_BOOTS", Material.GOLD_BOOTS);
|
||||
WEtoM.put("GUNPOWDER", Material.SULPHUR);
|
||||
WEtoM.put("HARDENED_CLAY",Material.HARD_CLAY);
|
||||
WEtoM.put("HEAVY_WEIGHTED_PRESSURE_PLATE",Material.GOLD_PLATE);
|
||||
WEtoM.put("IRON_BARS",Material.IRON_FENCE);
|
||||
WEtoM.put("IRON_HORSE_ARMOR",Material.IRON_BARDING);
|
||||
WEtoM.put("IRON_SHOVEL",Material.IRON_SPADE);
|
||||
WEtoM.put("LEAD",Material.LEASH);
|
||||
WEtoM.put("LEAVES2",Material.LEAVES_2);
|
||||
WEtoM.put("LIGHT_WEIGHTED_PRESSURE_PLATE",Material.IRON_PLATE);
|
||||
WEtoM.put("LOG2",Material.LOG_2);
|
||||
WEtoM.put("MAP",Material.EMPTY_MAP);
|
||||
WEtoM.put("MYCELIUM", Material.MYCEL);
|
||||
WEtoM.put("NETHER_BRICK_FENCE",Material.NETHER_FENCE);
|
||||
WEtoM.put("NETHER_WART",Material.NETHER_STALK);
|
||||
WEtoM.put("NETHERBRICK",Material.NETHER_BRICK_ITEM);
|
||||
WEtoM.put("OAK_STAIRS",Material.WOOD_STAIRS);
|
||||
WEtoM.put("POTATO", Material.POTATO_ITEM);
|
||||
WEtoM.put("RAIL",Material.RAILS);
|
||||
WEtoM.put("RECORD_11",Material.RECORD_11);
|
||||
WEtoM.put("RECORD_13",Material.GOLD_RECORD);
|
||||
WEtoM.put("RECORD_BLOCKS",Material.RECORD_3);
|
||||
WEtoM.put("RECORD_CAT",Material.GREEN_RECORD);
|
||||
WEtoM.put("RECORD_CHIRP",Material.RECORD_4);
|
||||
WEtoM.put("RECORD_FAR",Material.RECORD_5);
|
||||
WEtoM.put("RECORD_MALL",Material.RECORD_6);
|
||||
WEtoM.put("RECORD_MELLOHI",Material.RECORD_7);
|
||||
WEtoM.put("RECORD_STAL",Material.RECORD_8);
|
||||
WEtoM.put("RECORD_STRAD",Material.RECORD_9);
|
||||
WEtoM.put("RECORD_WAIT",Material.RECORD_12);
|
||||
WEtoM.put("RECORD_WARD",Material.RECORD_10);
|
||||
WEtoM.put("RED_FLOWER",Material.RED_ROSE);
|
||||
WEtoM.put("REEDS",Material.SUGAR_CANE);
|
||||
WEtoM.put("REPEATER",Material.DIODE);
|
||||
WEtoM.put("SKULL", Material.SKULL_ITEM);
|
||||
WEtoM.put("SPAWN_EGG",Material.MONSTER_EGG);
|
||||
WEtoM.put("STONE_BRICK_STAIRS",Material.BRICK_STAIRS);
|
||||
WEtoM.put("STONE_BRICK_STAIRS",Material.SMOOTH_STAIRS);
|
||||
WEtoM.put("STONE_SHOVEL",Material.STONE_SPADE);
|
||||
WEtoM.put("STONE_SLAB",Material.STEP);
|
||||
WEtoM.put("STONE_STAIRS",Material.COBBLESTONE_STAIRS);
|
||||
WEtoM.put("TNT_MINECART",Material.EXPLOSIVE_MINECART);
|
||||
WEtoM.put("WATERLILY",Material.WATER_LILY);
|
||||
WEtoM.put("WHEAT_SEEDS", Material.SEEDS);
|
||||
WEtoM.put("WOODEN_AXE",Material.WOOD_AXE);
|
||||
WEtoM.put("WOODEN_BUTTON",Material.WOOD_BUTTON);
|
||||
WEtoM.put("WOODEN_DOOR",Material.WOOD_DOOR);
|
||||
WEtoM.put("WOODEN_HOE",Material.WOOD_HOE);
|
||||
WEtoM.put("WOODEN_PICKAXE",Material.WOOD_PICKAXE);
|
||||
WEtoM.put("WOODEN_PRESSURE_PLATE",Material.WOOD_PLATE);
|
||||
WEtoM.put("WOODEN_SHOVEL",Material.WOOD_SPADE);
|
||||
WEtoM.put("WOODEN_SLAB",Material.WOOD_STEP);
|
||||
WEtoM.put("WOODEN_SWORD",Material.WOOD_SWORD);
|
||||
WEtoM.put("MUSHROOM_STEW",Material.MUSHROOM_SOUP);
|
||||
// Entities
|
||||
WEtoME.put("LAVASLIME", EntityType.MAGMA_CUBE);
|
||||
WEtoME.put("ENTITYHORSE", EntityType.HORSE);
|
||||
WEtoME.put("OZELOT", EntityType.OCELOT);
|
||||
WEtoME.put("MUSHROOMCOW", EntityType.MUSHROOM_COW);
|
||||
WEtoME.put("MOOSHROOM", EntityType.MUSHROOM_COW); // 1.11 rename
|
||||
WEtoME.put("PIGZOMBIE", EntityType.PIG_ZOMBIE);
|
||||
WEtoME.put("ZOMBIE_PIGMAN", EntityType.PIG_ZOMBIE); // 1.11 rename
|
||||
WEtoME.put("CAVESPIDER", EntityType.CAVE_SPIDER);
|
||||
WEtoME.put("XPORB", EntityType.EXPERIENCE_ORB);
|
||||
WEtoME.put("XP_ORB", EntityType.EXPERIENCE_ORB); // 1.11 rename
|
||||
WEtoME.put("MINECARTRIDEABLE", EntityType.MINECART);
|
||||
WEtoME.put("MINECARTHOPPER", EntityType.MINECART_HOPPER);
|
||||
WEtoME.put("HOPPER_MINECART", EntityType.MINECART_HOPPER);
|
||||
WEtoME.put("MINECARTFURNACE", EntityType.MINECART_FURNACE);
|
||||
WEtoME.put("FURNACE_MINECART", EntityType.MINECART_FURNACE);
|
||||
WEtoME.put("MINECARTMOBSPAWNER", EntityType.MINECART_MOB_SPAWNER);
|
||||
WEtoME.put("SPAWNER_MINECART", EntityType.MINECART_MOB_SPAWNER); // 1.11 rename
|
||||
WEtoME.put("MINECARTTNT", EntityType.MINECART_TNT);
|
||||
WEtoME.put("TNT_MINECART", EntityType.MINECART_TNT); // 1.11
|
||||
WEtoME.put("LEASH_KNOT",EntityType.LEASH_HITCH); // 1.11
|
||||
WEtoME.put("MINECARTCHEST", EntityType.MINECART_CHEST);
|
||||
WEtoME.put("CHEST_MINECART", EntityType.MINECART_CHEST); //1.11 rename
|
||||
WEtoME.put("VILLAGERGOLEM", EntityType.IRON_GOLEM);
|
||||
WEtoME.put("ENDERDRAGON", EntityType.ENDER_DRAGON);
|
||||
WEtoME.put("PAINTING", EntityType.PAINTING);
|
||||
WEtoME.put("ITEMFRAME", EntityType.ITEM_FRAME);
|
||||
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7")) {
|
||||
WEtoME.put("ENDERCRYSTAL", EntityType.ENDER_CRYSTAL);
|
||||
WEtoME.put("ARMORSTAND", EntityType.ARMOR_STAND);
|
||||
}
|
||||
// 1.10 entities and materials
|
||||
if (!Bukkit.getServer().getVersion().contains("(MC: 1.7") && !Bukkit.getServer().getVersion().contains("(MC: 1.8") && !Bukkit.getServer().getVersion().contains("(MC: 1.9")) {
|
||||
WEtoME.put("POLARBEAR", EntityType.POLAR_BEAR);
|
||||
WEtoM.put("ENDER_CRYSTAL", Material.END_CRYSTAL); // 1.11
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public IslandBlock(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
signText = null;
|
||||
banner = null;
|
||||
skull = null;
|
||||
pot = null;
|
||||
spawnerBlockType = null;
|
||||
chestContents = new HashMap<Byte,ItemStack>();
|
||||
}
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public int getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setTypeId(short type) {
|
||||
this.typeId = type;
|
||||
}
|
||||
/**
|
||||
* @return the data
|
||||
*/
|
||||
public int getData() {
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* @param data the data to set
|
||||
*/
|
||||
public void setData(byte data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the signText
|
||||
*/
|
||||
public List<String> getSignText() {
|
||||
return signText;
|
||||
}
|
||||
/**
|
||||
* @param signText the signText to set
|
||||
*/
|
||||
public void setSignText(List<String> signText) {
|
||||
this.signText = signText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s
|
||||
* @param b
|
||||
*/
|
||||
public void setBlock(int s, byte b) {
|
||||
this.typeId = (short)s;
|
||||
this.data = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block up with all the banner data required
|
||||
* @param map
|
||||
*/
|
||||
public void setBanner(Map<String, Tag> map) {
|
||||
banner = new BannerBlock();
|
||||
banner.prep(map);
|
||||
}
|
||||
/**
|
||||
* Sets this block up with all the skull data required
|
||||
* @param map
|
||||
* @param dataValue
|
||||
*/
|
||||
public void setSkull(Map<String, Tag> map, int dataValue) {
|
||||
skull = new SkullBlock();
|
||||
skull.prep(map, dataValue);
|
||||
}
|
||||
public void setFlowerPot(Map<String, Tag> map){
|
||||
pot = new PotBlock();
|
||||
pot.prep(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the spawner type if this block is a spawner
|
||||
* @param tileData
|
||||
*/
|
||||
public void setSpawnerType(Map<String, Tag> tileData) {
|
||||
//Bukkit.getLogger().info("DEBUG: " + tileData.toString());
|
||||
String creatureType = "";
|
||||
if (tileData.containsKey("EntityId")) {
|
||||
creatureType = ((StringTag) tileData.get("EntityId")).getValue().toUpperCase();
|
||||
} else if (tileData.containsKey("SpawnData")) {
|
||||
// 1.9 format
|
||||
Map<String,Tag> spawnData = ((CompoundTag) tileData.get("SpawnData")).getValue();
|
||||
//Bukkit.getLogger().info("DEBUG: " + spawnData.toString());
|
||||
if (spawnData.containsKey("id")) {
|
||||
creatureType = ((StringTag) spawnData.get("id")).getValue().toUpperCase();
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("DEBUG: creature type = " + creatureType);
|
||||
// The mob type might be prefixed with "Minecraft:"
|
||||
if (creatureType.startsWith("MINECRAFT:")) {
|
||||
creatureType = creatureType.substring(10);
|
||||
}
|
||||
if (WEtoME.containsKey(creatureType)) {
|
||||
spawnerBlockType = WEtoME.get(creatureType);
|
||||
} else {
|
||||
try {
|
||||
spawnerBlockType = EntityType.valueOf(creatureType);
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().warning("Spawner setting of " + creatureType + " is unknown for this server. Skipping.");
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("DEBUG: spawnerblock type = " + spawnerBlockType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block's sign data
|
||||
* @param tileData
|
||||
*/
|
||||
public void setSign(Map<String, Tag> tileData) {
|
||||
signText = new ArrayList<String>();
|
||||
List<String> text = new ArrayList<String>();
|
||||
for (int i = 1; i < 5; i++) {
|
||||
String line = ((StringTag) tileData.get("Text" + String.valueOf(i))).getValue();
|
||||
// This value can actually be a string that says null sometimes.
|
||||
if (line.equalsIgnoreCase("null")) {
|
||||
line = "";
|
||||
}
|
||||
//System.out.println("DEBUG: line " + i + " = '"+ line + "' of length " + line.length());
|
||||
text.add(line);
|
||||
}
|
||||
|
||||
JSONParser parser = new JSONParser();
|
||||
ContainerFactory containerFactory = new ContainerFactory(){
|
||||
public List creatArrayContainer() {
|
||||
return new LinkedList();
|
||||
}
|
||||
|
||||
public Map createObjectContainer() {
|
||||
return new LinkedHashMap();
|
||||
}
|
||||
|
||||
};
|
||||
// This just removes all the JSON formatting and provides the raw text
|
||||
for (int line = 0; line < 4; line++) {
|
||||
String lineText = "";
|
||||
if (!text.get(line).equals("\"\"") && !text.get(line).isEmpty()) {
|
||||
//String lineText = text.get(line).replace("{\"extra\":[\"", "").replace("\"],\"text\":\"\"}", "");
|
||||
//Bukkit.getLogger().info("DEBUG: sign text = '" + text.get(line) + "'");
|
||||
if (text.get(line).startsWith("{")) {
|
||||
// JSON string
|
||||
try {
|
||||
|
||||
Map json = (Map)parser.parse(text.get(line), containerFactory);
|
||||
List list = (List) json.get("extra");
|
||||
//System.out.println("DEBUG1:" + JSONValue.toJSONString(list));
|
||||
if (list != null) {
|
||||
Iterator iter = list.iterator();
|
||||
while(iter.hasNext()){
|
||||
Object next = iter.next();
|
||||
String format = JSONValue.toJSONString(next);
|
||||
//System.out.println("DEBUG2:" + format);
|
||||
// This doesn't see right, but appears to be the easiest way to identify this string as JSON...
|
||||
if (format.startsWith("{")) {
|
||||
// JSON string
|
||||
Map jsonFormat = (Map)parser.parse(format, containerFactory);
|
||||
Iterator formatIter = jsonFormat.entrySet().iterator();
|
||||
while (formatIter.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)formatIter.next();
|
||||
//System.out.println("DEBUG3:" + entry.getKey() + "=>" + entry.getValue());
|
||||
String key = entry.getKey().toString();
|
||||
String value = entry.getValue().toString();
|
||||
if (key.equalsIgnoreCase("color")) {
|
||||
try {
|
||||
lineText += ChatColor.valueOf(value.toUpperCase());
|
||||
} catch (Exception noColor) {
|
||||
Bukkit.getLogger().warning("Unknown color " + value +" in sign when pasting schematic, skipping...");
|
||||
}
|
||||
} else if (key.equalsIgnoreCase("text")) {
|
||||
lineText += value;
|
||||
} else {
|
||||
// Formatting - usually the value is always true, but check just in case
|
||||
if (key.equalsIgnoreCase("obfuscated") && value.equalsIgnoreCase("true")) {
|
||||
lineText += ChatColor.MAGIC;
|
||||
} else if (key.equalsIgnoreCase("underlined") && value.equalsIgnoreCase("true")) {
|
||||
lineText += ChatColor.UNDERLINE;
|
||||
} else {
|
||||
// The rest of the formats
|
||||
try {
|
||||
lineText += ChatColor.valueOf(key.toUpperCase());
|
||||
} catch (Exception noFormat) {
|
||||
// Ignore
|
||||
//System.out.println("DEBUG3:" + key + "=>" + value);
|
||||
Bukkit.getLogger().warning("Unknown format " + value +" in sign when pasting schematic, skipping...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is unformatted text. It is included in "". A reset is required to clear
|
||||
// any previous formatting
|
||||
if (format.length()>1) {
|
||||
lineText += ChatColor.RESET + format.substring(format.indexOf('"')+1,format.lastIndexOf('"'));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No extra tag
|
||||
json = (Map)parser.parse(text.get(line), containerFactory);
|
||||
String value = (String) json.get("text");
|
||||
//System.out.println("DEBUG text only?:" + value);
|
||||
lineText += value;
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
// This is unformatted text (not JSON). It is included in "".
|
||||
if (text.get(line).length() > 1) {
|
||||
try {
|
||||
lineText = text.get(line).substring(text.get(line).indexOf('"')+1,text.get(line).lastIndexOf('"'));
|
||||
} catch (Exception e) {
|
||||
//There may not be those "'s, so just use the raw line
|
||||
lineText = text.get(line);
|
||||
}
|
||||
} else {
|
||||
// just in case it isn't - show the raw line
|
||||
lineText = text.get(line);
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("Line " + line + " is " + lineText);
|
||||
}
|
||||
signText.add(lineText);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBook(Map<String, Tag> tileData) {
|
||||
//Bukkit.getLogger().info("DEBUG: Book data ");
|
||||
Bukkit.getLogger().info(tileData.toString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setChest(NMSAbstraction nms, Map<String, Tag> tileData) {
|
||||
try {
|
||||
ListTag chestItems = (ListTag) tileData.get("Items");
|
||||
if (chestItems != null) {
|
||||
//int number = 0;
|
||||
for (Tag item : chestItems.getValue()) {
|
||||
// Format for chest items is:
|
||||
// id = short value of item id
|
||||
// Damage = short value of item damage
|
||||
// Count = the number of items
|
||||
// Slot = the slot in the chest
|
||||
// inventory
|
||||
|
||||
if (item instanceof CompoundTag) {
|
||||
try {
|
||||
// Id is a number
|
||||
short itemType = (Short) ((CompoundTag) item).getValue().get("id").getValue();
|
||||
short itemDamage = (Short) ((CompoundTag) item).getValue().get("Damage").getValue();
|
||||
byte itemAmount = (Byte) ((CompoundTag) item).getValue().get("Count").getValue();
|
||||
byte itemSlot = (Byte) ((CompoundTag) item).getValue().get("Slot").getValue();
|
||||
ItemStack chestItem = new ItemStack(itemType, itemAmount, itemDamage);
|
||||
chestContents.put(itemSlot, chestItem);
|
||||
} catch (ClassCastException ex) {
|
||||
// Id is a material
|
||||
String itemType = (String) ((CompoundTag) item).getValue().get("id").getValue();
|
||||
try {
|
||||
// Get the material
|
||||
if (itemType.startsWith("minecraft:")) {
|
||||
String material = itemType.substring(10).toUpperCase();
|
||||
// Special case for non-standard material names
|
||||
Material itemMaterial;
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: " + material);
|
||||
|
||||
if (WEtoM.containsKey(material)) {
|
||||
//Bukkit.getLogger().info("DEBUG: Found in hashmap");
|
||||
itemMaterial = WEtoM.get(material);
|
||||
} else {
|
||||
//Bukkit.getLogger().info("DEBUG: Not in hashmap");
|
||||
itemMaterial = Material.valueOf(material);
|
||||
}
|
||||
short itemDamage = (Short) ((CompoundTag) item).getValue().get("Damage").getValue();
|
||||
byte itemAmount = (Byte) ((CompoundTag) item).getValue().get("Count").getValue();
|
||||
byte itemSlot = (Byte) ((CompoundTag) item).getValue().get("Slot").getValue();
|
||||
ItemStack chestItem = new ItemStack(itemMaterial, itemAmount, itemDamage);
|
||||
if (itemMaterial.equals(Material.WRITTEN_BOOK)) {
|
||||
chestItem = nms.setBook(item);
|
||||
}
|
||||
// Check for potions
|
||||
if (itemMaterial.toString().contains("POTION")) {
|
||||
chestItem = nms.setPotion(itemMaterial, item, chestItem);
|
||||
}
|
||||
chestContents.put(itemSlot, chestItem);
|
||||
}
|
||||
} catch (Exception exx) {
|
||||
// Bukkit.getLogger().info(item.toString());
|
||||
// Bukkit.getLogger().info(((CompoundTag)item).getValue().get("id").getName());
|
||||
Bukkit.getLogger().severe(
|
||||
"Could not parse item [" + itemType.substring(10).toUpperCase() + "] in schematic - skipping!");
|
||||
// Bukkit.getLogger().severe(item.toString());
|
||||
exx.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Bukkit.getLogger().info("Set chest inventory slot "
|
||||
// + itemSlot + " to " +
|
||||
// chestItem.toString());
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("Added " + number + " items to chest");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().severe("Could not parse schematic file item, skipping!");
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paste this block at blockLoc
|
||||
* @param nms
|
||||
* @param blockLoc
|
||||
*/
|
||||
//@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings("deprecation")
|
||||
public void paste(NMSAbstraction nms, Location blockLoc, boolean usePhysics, Biome biome) {
|
||||
// Only paste air if it is below the sea level and in the overworld
|
||||
Block block = new Location(blockLoc.getWorld(), x, y, z).add(blockLoc).getBlock();
|
||||
block.setBiome(biome);
|
||||
nms.setBlockSuperFast(block, typeId, data, usePhysics);
|
||||
if (signText != null) {
|
||||
if (block.getTypeId() != typeId) {
|
||||
block.setTypeId(typeId);
|
||||
}
|
||||
// Sign
|
||||
Sign sign = (Sign) block.getState();
|
||||
int index = 0;
|
||||
for (String line : signText) {
|
||||
sign.setLine(index++, line);
|
||||
}
|
||||
sign.update();
|
||||
} else if (banner != null) {
|
||||
banner.set(block);
|
||||
} else if (skull != null){
|
||||
skull.set(block);
|
||||
} else if (pot != null){
|
||||
pot.set(nms, block);
|
||||
} else if (spawnerBlockType != null) {
|
||||
if (block.getTypeId() != typeId) {
|
||||
block.setTypeId(typeId);
|
||||
}
|
||||
CreatureSpawner cs = (CreatureSpawner)block.getState();
|
||||
cs.setSpawnedType(spawnerBlockType);
|
||||
} else if (!chestContents.isEmpty()) {
|
||||
if (block.getTypeId() != typeId) {
|
||||
block.setTypeId(typeId);
|
||||
}
|
||||
// Check if this is a double chest
|
||||
Chest chestBlock = (Chest) block.getState();
|
||||
InventoryHolder iH = chestBlock.getInventory().getHolder();
|
||||
if (iH instanceof DoubleChest) {
|
||||
//Bukkit.getLogger().info("DEBUG: double chest");
|
||||
DoubleChest doubleChest = (DoubleChest) iH;
|
||||
for (ItemStack chestItem: chestContents.values()) {
|
||||
doubleChest.getInventory().addItem(chestItem);
|
||||
}
|
||||
} else {
|
||||
// Single chest
|
||||
for (Entry<Byte, ItemStack> en : chestContents.entrySet()) {
|
||||
chestBlock.getInventory().setItem(en.getKey(), en.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector for where this block is in the schematic
|
||||
*/
|
||||
public Vector getVector() {
|
||||
return new Vector(x,y,z);
|
||||
}
|
||||
}
|
139
src/main/java/us/tastybento/bskyblock/schematics/PotBlock.java
Normal file
139
src/main/java/us/tastybento/bskyblock/schematics/PotBlock.java
Normal file
@ -0,0 +1,139 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of ASkyBlock.
|
||||
*
|
||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ASkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
import us.tastybento.org.jnbt.IntTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* This class describes pots and is used in schematic importing
|
||||
*
|
||||
* @author SpyL1nk
|
||||
*
|
||||
*/
|
||||
public class PotBlock {
|
||||
private Material potItem;
|
||||
private int potItemData;
|
||||
|
||||
private static HashMap<String, Material> potItemList;
|
||||
|
||||
static {
|
||||
potItemList = new HashMap<String, Material>();
|
||||
potItemList.put("", Material.AIR);
|
||||
potItemList.put("minecraft:red_flower", Material.RED_ROSE);
|
||||
potItemList.put("minecraft:yellow_flower", Material.YELLOW_FLOWER);
|
||||
potItemList.put("minecraft:sapling", Material.SAPLING);
|
||||
potItemList.put("minecraft:red_mushroom", Material.RED_MUSHROOM);
|
||||
potItemList.put("minecraft:brown_mushroom", Material.BROWN_MUSHROOM);
|
||||
potItemList.put("minecraft:cactus", Material.CACTUS);
|
||||
potItemList.put("minecraft:deadbush", Material.LONG_GRASS);
|
||||
potItemList.put("minecraft:tallgrass", Material.LONG_GRASS);
|
||||
}
|
||||
|
||||
public boolean set(NMSAbstraction nms, Block block) {
|
||||
if(potItem != Material.AIR){
|
||||
nms.setFlowerPotBlock(block, new ItemStack(potItem, 1,(short) potItemData));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean prep(Map<String, Tag> tileData) {
|
||||
// Initialize as default
|
||||
potItem = Material.AIR;
|
||||
potItemData = 0;
|
||||
try {
|
||||
if(tileData.containsKey("Item")){
|
||||
|
||||
// Get the item in the pot
|
||||
if (tileData.get("Item") instanceof IntTag) {
|
||||
// Item is a number, not a material
|
||||
int id = ((IntTag) tileData.get("Item")).getValue();
|
||||
potItem = Material.getMaterial(id);
|
||||
// Check it's a viable pot item
|
||||
if (!potItemList.containsValue(potItem)) {
|
||||
// No, so reset to AIR
|
||||
potItem = Material.AIR;
|
||||
}
|
||||
} else if (tileData.get("Item") instanceof StringTag) {
|
||||
// Item is a material
|
||||
String itemName = ((StringTag) tileData.get("Item")).getValue();
|
||||
if (potItemList.containsKey(itemName)){
|
||||
// Check it's a viable pot item
|
||||
if (potItemList.containsKey(itemName)) {
|
||||
potItem = potItemList.get(itemName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tileData.containsKey("Data")){
|
||||
int dataTag = ((IntTag) tileData.get("Data")).getValue();
|
||||
// We should check data for each type of potItem
|
||||
if(potItem == Material.RED_ROSE){
|
||||
if(dataTag >= 0 && dataTag <= 8){
|
||||
potItemData = dataTag;
|
||||
} else {
|
||||
// Prevent hacks
|
||||
potItemData = 0;
|
||||
}
|
||||
} else if(potItem == Material.YELLOW_FLOWER ||
|
||||
potItem == Material.RED_MUSHROOM ||
|
||||
potItem == Material.BROWN_MUSHROOM ||
|
||||
potItem == Material.CACTUS){
|
||||
// Set to 0 anyway
|
||||
potItemData = 0;
|
||||
} else if(potItem == Material.SAPLING){
|
||||
if(dataTag >= 0 && dataTag <= 4){
|
||||
potItemData = dataTag;
|
||||
} else {
|
||||
// Prevent hacks
|
||||
potItemData = 0;
|
||||
}
|
||||
} else if(potItem == Material.LONG_GRASS){
|
||||
// Only 0 or 2
|
||||
if(dataTag == 0 || dataTag == 2){
|
||||
potItemData = dataTag;
|
||||
} else {
|
||||
potItemData = 0;
|
||||
}
|
||||
} else {
|
||||
// ERROR ?
|
||||
potItemData = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
potItemData = 0;
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("Debug: flowerpot item = " + potItem.toString());
|
||||
//Bukkit.getLogger().info("Debug: flowerpot item data = " + potItemData);
|
||||
//Bukkit.getLogger().info("Debug: flowerpot materialdata = " + new MaterialData(potItem,(byte) potItemData).toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
1759
src/main/java/us/tastybento/bskyblock/schematics/Schematic.java
Normal file
1759
src/main/java/us/tastybento/bskyblock/schematics/Schematic.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,193 @@
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.config.Settings;
|
||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||
import us.tastybento.bskyblock.util.VaultHelper;
|
||||
|
||||
public class SchematicsMgr {
|
||||
private BSkyBlock plugin;
|
||||
private static HashMap<String, Schematic> schematics = new HashMap<String, Schematic>();
|
||||
|
||||
/**
|
||||
* Class to hold all schematics that are available
|
||||
* @param plugin
|
||||
*/
|
||||
public SchematicsMgr(BSkyBlock plugin) {
|
||||
this.plugin = plugin;
|
||||
loadSchematics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads schematics. If the default
|
||||
* island is not included, it will be made
|
||||
*/
|
||||
public void loadSchematics() {
|
||||
// Check if there is a schematic folder and make it if it does not exist
|
||||
File schematicFolder = new File(plugin.getDataFolder(), "schematics");
|
||||
if (!schematicFolder.exists()) {
|
||||
schematicFolder.mkdir();
|
||||
}
|
||||
// Clear the schematic list that is kept in memory
|
||||
schematics.clear();
|
||||
// Load the default schematic if it exists
|
||||
// Set up the default schematic
|
||||
File schematicFile = new File(schematicFolder, "island.schematic");
|
||||
File netherFile = new File(schematicFolder, "nether.schematic");
|
||||
if (!schematicFile.exists()) {
|
||||
//plugin.getLogger().info("Default schematic does not exist...");
|
||||
// Only copy if the default exists
|
||||
if (plugin.getResource("schematics/island.schematic") != null) {
|
||||
plugin.getLogger().info("Default schematic does not exist, saving it...");
|
||||
plugin.saveResource("schematics/island.schematic", false);
|
||||
// Add it to schematics
|
||||
try {
|
||||
schematics.put("default",new Schematic(plugin, schematicFile));
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not load default schematic!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
// If this is repeated later due to the schematic config, fine, it will only add info
|
||||
} else {
|
||||
// No islands.schematic in the jar, so just make the default using
|
||||
// built-in island generation
|
||||
schematics.put("default",new Schematic(plugin));
|
||||
}
|
||||
plugin.getLogger().info("Loaded default nether schematic");
|
||||
} else {
|
||||
// It exists, so load it
|
||||
try {
|
||||
schematics.put("default",new Schematic(plugin, schematicFile));
|
||||
plugin.getLogger().info("Loaded default island schematic.");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not load default schematic!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// Add the nether default too
|
||||
if (!netherFile.exists()) {
|
||||
if (plugin.getResource("schematics/nether.schematic") != null) {
|
||||
plugin.saveResource("schematics/nether.schematic", false);
|
||||
|
||||
// Add it to schematics
|
||||
try {
|
||||
Schematic netherIsland = new Schematic(plugin, netherFile);
|
||||
netherIsland.setVisible(false);
|
||||
schematics.put("nether", netherIsland);
|
||||
plugin.getLogger().info("Loaded default nether schematic.");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not load default nether schematic!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
plugin.getLogger().severe("Could not find default nether schematic!");
|
||||
}
|
||||
} else {
|
||||
// It exists, so load it
|
||||
try {
|
||||
Schematic netherIsland = new Schematic(plugin, netherFile);
|
||||
netherIsland.setVisible(false);
|
||||
schematics.put("nether", netherIsland);
|
||||
plugin.getLogger().info("Loaded default nether schematic.");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not load default nether schematic!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// Set up some basic settings
|
||||
if (schematics.containsKey("default")) {
|
||||
schematics.get("default").setName("Island");
|
||||
schematics.get("default").setDescription("");
|
||||
schematics.get("default").setPartnerName("nether");
|
||||
schematics.get("default").setBiome(Settings.defaultBiome);
|
||||
schematics.get("default").setIcon(Material.GRASS);
|
||||
if (Settings.chestItems.length == 0) {
|
||||
schematics.get("default").setUseDefaultChest(false);
|
||||
}
|
||||
schematics.get("default").setOrder(0);
|
||||
}
|
||||
if (schematics.containsKey("nether")) {
|
||||
schematics.get("nether").setName("NetherBlock Island");
|
||||
schematics.get("nether").setDescription("Nether Island");
|
||||
schematics.get("nether").setPartnerName("default");
|
||||
schematics.get("nether").setBiome(Biome.HELL);
|
||||
schematics.get("nether").setIcon(Material.NETHERRACK);
|
||||
schematics.get("nether").setVisible(false);
|
||||
schematics.get("nether").setPasteEntities(true);
|
||||
if (Settings.chestItems.length == 0) {
|
||||
schematics.get("nether").setUseDefaultChest(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Load other settings from config.yml
|
||||
}
|
||||
|
||||
/**
|
||||
* Get schematic with name
|
||||
* @param name
|
||||
* @return schematic or null if it does not exist
|
||||
*/
|
||||
public Schematic getSchematic(String name) {
|
||||
return schematics.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* List schematics this player can access. If @param ignoreNoPermission is true, then only
|
||||
* schematics with a specific permission set will be checked. I.e., no common schematics will
|
||||
* be returned (including the default one).
|
||||
* @param player
|
||||
* @param ignoreNoPermission
|
||||
* @return List of schematics this player can use based on their permission level
|
||||
*/
|
||||
public List<Schematic> getSchematics(Player player, boolean ignoreNoPermission) {
|
||||
List<Schematic> result = new ArrayList<Schematic>();
|
||||
// Find out what schematics this player can choose from
|
||||
//Bukkit.getLogger().info("DEBUG: Checking schematics for " + player.getName());
|
||||
for (Schematic schematic : schematics.values()) {
|
||||
//Bukkit.getLogger().info("DEBUG: schematic name is '"+ schematic.getName() + "'");
|
||||
//Bukkit.getLogger().info("DEBUG: perm is " + schematic.getPerm());
|
||||
if ((!ignoreNoPermission && schematic.getPerm().isEmpty()) || VaultHelper.hasPerm(player, schematic.getPerm())) {
|
||||
//Bukkit.getLogger().info("DEBUG: player can use this schematic");
|
||||
// Only add if it's visible
|
||||
if (schematic.isVisible()) {
|
||||
// Check if it's a nether island, but the nether is not enables
|
||||
if (schematic.getBiome().equals(Biome.HELL)) {
|
||||
if (Settings.createNether && IslandWorld.getNetherWorld() != null) {
|
||||
result.add(schematic);
|
||||
}
|
||||
} else {
|
||||
result.add(schematic);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Sort according to order
|
||||
Collections.sort(result, new Comparator<Schematic>() {
|
||||
|
||||
@Override
|
||||
public int compare(Schematic o1, Schematic o2) {
|
||||
return ((o2.getOrder() < o1.getOrder()) ? 1 : -1);
|
||||
}
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public HashMap<String, Schematic> getAll() {
|
||||
return schematics;
|
||||
}
|
||||
|
||||
}
|
308
src/main/java/us/tastybento/bskyblock/schematics/SkullBlock.java
Normal file
308
src/main/java/us/tastybento/bskyblock/schematics/SkullBlock.java
Normal file
@ -0,0 +1,308 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of ASkyBlock.
|
||||
*
|
||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ASkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.schematics;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.SkullType;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Skull;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
|
||||
import us.tastybento.org.jnbt.ByteTag;
|
||||
import us.tastybento.org.jnbt.CompoundTag;
|
||||
import us.tastybento.org.jnbt.IntTag;
|
||||
import us.tastybento.org.jnbt.ListTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* This class describes skulls and is used in schematic importing
|
||||
*
|
||||
* @author SpyL1nk
|
||||
*
|
||||
*/
|
||||
public class SkullBlock {
|
||||
|
||||
private static final Random random = new Random();
|
||||
private static final String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
private SkullType skullType;
|
||||
private String skullOwnerName;
|
||||
private String skullOwnerUUID;
|
||||
private BlockFace skullRotation;
|
||||
private int skullStanding;
|
||||
private String skullTextureValue = null;
|
||||
private String skullTextureSignature = null;
|
||||
|
||||
private static HashMap<Integer, SkullType> skullTypeList;
|
||||
private static HashMap<Integer, BlockFace> skullRotationList;
|
||||
|
||||
static {
|
||||
skullTypeList = new HashMap<Integer, SkullType>();
|
||||
skullTypeList.put(0, SkullType.SKELETON);
|
||||
skullTypeList.put(1, SkullType.WITHER);
|
||||
skullTypeList.put(2, SkullType.ZOMBIE);
|
||||
skullTypeList.put(3, SkullType.PLAYER);
|
||||
skullTypeList.put(4, SkullType.CREEPER);
|
||||
}
|
||||
|
||||
static {
|
||||
skullRotationList = new HashMap<Integer, BlockFace>();
|
||||
skullRotationList.put(0, BlockFace.NORTH);
|
||||
skullRotationList.put(1, BlockFace.NORTH_NORTH_EAST);
|
||||
skullRotationList.put(2, BlockFace.NORTH_EAST);
|
||||
skullRotationList.put(3, BlockFace.EAST_NORTH_EAST);
|
||||
skullRotationList.put(4, BlockFace.EAST);
|
||||
skullRotationList.put(5, BlockFace.EAST_SOUTH_EAST);
|
||||
skullRotationList.put(6, BlockFace.SOUTH_EAST);
|
||||
skullRotationList.put(7, BlockFace.SOUTH_SOUTH_EAST);
|
||||
skullRotationList.put(8, BlockFace.SOUTH);
|
||||
skullRotationList.put(9, BlockFace.SOUTH_SOUTH_WEST);
|
||||
skullRotationList.put(10, BlockFace.SOUTH_WEST);
|
||||
skullRotationList.put(11, BlockFace.WEST_SOUTH_WEST);
|
||||
skullRotationList.put(12, BlockFace.WEST);
|
||||
skullRotationList.put(13, BlockFace.WEST_NORTH_WEST);
|
||||
skullRotationList.put(14, BlockFace.NORTH_WEST);
|
||||
skullRotationList.put(15, BlockFace.NORTH_NORTH_WEST);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean set(Block block) {
|
||||
Skull skull = (Skull) block.getState();
|
||||
if(skullOwnerName != null){
|
||||
skull.setOwner(skullOwnerName);
|
||||
}
|
||||
skull.setSkullType(skullType);
|
||||
skull.setRotation(skullRotation);
|
||||
skull.setRawData((byte) skullStanding);
|
||||
// Texture update
|
||||
if(skullTextureValue != null){
|
||||
setSkullWithNonPlayerProfile(skullTextureValue, skullTextureSignature, skullOwnerUUID, skullOwnerName, skull);
|
||||
}
|
||||
skull.update();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean prep(Map<String, Tag> tileData, int dataValue) {
|
||||
|
||||
try {
|
||||
// Take skull type
|
||||
if(tileData.containsKey("SkullType")){
|
||||
int skullTypeId = (int) ((ByteTag) tileData.get("SkullType")).getValue();
|
||||
//Bukkit.getLogger().info("DEBUG: skull type = " + skullTypeId);
|
||||
if(skullTypeList.containsKey(skullTypeId)){
|
||||
skullType = skullTypeList.get(skullTypeId);
|
||||
}
|
||||
else {
|
||||
// Prevent hacks, set to default skull type
|
||||
skullType = skullTypeList.get(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Prevent hacks, set to defaut skull type
|
||||
skullType = skullTypeList.get(0);
|
||||
}
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull's data value = " + dataValue);
|
||||
// Data value 0 is actually unused for skulls, set to 2 to prevent hacks
|
||||
if(dataValue > 0 && dataValue < 6){
|
||||
|
||||
skullStanding = dataValue;
|
||||
|
||||
if(tileData.containsKey("Rot")){
|
||||
int skullRotId = (int) ((ByteTag) tileData.get("Rot")).getValue();
|
||||
//Bukkit.getLogger().info("DEBUG: skull's rotation byte = " + skullRotId);
|
||||
// Useful for skulls on the floor to insert rotation data
|
||||
if(skullRotationList.containsKey(skullStanding)){
|
||||
skullRotation = skullRotationList.get(skullRotId);
|
||||
}
|
||||
else{
|
||||
// Prevents hacks
|
||||
skullRotation = skullRotationList.get(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
skullRotation = skullRotationList.get(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
skullStanding = 2;
|
||||
|
||||
if(tileData.containsKey("Rot")){
|
||||
int skullRotId = ((IntTag) tileData.get("Rot")).getValue();
|
||||
//Bukkit.getLogger().info("DEBUG: skull's rotation byte = " + skullRotId);
|
||||
// Useful for skulls on the floor to insert rotation data
|
||||
if(skullRotationList.containsKey(skullStanding)){
|
||||
skullRotation = skullRotationList.get(skullRotId);
|
||||
}
|
||||
// Prevents hacks
|
||||
else{
|
||||
skullRotation = skullRotationList.get(0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
skullRotation = skullRotationList.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Player Heads (skin, texture etc.)
|
||||
if(skullType == SkullType.PLAYER && tileData.containsKey("Owner")){
|
||||
|
||||
Map<String, Tag> skullOwner = ((CompoundTag) tileData.get("Owner")).getValue();
|
||||
|
||||
if(skullOwner.containsKey("Name")){
|
||||
skullOwnerName = ((StringTag) skullOwner.get("Name")).getValue();
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull owner's name = " + skullOwnerName);
|
||||
}
|
||||
|
||||
if(skullOwner.containsKey("Id")){
|
||||
skullOwnerUUID = ((StringTag) skullOwner.get("Id")).getValue();
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull owner's UUID = " + skullOwnerUUID);
|
||||
}
|
||||
|
||||
if(skullOwner.containsKey("Properties")){
|
||||
Map<String, Tag> skullOwnerProperties = ((CompoundTag) skullOwner.get("Properties")).getValue();
|
||||
|
||||
if(skullOwnerProperties.containsKey("textures")){
|
||||
|
||||
ListTag listTagTextures = (ListTag) skullOwnerProperties.get("textures");
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull texture's list = " + listTagTextures);
|
||||
|
||||
if(listTagTextures != null){
|
||||
|
||||
// Logicaly, textures should have only one entry ...
|
||||
Map<String, Tag> skullOwnerTextures = ((CompoundTag) listTagTextures.getValue().get(0)).getValue();
|
||||
|
||||
if(skullOwnerTextures.containsKey("Value")){
|
||||
skullTextureValue = ((StringTag) skullOwnerTextures.get("Value")).getValue();
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull texture's value = " + skullTextureValue);
|
||||
}
|
||||
if(skullOwnerTextures.containsKey("Signature")){
|
||||
skullTextureSignature = ((StringTag) skullOwnerTextures.get("Signature")).getValue();
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: skull's texture signature = " + skullTextureSignature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Credits: GermanCoding
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setSkullWithNonPlayerProfile(String textureValue, String textureSignature, String ownerUUID, String ownerName, Skull skull) {
|
||||
if (skull.getType() != Material.SKULL)
|
||||
throw new IllegalArgumentException("Block must be a skull.");
|
||||
|
||||
skull.getWorld().refreshChunk(skull.getChunk().getX(), skull.getChunk().getZ());
|
||||
|
||||
|
||||
// Difference beetween NonPlayerSkin and PlayerSkin
|
||||
if(textureSignature != null){
|
||||
try {
|
||||
setSkullProfile(skull, getPlayerProfile(textureValue, textureSignature, ownerUUID, ownerName));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
setSkullProfile(skull, getNonPlayerProfile(textureValue, ownerUUID, ownerName));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//skull.getWorld().refreshChunk(skull.getChunk().getX(), skull.getChunk().getZ());
|
||||
}
|
||||
|
||||
// Credits: val59000 (THANK YOU VERY MUCH VAL59000 !)
|
||||
private static void setSkullProfile(Skull skull, GameProfile gameProfile) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
|
||||
Field profileField = null;
|
||||
try {
|
||||
profileField = skull.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
profileField.set(skull, gameProfile);
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Credits: dori99xd
|
||||
public static GameProfile getNonPlayerProfile(String textureValue, String ownerUUID, String ownerName) {
|
||||
// Create a new GameProfile with .schematic informations or with fake informations
|
||||
GameProfile newSkinProfile = new GameProfile(ownerUUID == null ? UUID.randomUUID() : UUID.fromString(ownerUUID),
|
||||
ownerName == null ? getRandomString(16) : null);
|
||||
|
||||
// Insert textures properties
|
||||
newSkinProfile.getProperties().put("textures", new Property("textures", textureValue));
|
||||
return newSkinProfile;
|
||||
}
|
||||
|
||||
// Credits: dori99xd
|
||||
public static GameProfile getPlayerProfile(String textureValue, String textureSignature, String ownerUUID, String ownerName) {
|
||||
// Create a new GameProfile with .schematic informations or with fake informations
|
||||
GameProfile newSkinProfile = new GameProfile( ownerUUID == null ? UUID.randomUUID() : UUID.fromString(ownerUUID),
|
||||
ownerName == null ? getRandomString(16) : null);
|
||||
|
||||
// Insert textures properties
|
||||
newSkinProfile.getProperties().put("textures", new Property("textures", textureValue, textureSignature));
|
||||
return newSkinProfile;
|
||||
}
|
||||
|
||||
// Credits: dori99xd
|
||||
public static String getRandomString(int length) {
|
||||
StringBuilder b = new StringBuilder(length);
|
||||
for(int j = 0; j < length; j++){
|
||||
b.append(chars.charAt(random.nextInt(chars.length())));
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
}
|
356
src/main/java/us/tastybento/bskyblock/util/SafeSpotTeleport.java
Normal file
356
src/main/java/us/tastybento/bskyblock/util/SafeSpotTeleport.java
Normal file
@ -0,0 +1,356 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of BSkyBlock.
|
||||
*
|
||||
* BSkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BSkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BSkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.database.objects.Island;
|
||||
|
||||
/**
|
||||
* A class that calculates finds a safe spot asynchronously and then teleports the player there.
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class SafeSpotTeleport {
|
||||
|
||||
//private NMSAbstraction nms;
|
||||
//private BSkyBlock plugin;
|
||||
/**
|
||||
* Teleport to a safe place and if it fails, show a failure message
|
||||
* @param plugin
|
||||
* @param player
|
||||
* @param l
|
||||
* @param failureMessage
|
||||
*/
|
||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l, final String failureMessage) {
|
||||
new SafeSpotTeleport(plugin, player, l, 1, failureMessage, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport to a safe place and set home
|
||||
* @param plugin
|
||||
* @param player
|
||||
* @param l
|
||||
* @param number
|
||||
*/
|
||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l, final int number) {
|
||||
new SafeSpotTeleport(plugin, player, l, number, "", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport to a safe spot on an island
|
||||
* @param plugin
|
||||
* @param player
|
||||
* @param l
|
||||
*/
|
||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l) {
|
||||
new SafeSpotTeleport(plugin, player, l, 1, "", false);
|
||||
}
|
||||
/**
|
||||
* Teleport to a safe spot on an island
|
||||
|
||||
* @param plugin
|
||||
* @param entity
|
||||
* @param islandLoc
|
||||
*/
|
||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity entity, final Location islandLoc, final int homeNumber, final String failureMessage, final boolean setHome) {
|
||||
//this.plugin = plugin;
|
||||
//plugin.getLogger().info("DEBUG: running safe spot");
|
||||
// Get island
|
||||
Island island = plugin.getIslands().getIslandAt(islandLoc);
|
||||
if (island != null) {
|
||||
final World world = islandLoc.getWorld();
|
||||
// Get the chunks
|
||||
List<ChunkSnapshot> chunkSnapshot = new ArrayList<ChunkSnapshot>();
|
||||
// Add the center chunk
|
||||
chunkSnapshot.add(island.getCenter().toVector().toLocation(world).getChunk().getChunkSnapshot());
|
||||
// Add immediately adjacent chunks
|
||||
for (int x = islandLoc.getChunk().getX()-1; x <= islandLoc.getChunk().getX()+1; x++) {
|
||||
for (int z = islandLoc.getChunk().getZ()-1; z <= islandLoc.getChunk().getZ()+1; z++) {
|
||||
if (x != islandLoc.getChunk().getX() || z != islandLoc.getChunk().getZ()) {
|
||||
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the rest of the island protected area
|
||||
for (int x = island.getMinProtectedX() /16; x <= (island.getMinProtectedX() + island.getProtectionRange() - 1)/16; x++) {
|
||||
for (int z = island.getMinProtectedZ() /16; z <= (island.getMinProtectedZ() + island.getProtectionRange() - 1)/16; z++) {
|
||||
// This includes the center spots again, so is not as efficient...
|
||||
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
||||
}
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: size of chunk ss = " + chunkSnapshot.size());
|
||||
final List<ChunkSnapshot> finalChunk = chunkSnapshot;
|
||||
int maxHeight = world.getMaxHeight() - 2;
|
||||
if (world.getEnvironment().equals(Environment.NETHER)) {
|
||||
// We need to ignore the roof
|
||||
maxHeight -= 20;
|
||||
}
|
||||
final int worldHeight = maxHeight;
|
||||
//plugin.getLogger().info("DEBUG:world height = " + worldHeight);
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void run() {
|
||||
// Find a safe spot, defined as a solid block, with 2 air spaces above it
|
||||
//long time = System.nanoTime();
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int z = 0;
|
||||
ChunkSnapshot safeChunk = null;
|
||||
ChunkSnapshot portalChunk = null;
|
||||
boolean safeSpotFound = false;
|
||||
/*
|
||||
try {
|
||||
nms = checkVersion();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
Vector safeSpotInChunk = null;
|
||||
Vector portalPart = null;
|
||||
double distance = 0D;
|
||||
double safeDistance = 0D;
|
||||
for (ChunkSnapshot chunk: finalChunk) {
|
||||
for (x = 0; x< 16; x++) {
|
||||
for (z = 0; z < 16; z++) {
|
||||
// Work down from the entry point up
|
||||
for (y = Math.min(chunk.getHighestBlockYAt(x, z), worldHeight); y >= 0; y--) {
|
||||
//System.out.println("Trying " + (16 * chunk.getX() + x) + " " + y + " " + (16 * chunk.getZ() + z));
|
||||
// Check for portal - only if this is not a safe home search
|
||||
if (!setHome && chunk.getBlockTypeId(x, y, z) == Material.PORTAL.getId()) {
|
||||
if (portalPart == null || (distance > islandLoc.toVector().distanceSquared(new Vector(x,y,z)))) {
|
||||
// First one found or a closer one, save the chunk the position and the distance
|
||||
portalChunk = chunk;
|
||||
portalPart = new Vector(x,y,z);
|
||||
distance = portalPart.distanceSquared(islandLoc.toVector());
|
||||
}
|
||||
}
|
||||
// Check for safe spot, but only if it is closer than one we have found already
|
||||
if (!safeSpotFound || (safeDistance > islandLoc.toVector().distanceSquared(new Vector(x,y,z)))) {
|
||||
// No safe spot yet, or closer distance
|
||||
if (checkBlock(chunk,x,y,z, worldHeight)) {
|
||||
safeChunk = chunk;
|
||||
safeSpotFound = true;
|
||||
safeSpotInChunk = new Vector(x,y,z);
|
||||
safeDistance = islandLoc.toVector().distanceSquared(safeSpotInChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //end z
|
||||
} // end x
|
||||
//if (safeSpotFound) {
|
||||
//System.out.print("DEBUG: safe spot found " + safeSpotInChunk.toString());
|
||||
//break search;
|
||||
//}
|
||||
}
|
||||
// End search
|
||||
// Check if the portal is safe (it should be)
|
||||
if (portalPart != null) {
|
||||
//System.out.print("DEBUG: Portal found");
|
||||
// There is a portal available, but is it safe?
|
||||
// Get the lowest portal spot
|
||||
x = portalPart.getBlockX();
|
||||
y = portalPart.getBlockY();
|
||||
z = portalPart.getBlockZ();
|
||||
while (portalChunk.getBlockTypeId(x,y,z) == Material.PORTAL.getId()) {
|
||||
y--;
|
||||
}
|
||||
//System.out.print("DEBUG: Portal teleport loc = " + (16 * portalChunk.getX() + x) + "," + (y) + "," + (16 * portalChunk.getZ() + z));
|
||||
// Now check if this is a safe location
|
||||
if (checkBlock(portalChunk,x,y,z, worldHeight)) {
|
||||
// Yes, so use this instead of the highest location
|
||||
//System.out.print("DEBUG: Portal is safe");
|
||||
safeSpotFound = true;
|
||||
safeSpotInChunk = new Vector(x,y,z);
|
||||
safeChunk = portalChunk;
|
||||
// TODO: Add safe portal spot to island
|
||||
}
|
||||
}
|
||||
//System.out.print("Seconds = " + ((System.nanoTime() - time) * 0.000000001));
|
||||
if (safeChunk != null && safeSpotFound) {
|
||||
//final Vector spot = new Vector((16 *currentChunk.getX()) + x + 0.5D, y +1, (16 * currentChunk.getZ()) + z + 0.5D)
|
||||
final Vector spot = new Vector((16 *safeChunk.getX()) + 0.5D, 1, (16 * safeChunk.getZ()) + 0.5D).add(safeSpotInChunk);
|
||||
// Return to main thread and teleport the player
|
||||
plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Location destination = spot.toLocation(islandLoc.getWorld());
|
||||
//plugin.getLogger().info("DEBUG: safe spot found = " + destination);
|
||||
|
||||
// Create a portal
|
||||
// TODO Add if statement here
|
||||
//Block b = player.getLocation().getBlock();
|
||||
//if (b.getType() != Material.PORTAL) {
|
||||
/*
|
||||
if (world.equals(BSkyBlock.getNetherWorld())) {
|
||||
for (int x = -1; x < 3; x++) {
|
||||
for (int y = -1; y< 4; y++) {
|
||||
Location l = new Location(islandLoc.getWorld(), destination.getBlockX() + x, destination.getBlockY() + y, destination.getBlockZ() -1);
|
||||
if (x == -1 || x == 2 || y == -1 || y == 3) {
|
||||
//nms.setBlockSuperFast(l.getBlock(), Material.OBSIDIAN.getId(), (byte)0, false);
|
||||
//l.getBlock().setType(Material.OBSIDIAN);
|
||||
//plugin.getLogger().info("DEBUG: obsidian at "+ l);
|
||||
} else {
|
||||
//plugin.getLogger().info("DEBUG: Portal at "+ l);
|
||||
nms.setBlockSuperFast(l.getBlock(), Material.PORTAL.getId(), (byte)0, false);
|
||||
//l.getBlock().setType(Material.PORTAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
if (setHome && entity instanceof Player) {
|
||||
plugin.getPlayers().setHomeLocation(entity.getUniqueId(), destination, homeNumber);
|
||||
}
|
||||
Vector velocity = entity.getVelocity();
|
||||
entity.teleport(destination);
|
||||
entity.setVelocity(velocity);
|
||||
}});
|
||||
} else {
|
||||
// We did not find a spot
|
||||
plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//plugin.getLogger().info("DEBUG: safe spot not found");
|
||||
if (entity instanceof Player) {
|
||||
if (!failureMessage.isEmpty()) {
|
||||
Util.sendMessage(((Player)entity), failureMessage);
|
||||
} else {
|
||||
Util.sendMessage(((Player)entity), ChatColor.RED + "Warp not safe");
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the location is a safe one.
|
||||
* @param chunk
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param worldHeight
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean checkBlock(ChunkSnapshot chunk, int x, int y, int z, int worldHeight) {
|
||||
int type = chunk.getBlockTypeId(x, y, z);
|
||||
if (type != 0) { // AIR
|
||||
int space1 = chunk.getBlockTypeId(x, Math.min(y + 1, worldHeight), z);
|
||||
int space2 = chunk.getBlockTypeId(x, Math.min(y + 2, worldHeight), z);
|
||||
if ((space1 == 0 && space2 == 0) || (space1 == Material.PORTAL.getId() || space2 == Material.PORTAL.getId())) {
|
||||
// Now there is a chance that this is a safe spot
|
||||
// Check for safe ground
|
||||
Material mat = Material.getMaterial(type);
|
||||
if (!mat.toString().contains("FENCE")
|
||||
&& !mat.toString().contains("DOOR")
|
||||
&& !mat.toString().contains("GATE")
|
||||
&& !mat.toString().contains("PLATE")) {
|
||||
switch (mat) {
|
||||
// Unsafe
|
||||
case ANVIL:
|
||||
case BARRIER:
|
||||
case BOAT:
|
||||
case CACTUS:
|
||||
case DOUBLE_PLANT:
|
||||
case ENDER_PORTAL:
|
||||
case FIRE:
|
||||
case FLOWER_POT:
|
||||
case LADDER:
|
||||
case LAVA:
|
||||
case LEVER:
|
||||
case LONG_GRASS:
|
||||
case PISTON_EXTENSION:
|
||||
case PISTON_MOVING_PIECE:
|
||||
case PORTAL:
|
||||
case SIGN_POST:
|
||||
case SKULL:
|
||||
case STANDING_BANNER:
|
||||
case STATIONARY_LAVA:
|
||||
case STATIONARY_WATER:
|
||||
case STONE_BUTTON:
|
||||
case TORCH:
|
||||
case TRIPWIRE:
|
||||
case WATER:
|
||||
case WEB:
|
||||
case WOOD_BUTTON:
|
||||
//System.out.println("Block is dangerous " + mat.toString());
|
||||
break;
|
||||
default:
|
||||
// Safe
|
||||
// System.out.println("Block is safe " + mat.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks what version the server is running and picks the appropriate NMS handler, or fallback
|
||||
* @return NMSAbstraction class
|
||||
* @throws ClassNotFoundException
|
||||
* @throws IllegalArgumentException
|
||||
* @throws SecurityException
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
/*
|
||||
private NMSAbstraction checkVersion() throws ClassNotFoundException, IllegalArgumentException,
|
||||
SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException,
|
||||
NoSuchMethodException {
|
||||
String serverPackageName = plugin.getServer().getClass().getPackage().getName();
|
||||
String pluginPackageName = plugin.getClass().getPackage().getName();
|
||||
String version = serverPackageName.substring(serverPackageName.lastIndexOf('.') + 1);
|
||||
Class<?> clazz;
|
||||
try {
|
||||
//plugin.getLogger().info("DEBUG: Trying " + pluginPackageName + ".nms." + version + ".NMSHandler");
|
||||
clazz = Class.forName(pluginPackageName + ".nms." + version + ".NMSHandler");
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().info("No NMS Handler found, falling back to Bukkit API.");
|
||||
clazz = Class.forName(pluginPackageName + ".nms.fallback.NMSHandler");
|
||||
}
|
||||
//plugin.getLogger().info("DEBUG: " + serverPackageName);
|
||||
//plugin.getLogger().info("DEBUG: " + pluginPackageName);
|
||||
// Check if we have a NMSAbstraction implementing class at that location.
|
||||
if (NMSAbstraction.class.isAssignableFrom(clazz)) {
|
||||
return (NMSAbstraction) clazz.getConstructor().newInstance();
|
||||
} else {
|
||||
throw new IllegalStateException("Class " + clazz.getName() + " does not implement NMSAbstraction");
|
||||
}
|
||||
}*/
|
||||
}
|
@ -142,4 +142,9 @@ public class Util {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isOnePointEight() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,90 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of BSkyBlock.
|
||||
*
|
||||
* BSkyBlock is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BSkyBlock is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BSkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
package us.tastybento.bskyblock.util.nms;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
public interface NMSAbstraction {
|
||||
|
||||
/**
|
||||
* Update the low-level chunk information for the given block to the new block ID and data. This
|
||||
* change will not be propagated to clients until the chunk is refreshed to them.
|
||||
* @param block
|
||||
* @param blockId
|
||||
* @param data
|
||||
* @param applyPhysics
|
||||
*/
|
||||
public void setBlockSuperFast(Block block, int blockId, byte data, boolean applyPhysics);
|
||||
|
||||
public ItemStack setBook(Tag item);
|
||||
|
||||
/**
|
||||
* Sets a block to be an item stack
|
||||
* @param block
|
||||
* @param itemStack
|
||||
*/
|
||||
public void setFlowerPotBlock(Block block, ItemStack itemStack);
|
||||
|
||||
boolean isPotion(ItemStack item);
|
||||
|
||||
/**
|
||||
* Returns a potion ItemStack
|
||||
* @param itemMaterial
|
||||
* @param itemTag
|
||||
* @param chestItem
|
||||
* @return
|
||||
*/
|
||||
public ItemStack setPotion(Material itemMaterial, Tag itemTag, ItemStack chestItem);
|
||||
|
||||
/**
|
||||
* Gets a monster egg itemstack
|
||||
* @param type
|
||||
* @param amount
|
||||
* @return itemstack
|
||||
*/
|
||||
public ItemStack getSpawnEgg(EntityType type, int amount);
|
||||
|
||||
/**
|
||||
* Send an action bar message to player
|
||||
* @param player
|
||||
* @param message
|
||||
*/
|
||||
public void sendActionBar(Player player, String message);
|
||||
|
||||
|
||||
/**
|
||||
* Send a title to a player
|
||||
* @param player
|
||||
* @param message
|
||||
*/
|
||||
public void sendTitle(Player player, String message);
|
||||
|
||||
|
||||
/**
|
||||
* Send a subtitle to a player
|
||||
* @param player
|
||||
* @param message
|
||||
*/
|
||||
public void sendSubtitle(Player player, String message);
|
||||
}
|
||||
|
@ -1,8 +1,21 @@
|
||||
package us.tastybento.bskyblock.util.nms.fallback;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.SpawnEgg;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
import us.tastybento.org.jnbt.CompoundTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* A fallback NMS Handler when the NMS version is not supported by BSkyBlock
|
||||
@ -30,4 +43,96 @@ public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.wasteofplastic.askyblock.nms.NMSAbstraction#getSpawnEgg(org.bukkit.entity.EntityType, int)
|
||||
*/
|
||||
@Override
|
||||
public ItemStack getSpawnEgg(EntityType type, int amount) {
|
||||
SpawnEgg egg = new SpawnEgg(type);
|
||||
return egg.toItemStack(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPotion(ItemStack item) {
|
||||
if (item.getType().equals(Material.POTION) && item.getDurability() != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.wasteofplastic.askyblock.nms.NMSAbstraction#setBlockSuperFast(org.bukkit.block.Block, org.bukkit.Material)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setBlockSuperFast(Block b, int blockId, byte data, boolean applyPhysics) {
|
||||
b.setTypeIdAndData(blockId, data, applyPhysics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack setBook(Tag item) {
|
||||
Bukkit.getLogger().warning("Written books in schematics not supported with this version of server");
|
||||
return new ItemStack(Material.WRITTEN_BOOK);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setFlowerPotBlock(Block block, ItemStack itemStack) {
|
||||
block.setTypeIdAndData(itemStack.getTypeId(), itemStack.getData().getData(), false);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ItemStack setPotion(Material itemMaterial, Tag itemTags,
|
||||
ItemStack chestItem) {
|
||||
// Try some backwards compatibility with new 1.9 schematics
|
||||
Map<String,Tag> contents = (Map<String,Tag>) ((CompoundTag) itemTags).getValue().get("tag").getValue();
|
||||
StringTag stringTag = ((StringTag)contents.get("Potion"));
|
||||
if (stringTag != null) {
|
||||
String tag = stringTag.getValue().replace("minecraft:", "");
|
||||
PotionType type = null;
|
||||
boolean strong = tag.contains("strong");
|
||||
boolean _long = tag.contains("long");
|
||||
//Bukkit.getLogger().info("tag = " + tag);
|
||||
if(tag.equals("fire_resistance") || tag.equals("long_fire_resistance")){
|
||||
type = PotionType.FIRE_RESISTANCE;
|
||||
}else if(tag.equals("harming") || tag.equals("strong_harming")){
|
||||
type = PotionType.INSTANT_DAMAGE;
|
||||
}else if(tag.equals("healing") || tag.equals("strong_healing")){
|
||||
type = PotionType.INSTANT_HEAL;
|
||||
}else if(tag.equals("invisibility") || tag.equals("long_invisibility")){
|
||||
type = PotionType.INVISIBILITY;
|
||||
}else if(tag.equals("leaping") || tag.equals("long_leaping") || tag.equals("strong_leaping")){
|
||||
type = PotionType.JUMP;
|
||||
}else if(tag.equals("night_vision") || tag.equals("long_night_vision")){
|
||||
type = PotionType.NIGHT_VISION;
|
||||
}else if(tag.equals("poison") || tag.equals("long_poison") || tag.equals("strong_poison")){
|
||||
type = PotionType.POISON;
|
||||
}else if(tag.equals("regeneration") || tag.equals("long_regeneration") || tag.equals("strong_regeneration")){
|
||||
type = PotionType.REGEN;
|
||||
}else if(tag.equals("slowness") || tag.equals("long_slowness")){
|
||||
type = PotionType.SLOWNESS;
|
||||
}else if(tag.equals("swiftness") || tag.equals("long_swiftness") || tag.equals("strong_swiftness")){
|
||||
type = PotionType.SPEED;
|
||||
}else if(tag.equals("strength") || tag.equals("long_strength") || tag.equals("strong_strength")){
|
||||
type = PotionType.STRENGTH;
|
||||
}else if(tag.equals("water_breathing") || tag.equals("long_water_breathing")){
|
||||
type = PotionType.WATER_BREATHING;
|
||||
}else if(tag.equals("water")){
|
||||
type = PotionType.WATER;
|
||||
}else if(tag.equals("weakness") || tag.equals("long_weakness")){
|
||||
type = PotionType.WEAKNESS;
|
||||
}else{
|
||||
return chestItem;
|
||||
}
|
||||
Potion potion = new Potion(type);
|
||||
potion.setHasExtendedDuration(_long);
|
||||
potion.setLevel(strong ? 2 : 1);
|
||||
chestItem = potion.toItemStack(chestItem.getAmount());
|
||||
}
|
||||
|
||||
return chestItem;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_10_R1;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_10_R1
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_11_R1;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_11_R1
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,32 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_12_R1;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagList;
|
||||
import net.minecraft.server.v1_12_R1.NBTTagString;
|
||||
import net.minecraft.server.v1_12_R1.TileEntityFlowerPot;
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
import us.tastybento.org.jnbt.CompoundTag;
|
||||
import us.tastybento.org.jnbt.ListTag;
|
||||
import us.tastybento.org.jnbt.StringTag;
|
||||
import us.tastybento.org.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_12_R1
|
||||
@ -11,6 +35,178 @@ import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
private static HashMap<EntityType, String> bToMConversion;
|
||||
|
||||
static {
|
||||
bToMConversion = new HashMap<EntityType, String> ();
|
||||
bToMConversion.put(EntityType.MUSHROOM_COW, "mooshroom");
|
||||
bToMConversion.put(EntityType.PIG_ZOMBIE, "zombie_pigman");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockSuperFast(Block b, int blockId, byte data, boolean applyPhysics) {
|
||||
net.minecraft.server.v1_12_R1.World w = ((CraftWorld) b.getWorld()).getHandle();
|
||||
net.minecraft.server.v1_12_R1.Chunk chunk = w.getChunkAt(b.getX() >> 4, b.getZ() >> 4);
|
||||
BlockPosition bp = new BlockPosition(b.getX(), b.getY(), b.getZ());
|
||||
int combined = blockId + (data << 12);
|
||||
IBlockData ibd = net.minecraft.server.v1_12_R1.Block.getByCombinedId(combined);
|
||||
if (applyPhysics) {
|
||||
w.setTypeAndData(bp, ibd, 3);
|
||||
} else {
|
||||
w.setTypeAndData(bp, ibd, 2);
|
||||
}
|
||||
chunk.a(bp, ibd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack setBook(Tag item) {
|
||||
ItemStack chestItem = new ItemStack(Material.WRITTEN_BOOK);
|
||||
//Bukkit.getLogger().info("item data");
|
||||
//Bukkit.getLogger().info(item.toString());
|
||||
if (((CompoundTag) item).getValue().containsKey("tag")) {
|
||||
Map<String,Tag> contents = (Map<String,Tag>) ((CompoundTag) item).getValue().get("tag").getValue();
|
||||
//BookMeta bookMeta = (BookMeta) chestItem.getItemMeta();
|
||||
String author = "";
|
||||
if (contents.containsKey("author")) {
|
||||
author = ((StringTag)contents.get("author")).getValue();
|
||||
}
|
||||
//Bukkit.getLogger().info("Author: " + author);
|
||||
//bookMeta.setAuthor(author);
|
||||
String title = "";
|
||||
if (contents.containsKey("title")) {
|
||||
title = ((StringTag)contents.get("title")).getValue();
|
||||
}
|
||||
//Bukkit.getLogger().info("Title: " + title);
|
||||
//bookMeta.setTitle(title);
|
||||
List<String> lore = new ArrayList<String>();
|
||||
if (contents.containsKey("display")) {
|
||||
Map<String,Tag> display = (Map<String, Tag>) (contents.get("display")).getValue();
|
||||
List<Tag> loreTag = ((ListTag)display.get("Lore")).getValue();
|
||||
for (Tag s: loreTag) {
|
||||
lore.add(((StringTag)s).getValue());
|
||||
}
|
||||
}
|
||||
//Bukkit.getLogger().info("Lore: " + lore);
|
||||
net.minecraft.server.v1_12_R1.ItemStack stack = CraftItemStack.asNMSCopy(chestItem);
|
||||
// Pages
|
||||
NBTTagCompound tag = new NBTTagCompound(); //Create the NMS Stack's NBT (item data)
|
||||
tag.setString("title", title); //Set the book's title
|
||||
tag.setString("author", author);
|
||||
if (contents.containsKey("pages")) {
|
||||
NBTTagList pages = new NBTTagList();
|
||||
List<Tag> pagesTag = ((ListTag)contents.get("pages")).getValue();
|
||||
for (Tag s: pagesTag) {
|
||||
pages.add(new NBTTagString(((StringTag)s).getValue()));
|
||||
}
|
||||
tag.set("pages", pages); //Add the pages to the tag
|
||||
}
|
||||
stack.setTag(tag); //Apply the tag to the item
|
||||
chestItem = CraftItemStack.asCraftMirror(stack);
|
||||
ItemMeta bookMeta = (ItemMeta) chestItem.getItemMeta();
|
||||
bookMeta.setLore(lore);
|
||||
chestItem.setItemMeta(bookMeta);
|
||||
}
|
||||
return chestItem;
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.wasteofplastic.askyblock.nms.NMSAbstraction#setBlock(org.bukkit.block.Block, org.bukkit.inventory.ItemStack)
|
||||
*/
|
||||
@Override
|
||||
public void setFlowerPotBlock(final Block block, final ItemStack itemStack) {
|
||||
if (block.getType().equals(Material.FLOWER_POT)) {
|
||||
Location loc = block.getLocation();
|
||||
CraftWorld cw = (CraftWorld)block.getWorld();
|
||||
BlockPosition bp = new BlockPosition(loc.getX(), loc.getY(), loc.getZ());
|
||||
TileEntityFlowerPot te = (TileEntityFlowerPot)cw.getHandle().getTileEntity(bp);
|
||||
//Bukkit.getLogger().info("Debug: flowerpot materialdata = " + (new ItemStack(potItem, 1,(short) potItemData).toString()));
|
||||
net.minecraft.server.v1_12_R1.ItemStack cis = CraftItemStack.asNMSCopy(itemStack);
|
||||
te.setContents(cis);
|
||||
te.update();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.wasteofplastic.askyblock.nms.NMSAbstraction#isPotion(org.bukkit.inventory.ItemStack)
|
||||
*/
|
||||
@Override
|
||||
public boolean isPotion(ItemStack item) {
|
||||
//Bukkit.getLogger().info("DEBUG:item = " + item);
|
||||
if (item.getType().equals(Material.POTION)) {
|
||||
net.minecraft.server.v1_12_R1.ItemStack stack = CraftItemStack.asNMSCopy(item);
|
||||
NBTTagCompound tag = stack.getTag();
|
||||
//Bukkit.getLogger().info("DEBUG: tag is " + tag);
|
||||
//Bukkit.getLogger().info("DEBUG: display is " + tag.getString("display"));
|
||||
/*
|
||||
for (String list : tag.c()) {
|
||||
Bukkit.getLogger().info("DEBUG: list = " + list);
|
||||
}*/
|
||||
if (tag != null && (!tag.getString("Potion").equalsIgnoreCase("minecraft:water") || tag.getString("Potion").isEmpty())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.wasteofplastic.acidisland.nms.NMSAbstraction#setPotion(com.wasteofplastic.org.jnbt.Tag)
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked"})
|
||||
@Override
|
||||
public ItemStack setPotion(Material material, Tag itemTags, ItemStack chestItem) {
|
||||
Map<String,Tag> cont = (Map<String,Tag>) ((CompoundTag) itemTags).getValue();
|
||||
if (cont != null) {
|
||||
if (((CompoundTag) itemTags).getValue().containsKey("tag")) {
|
||||
Map<String,Tag> contents = (Map<String,Tag>)((CompoundTag) itemTags).getValue().get("tag").getValue();
|
||||
StringTag stringTag = ((StringTag)contents.get("Potion"));
|
||||
if (stringTag != null) {
|
||||
String tag = ((StringTag)contents.get("Potion")).getValue();
|
||||
//Bukkit.getLogger().info("DEBUG: potioninfo found: " + tag);
|
||||
net.minecraft.server.v1_12_R1.ItemStack stack = CraftItemStack.asNMSCopy(chestItem);
|
||||
NBTTagCompound tagCompound = stack.getTag();
|
||||
if(tagCompound == null){
|
||||
tagCompound = new NBTTagCompound();
|
||||
}
|
||||
tagCompound.setString("Potion", tag);
|
||||
stack.setTag(tagCompound);
|
||||
return CraftItemStack.asBukkitCopy(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Schematic is old, the potions do not have tags
|
||||
// Set it to zero so that the potion bottles don't look like giant purple and black blocks
|
||||
chestItem.setDurability((short)0);
|
||||
Bukkit.getLogger().warning("Potion in schematic is pre-V1.9 format and will just be water.");
|
||||
return chestItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get spawn egg
|
||||
* @param type
|
||||
* @param amount
|
||||
* @return
|
||||
*/
|
||||
public ItemStack getSpawnEgg(EntityType type, int amount) {
|
||||
//Bukkit.getLogger().info("DEBUG: setting spawn egg " + type.toString());
|
||||
ItemStack item = new ItemStack(Material.MONSTER_EGG, amount);
|
||||
net.minecraft.server.v1_12_R1.ItemStack stack = CraftItemStack.asNMSCopy(item);
|
||||
NBTTagCompound tagCompound = stack.getTag();
|
||||
if(tagCompound == null){
|
||||
tagCompound = new NBTTagCompound();
|
||||
}
|
||||
//Bukkit.getLogger().info("DEBUG: tag = " + tagCompound);
|
||||
NBTTagCompound id = new NBTTagCompound();
|
||||
if (!bToMConversion.containsKey(type)) {
|
||||
id.setString("id", "minecraft:" + type.toString().toLowerCase());
|
||||
} else {
|
||||
id.setString("id", "minecraft:" + bToMConversion.get(type));
|
||||
}
|
||||
tagCompound.set("EntityTag", id);
|
||||
stack.setTag(tagCompound);
|
||||
//Bukkit.getLogger().info("DEBUG: after tag = " + tagCompound);
|
||||
return CraftItemStack.asBukkitCopy(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
@ -29,5 +225,4 @@ public class NMSHandler implements NMSAbstraction{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_7_R3;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_7_R3
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_7_R4;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_7_R4
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_8_R1;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_8_R1
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_8_R2;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_8_R2
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_8_R3;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_8_R3
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_9_R1;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_9_R1
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package us.tastybento.bskyblock.util.nms.v1_9_R2;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import us.tastybento.bskyblock.util.nms.NMSAbstraction;
|
||||
|
||||
/**
|
||||
* NMS Handler for v1_9_R2
|
||||
*
|
||||
* @author Tastybento
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class NMSHandler implements NMSAbstraction{
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSubtitle(Player player, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
52
src/main/java/us/tastybento/org/jnbt/ByteArrayTag.java
Normal file
52
src/main/java/us/tastybento/org/jnbt/ByteArrayTag.java
Normal file
@ -0,0 +1,52 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Byte_Array</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ByteArrayTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final byte[] value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public ByteArrayTag(String name, byte[] value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder hex = new StringBuilder();
|
||||
for (byte b : 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.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Byte_Array" + append + ": " + hex.toString();
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/ByteTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/ByteTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Byte</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ByteTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final byte value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public ByteTag(String name, byte value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Byte" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
53
src/main/java/us/tastybento/org/jnbt/CompoundTag.java
Normal file
53
src/main/java/us/tastybento/org/jnbt/CompoundTag.java
Normal file
@ -0,0 +1,53 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Compound</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class CompoundTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final Map<String, Tag> value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public CompoundTag(String name, Map<String, Tag> value) {
|
||||
super(name);
|
||||
this.value = Collections.unmodifiableMap(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Tag> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("TAG_Compound" + append + ": " + value.size() + " entries\r\n{\r\n");
|
||||
for (Map.Entry<String, Tag> entry : value.entrySet()) {
|
||||
bldr.append(" " + entry.getValue().toString().replaceAll("\r\n", "\r\n ") + "\r\n");
|
||||
}
|
||||
bldr.append("}");
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/DoubleTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/DoubleTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Double</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class DoubleTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final double value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public DoubleTag(String name, double value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Double" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
28
src/main/java/us/tastybento/org/jnbt/EndTag.java
Normal file
28
src/main/java/us/tastybento/org/jnbt/EndTag.java
Normal file
@ -0,0 +1,28 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_End</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class EndTag extends Tag {
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*/
|
||||
public EndTag() {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TAG_End";
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/FloatTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/FloatTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Float</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class FloatTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final float value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public FloatTag(String name, float value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Float" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
60
src/main/java/us/tastybento/org/jnbt/IntArrayTag.java
Normal file
60
src/main/java/us/tastybento/org/jnbt/IntArrayTag.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package us.tastybento.org.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(String name, int[] value) {
|
||||
super(name);
|
||||
checkNotNull(value);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder hex = new StringBuilder();
|
||||
for (int b : value) {
|
||||
String hexDigits = Integer.toHexString(b).toUpperCase();
|
||||
if (hexDigits.length() == 1) {
|
||||
hex.append("0");
|
||||
}
|
||||
hex.append(hexDigits).append(" ");
|
||||
}
|
||||
return "TAG_Int_Array(" + hex + ")";
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/IntTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/IntTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Int</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class IntTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public IntTag(String name, int value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Int" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
70
src/main/java/us/tastybento/org/jnbt/ListTag.java
Normal file
70
src/main/java/us/tastybento/org/jnbt/ListTag.java
Normal file
@ -0,0 +1,70 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The <code>TAG_List</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ListTag extends Tag {
|
||||
|
||||
/**
|
||||
* The type.
|
||||
*/
|
||||
private final Class<? extends Tag> type;
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final List<Tag> value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param type
|
||||
* The type of item in the list.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public ListTag(String name, Class<? extends Tag> type, List<Tag> value) {
|
||||
super(name);
|
||||
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 type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("TAG_List" + append + ": " + value.size() + " entries of type " + NBTUtils.getTypeName(type) + "\r\n{\r\n");
|
||||
for (Tag t : value) {
|
||||
bldr.append(" " + t.toString().replaceAll("\r\n", "\r\n ") + "\r\n");
|
||||
}
|
||||
bldr.append("}");
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/LongTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/LongTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Long</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class LongTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final long value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public LongTag(String name, long value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Long" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
69
src/main/java/us/tastybento/org/jnbt/NBTConstants.java
Normal file
69
src/main/java/us/tastybento/org/jnbt/NBTConstants.java
Normal file
@ -0,0 +1,69 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* A class which holds constant values.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTConstants {
|
||||
|
||||
/**
|
||||
* The character set used by NBT (UTF-8).
|
||||
*/
|
||||
public static final Charset CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
/**
|
||||
* Tag type constants.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
172
src/main/java/us/tastybento/org/jnbt/NBTInputStream.java
Normal file
172
src/main/java/us/tastybento/org/jnbt/NBTInputStream.java
Normal file
@ -0,0 +1,172 @@
|
||||
package us.tastybento.org.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;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
||||
* streams, and produces an object graph of subclasses of the <code>Tag</code>
|
||||
* object.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The NBT format was created by Markus Persson, and the specification may be
|
||||
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
|
||||
* http://www.minecraft.net/docs/NBT.txt</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTInputStream implements Closeable {
|
||||
|
||||
/**
|
||||
* The data input stream.
|
||||
*/
|
||||
private final DataInputStream is;
|
||||
|
||||
/**
|
||||
* Creates a new <code>NBTInputStream</code>, 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) throws IOException {
|
||||
this.is = new DataInputStream(new GZIPInputStream(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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) throws IOException {
|
||||
int type = is.readByte() & 0xFF;
|
||||
|
||||
String name;
|
||||
if (type != NBTConstants.TYPE_END) {
|
||||
int nameLength = is.readShort() & 0xFFFF;
|
||||
byte[] nameBytes = new byte[nameLength];
|
||||
is.readFully(nameBytes);
|
||||
name = new String(nameBytes, NBTConstants.CHARSET);
|
||||
} else {
|
||||
name = "";
|
||||
}
|
||||
|
||||
return readTagPayload(type, name, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) throws IOException {
|
||||
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, is.readByte());
|
||||
case NBTConstants.TYPE_SHORT:
|
||||
return new ShortTag(name, is.readShort());
|
||||
case NBTConstants.TYPE_INT:
|
||||
return new IntTag(name, is.readInt());
|
||||
case NBTConstants.TYPE_LONG:
|
||||
return new LongTag(name, is.readLong());
|
||||
case NBTConstants.TYPE_FLOAT:
|
||||
return new FloatTag(name, is.readFloat());
|
||||
case NBTConstants.TYPE_DOUBLE:
|
||||
return new DoubleTag(name, is.readDouble());
|
||||
case NBTConstants.TYPE_BYTE_ARRAY:
|
||||
int length = is.readInt();
|
||||
byte[] bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return new ByteArrayTag(name, bytes);
|
||||
case NBTConstants.TYPE_STRING:
|
||||
length = is.readShort();
|
||||
bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
|
||||
case NBTConstants.TYPE_LIST:
|
||||
int childType = is.readByte();
|
||||
length = is.readInt();
|
||||
|
||||
List<Tag> tagList = new ArrayList<Tag>();
|
||||
for (int i = 0; i < length; i++) {
|
||||
Tag tag = readTagPayload(childType, "", depth + 1);
|
||||
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);
|
||||
if (tag instanceof EndTag) {
|
||||
break;
|
||||
} else {
|
||||
tagMap.put(tag.getName(), tag);
|
||||
}
|
||||
}
|
||||
|
||||
return new CompoundTag(name, tagMap);
|
||||
case NBTConstants.TYPE_INT_ARRAY:
|
||||
length = is.readInt();
|
||||
int[] data = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
data[i] = is.readInt();
|
||||
}
|
||||
return new IntArrayTag(name, data);
|
||||
|
||||
default:
|
||||
throw new IOException("Invalid tag type: " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
is.close();
|
||||
}
|
||||
|
||||
}
|
270
src/main/java/us/tastybento/org/jnbt/NBTOutputStream.java
Normal file
270
src/main/java/us/tastybento/org/jnbt/NBTOutputStream.java
Normal file
@ -0,0 +1,270 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
||||
* <code>Tag</code> objects to an underlying <code>OutputStream</code>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The NBT format was created by Markus Persson, and the specification may be
|
||||
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
|
||||
* http://www.minecraft.net/docs/NBT.txt</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class NBTOutputStream implements Closeable {
|
||||
|
||||
/**
|
||||
* The output stream.
|
||||
*/
|
||||
private final DataOutputStream os;
|
||||
|
||||
/**
|
||||
* Creates a new <code>NBTOutputStream</code>, 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) throws IOException {
|
||||
this.os = new DataOutputStream(new GZIPOutputStream(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);
|
||||
|
||||
os.writeByte(type);
|
||||
os.writeShort(nameBytes.length);
|
||||
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;
|
||||
default:
|
||||
throw new IOException("Invalid tag type: " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Byte</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeByteTagPayload(ByteTag tag) throws IOException {
|
||||
os.writeByte(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Byte_Array</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
|
||||
byte[] bytes = tag.getValue();
|
||||
os.writeInt(bytes.length);
|
||||
os.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Compound</code> 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);
|
||||
}
|
||||
os.writeByte((byte) 0); // end tag - better way?
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_List</code> 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();
|
||||
|
||||
os.writeByte(NBTUtils.getTypeCode(clazz));
|
||||
os.writeInt(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
writeTagPayload(tags.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_String</code> 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);
|
||||
os.writeShort(bytes.length);
|
||||
os.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Double</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
|
||||
os.writeDouble(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Float</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeFloatTagPayload(FloatTag tag) throws IOException {
|
||||
os.writeFloat(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Long</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeLongTagPayload(LongTag tag) throws IOException {
|
||||
os.writeLong(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Int</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeIntTagPayload(IntTag tag) throws IOException {
|
||||
os.writeInt(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Short</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeShortTagPayload(ShortTag tag) throws IOException {
|
||||
os.writeShort(tag.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>TAG_Empty</code> tag.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
private void writeEndTagPayload(EndTag tag) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
os.close();
|
||||
}
|
||||
|
||||
}
|
128
src/main/java/us/tastybento/org/jnbt/NBTUtils.java
Normal file
128
src/main/java/us/tastybento/org/jnbt/NBTUtils.java
Normal file
@ -0,0 +1,128 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* A class which contains NBT-related utility methods.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class 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 {
|
||||
throw new IllegalArgumentException("Invalid tag classs (" + 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 {
|
||||
throw new IllegalArgumentException("Invalid tag classs (" + 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;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid tag type : " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default private constructor.
|
||||
*/
|
||||
private NBTUtils() {
|
||||
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/ShortTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/ShortTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_Short</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class ShortTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final short value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public ShortTag(String name, short value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_Short" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/us/tastybento/org/jnbt/StringTag.java
Normal file
44
src/main/java/us/tastybento/org/jnbt/StringTag.java
Normal file
@ -0,0 +1,44 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* The <code>TAG_String</code> tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public final class StringTag extends Tag {
|
||||
|
||||
/**
|
||||
* The value.
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Creates the tag.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
* @param value
|
||||
* The value.
|
||||
*/
|
||||
public StringTag(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
String append = "";
|
||||
if (name != null && !name.equals("")) {
|
||||
append = "(\"" + this.getName() + "\")";
|
||||
}
|
||||
return "TAG_String" + append + ": " + value;
|
||||
}
|
||||
|
||||
}
|
42
src/main/java/us/tastybento/org/jnbt/Tag.java
Normal file
42
src/main/java/us/tastybento/org/jnbt/Tag.java
Normal file
@ -0,0 +1,42 @@
|
||||
package us.tastybento.org.jnbt;
|
||||
|
||||
/**
|
||||
* Represents a single NBT tag.
|
||||
*
|
||||
* @author Graham Edgecombe
|
||||
*
|
||||
*/
|
||||
public abstract class Tag {
|
||||
|
||||
/**
|
||||
* The name of this tag.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Creates the tag with the specified name.
|
||||
*
|
||||
* @param name
|
||||
* The name.
|
||||
*/
|
||||
public Tag(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this tag.
|
||||
*
|
||||
* @return The name of this tag.
|
||||
*/
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this tag.
|
||||
*
|
||||
* @return The value of this tag.
|
||||
*/
|
||||
public abstract Object getValue();
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user