diff --git a/Essentials/pom.xml b/Essentials/pom.xml
index 53da3c172..50df4fb19 100644
--- a/Essentials/pom.xml
+++ b/Essentials/pom.xml
@@ -28,8 +28,22 @@
false
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 1.4
+
+
+ package
+
+ shade
+
+
+
+
+
BOSEconomy
@@ -77,7 +91,45 @@
net.milkbowl.vault
Vault
1.5.4
+ provided
+
+ net.ess3
+ NMSProvider
+ 2.0.1
+ compile
+
+
+ net.ess3
+ BlockMetaProvider
+ 2.0.1
+ compile
+
+
+ org.spigotmc
+ spigot-api
+
+
+
+
+ net.ess3
+ 1_8_R1Provider
+ 2.0.1
+ compile
+
+
+ org.bukkit
+ craftbukkit
+
+
+
+
+ net.ess3
+ LegacyProvider
+ 2.0.1
+ compile
+
+
diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java
index 6e4664172..1ec7f3c35 100644
--- a/Essentials/src/com/earth2me/essentials/Essentials.java
+++ b/Essentials/src/com/earth2me/essentials/Essentials.java
@@ -30,13 +30,14 @@ import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.DateUtil;
-import com.earth2me.essentials.utils.SpawnerUtil;
+import com.earth2me.essentials.utils.SpawnerProviderFactory;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import net.ess3.api.*;
import net.ess3.api.IEssentials;
import net.ess3.api.ISettings;
+import net.ess3.nms.SpawnerProvider;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
@@ -69,8 +70,6 @@ import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import static com.earth2me.essentials.I18n.tl;
@@ -96,7 +95,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient EssentialsTimer timer;
private final transient List vanishedPlayers = new ArrayList<>();
private transient Method oldGetOnlinePlayers;
- private transient SpawnerUtil spawnerUtil;
+ private transient SpawnerProvider spawnerProvider;
public Essentials() {
}
@@ -186,7 +185,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
execTimer.mark("Init(Worth/ItemDB)");
jails = new Jails(this);
confList.add(jails);
- spawnerUtil = new SpawnerUtil(this);
+ spawnerProvider = new SpawnerProviderFactory(this).getProvider();
reload();
} catch (YAMLException exception) {
if (pm.getPlugin("EssentialsUpdate") != null) {
@@ -746,8 +745,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
}
@Override
- public SpawnerUtil getSpawnerUtil() {
- return spawnerUtil;
+ public SpawnerProvider getSpawnerProvider() {
+ return spawnerProvider;
}
private static class EssentialsWorldListener implements Listener, Runnable {
diff --git a/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
index 59aab8c39..497afc41e 100644
--- a/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
+++ b/Essentials/src/com/earth2me/essentials/EssentialsBlockListener.java
@@ -36,7 +36,7 @@ public class EssentialsBlockListener implements Listener {
final BlockState blockState = event.getBlockPlaced().getState();
if (blockState instanceof CreatureSpawner) {
final CreatureSpawner spawner = (CreatureSpawner) blockState;
- final EntityType type = ess.getSpawnerUtil().getEntityType(event.getItemInHand());
+ final EntityType type = ess.getSpawnerProvider().getEntityType(event.getItemInHand());
if (type != null && Mob.fromBukkitType(type) != null) {
if (ess.getUser(event.getPlayer()).isAuthorized("essentials.spawnerconvert." + Mob.fromBukkitType(type).name().toLowerCase(Locale.ENGLISH))) {
spawner.setSpawnedType(type);
diff --git a/Essentials/src/com/earth2me/essentials/IEssentials.java b/Essentials/src/com/earth2me/essentials/IEssentials.java
index 34dd9e530..5da38fd50 100644
--- a/Essentials/src/com/earth2me/essentials/IEssentials.java
+++ b/Essentials/src/com/earth2me/essentials/IEssentials.java
@@ -6,7 +6,7 @@ import com.earth2me.essentials.api.IWarps;
import com.earth2me.essentials.metrics.Metrics;
import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.register.payment.Methods;
-import com.earth2me.essentials.utils.SpawnerUtil;
+import net.ess3.nms.SpawnerProvider;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -98,5 +98,5 @@ public interface IEssentials extends Plugin {
Iterable getOnlineUsers();
- SpawnerUtil getSpawnerUtil();
+ SpawnerProvider getSpawnerProvider();
}
diff --git a/Essentials/src/com/earth2me/essentials/ItemDb.java b/Essentials/src/com/earth2me/essentials/ItemDb.java
index e129a75ba..06cfcb928 100644
--- a/Essentials/src/com/earth2me/essentials/ItemDb.java
+++ b/Essentials/src/com/earth2me/essentials/ItemDb.java
@@ -139,7 +139,7 @@ public class ItemDb implements IConf, net.ess3.api.IItemDb {
retval.setAmount(mat.getMaxStackSize());
if (mat == Material.MOB_SPAWNER) {
try {
- ess.getSpawnerUtil().setEntityType(retval, EntityType.fromId(metaData));
+ ess.getSpawnerProvider().setEntityType(retval, EntityType.fromId(metaData));
} catch (IllegalArgumentException e) {
throw new Exception("Can't spawn entity ID " + metaData + " from mob spawners.");
}
diff --git a/Essentials/src/com/earth2me/essentials/utils/SpawnerProviderFactory.java b/Essentials/src/com/earth2me/essentials/utils/SpawnerProviderFactory.java
new file mode 100644
index 000000000..2613c25ad
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/utils/SpawnerProviderFactory.java
@@ -0,0 +1,36 @@
+package com.earth2me.essentials.utils;
+
+import com.earth2me.essentials.IEssentials;
+import net.ess3.nms.SpawnerProvider;
+import net.ess3.nms.blockmeta.BlockMetaSpawnerProvider;
+import net.ess3.nms.legacy.LegacyProvider;
+import net.ess3.nms.v1_8_R1.v1_8_R1SpawnerProvider;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class SpawnerProviderFactory {
+ private IEssentials ess;
+
+ public SpawnerProviderFactory(IEssentials ess) {
+ this.ess = ess;
+ }
+
+ public SpawnerProvider getProvider() {
+ List availableProviders = Arrays.asList(
+ new BlockMetaSpawnerProvider(),
+ new v1_8_R1SpawnerProvider(),
+ new LegacyProvider()
+ );
+ SpawnerProvider finalProvider = null;
+ for (SpawnerProvider provider : availableProviders) {
+ finalProvider = provider;
+ if (finalProvider.tryProvider()) {
+ break;
+ }
+ }
+ assert finalProvider != null;
+ ess.getLogger().info("Using " + finalProvider.getHumanName() + " as spawner provider.");
+ return finalProvider;
+ }
+}
diff --git a/Essentials/src/com/earth2me/essentials/utils/SpawnerUtil.java b/Essentials/src/com/earth2me/essentials/utils/SpawnerUtil.java
deleted file mode 100644
index 245b071d3..000000000
--- a/Essentials/src/com/earth2me/essentials/utils/SpawnerUtil.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.earth2me.essentials.utils;
-
-import com.google.common.collect.ImmutableMap;
-import net.ess3.api.IEssentials;
-import org.bukkit.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.block.BlockState;
-import org.bukkit.block.CreatureSpawner;
-import org.bukkit.entity.EntityType;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.BlockStateMeta;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.Map;
-
-public class SpawnerUtil {
- private boolean useMeta;
- private Map entityToDisplayName = ImmutableMap.builder()
- .put(EntityType.CAVE_SPIDER, "Cave Spider")
- .put(EntityType.PIG_ZOMBIE, "Zombie Pigman")
- .put(EntityType.MAGMA_CUBE, "Magma Cube")
- .put(EntityType.ENDER_DRAGON, "Ender Dragon")
- .put(EntityType.MUSHROOM_COW, "Mooshroom")
- .put(EntityType.SNOWMAN, "Snow Golem")
- .put(EntityType.OCELOT, "Ocelot")
- .put(EntityType.IRON_GOLEM, "Iron Golem")
- .put(EntityType.WITHER, "Wither")
- .put(EntityType.HORSE, "Horse")
- .build();
-
- public SpawnerUtil(IEssentials ess) {
- try {
- ItemStack is = new ItemStack(Material.MOB_SPAWNER, 1);
- ItemMeta meta = is.getItemMeta();
- useMeta = meta instanceof BlockStateMeta;
- } catch (Throwable e) {
- useMeta = false;
- }
- if (useMeta) {
- ess.getLogger().info("Using BlockStateMeta for spawners");
- } else {
- ess.getLogger().warning("Using legacy item data for spawners");
- ess.getLogger().warning(ChatColor.RED + "UPGRADE TO 1.8.3 OR HIGHER FOR WORKING SPAWNERS");
- }
- }
-
- public ItemStack setEntityType(ItemStack is, EntityType type) throws IllegalArgumentException {
- if (useMeta) {
- // Supported in 1.8.3-R0.1-SNAPSHOT and above
- BlockStateMeta bsm = (BlockStateMeta) is.getItemMeta();
- BlockState bs = bsm.getBlockState();
- ((CreatureSpawner) bs).setSpawnedType(type);
- bsm.setBlockState(bs);
- is.setItemMeta(bsm);
- } else {
- // Legacy behavior
- is.setDurability(type.getTypeId());
- }
- ItemMeta meta = is.getItemMeta();
- String displayName;
- if (entityToDisplayName.containsKey(type)) {
- displayName = entityToDisplayName.get(type);
- } else {
- displayName = type.getName();
- }
- meta.setDisplayName(ChatColor.RESET + displayName + " Spawner");
- is.setItemMeta(meta);
- return is;
- }
-
- public EntityType getEntityType(ItemStack is) {
- if (useMeta) {
- BlockStateMeta bsm = (BlockStateMeta) is.getItemMeta();
- CreatureSpawner bs = (CreatureSpawner) bsm.getBlockState();
- return bs.getSpawnedType();
- } else {
- return EntityType.fromId((int) is.getData().getData());
- }
- }
-}
diff --git a/README.md b/README.md
index 0fd982bf0..7ce5cb395 100644
--- a/README.md
+++ b/README.md
@@ -19,8 +19,6 @@ EssentialsX is almost a completely drop-in replacement for Essentials. However,
* **EssentialsX requires Java 7.**
-* **EssentialsX requires Spigot/CraftBukkit 1.8, 1.8.3+ recommended (for spawner support)**
-
Building
--------
To build with Maven, use the command
diff --git a/nms/1_8_R1Provider/.gitignore b/nms/1_8_R1Provider/.gitignore
new file mode 100644
index 000000000..415c5104f
--- /dev/null
+++ b/nms/1_8_R1Provider/.gitignore
@@ -0,0 +1 @@
+craftbukkit-*.jar
\ No newline at end of file
diff --git a/nms/1_8_R1Provider/README.md b/nms/1_8_R1Provider/README.md
new file mode 100644
index 000000000..a4a714ffb
--- /dev/null
+++ b/nms/1_8_R1Provider/README.md
@@ -0,0 +1 @@
+Put a 1.8 Spigot/CraftBukkit JAR with filename `craftbukkit-1.8-R0.1-SNAPSHOT.jar` in `lib/org/bukkit/craftbukkit/1.8-R0.1-SNAPSHOT`.
\ No newline at end of file
diff --git a/nms/1_8_R1Provider/pom.xml b/nms/1_8_R1Provider/pom.xml
new file mode 100644
index 000000000..f4e7233f1
--- /dev/null
+++ b/nms/1_8_R1Provider/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ EssentialsParent
+ net.ess3
+ 2.0.1
+ ../../pom.xml
+
+ 4.0.0
+
+ 1_8_R1Provider
+
+
+
+ project.local
+ local repo
+ file:${project.basedir}/lib
+
+
+
+
+
+ org.bukkit
+ craftbukkit
+ 1.8-R0.1-SNAPSHOT
+ provided
+
+
+ net.ess3
+ NMSProvider
+ 2.0.1
+
+
+
\ No newline at end of file
diff --git a/nms/1_8_R1Provider/src/net/ess3/nms/v1_8_R1/v1_8_R1SpawnerProvider.java b/nms/1_8_R1Provider/src/net/ess3/nms/v1_8_R1/v1_8_R1SpawnerProvider.java
new file mode 100644
index 000000000..9945ed552
--- /dev/null
+++ b/nms/1_8_R1Provider/src/net/ess3/nms/v1_8_R1/v1_8_R1SpawnerProvider.java
@@ -0,0 +1,45 @@
+package net.ess3.nms.v1_8_R1;
+
+import net.ess3.nms.SpawnerProvider;
+import net.minecraft.server.v1_8_R1.NBTTagCompound;
+import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.ItemStack;
+
+public class v1_8_R1SpawnerProvider extends SpawnerProvider {
+ @Override
+ public ItemStack setEntityType(ItemStack is, EntityType type) {
+ net.minecraft.server.v1_8_R1.ItemStack itemStack;
+ CraftItemStack craftStack = CraftItemStack.asCraftCopy(is);
+ itemStack = CraftItemStack.asNMSCopy(craftStack);
+ NBTTagCompound tag = itemStack.getTag();
+ if (tag == null) {
+ tag = new NBTTagCompound();
+ itemStack.setTag(tag);
+ }
+ if (!tag.hasKey("BlockEntityTag")) {
+ tag.set("BlockEntityTag", new NBTTagCompound());
+ }
+ tag = itemStack.getTag().getCompound("BlockEntityTag");
+ tag.setString("EntityId", type.getName());
+ return CraftItemStack.asCraftMirror(itemStack);
+ }
+
+ @Override
+ public EntityType getEntityType(ItemStack is) {
+ net.minecraft.server.v1_8_R1.ItemStack itemStack;
+ CraftItemStack craftStack = CraftItemStack.asCraftCopy(is);
+ itemStack = CraftItemStack.asNMSCopy(craftStack);
+ NBTTagCompound tag = itemStack.getTag();
+ if (tag == null || !tag.hasKey("BlockEntityTag")) {
+ throw new IllegalArgumentException();
+ }
+ String name = tag.getCompound("BlockEntityTag").getString("EntityId");
+ return EntityType.fromName(name);
+ }
+
+ @Override
+ public String getHumanName() {
+ return "CraftBukkit 1.8 NMS-based provider";
+ }
+}
diff --git a/nms/BlockMetaProvider/pom.xml b/nms/BlockMetaProvider/pom.xml
new file mode 100644
index 000000000..6cbac825c
--- /dev/null
+++ b/nms/BlockMetaProvider/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ EssentialsParent
+ net.ess3
+ 2.0.1
+ ../../pom.xml
+
+ 4.0.0
+
+ BlockMetaProvider
+
+
+
+ spigot-repo
+ https://hub.spigotmc.org/nexus/content/groups/public/
+
+
+
+
+
+ net.ess3
+ NMSProvider
+ 2.0.1
+
+
+ org.spigotmc
+ spigot-api
+ 1.8.7-R0.1-SNAPSHOT
+ provided
+
+
+
\ No newline at end of file
diff --git a/nms/BlockMetaProvider/src/net/ess3/nms/blockmeta/BlockMetaSpawnerProvider.java b/nms/BlockMetaProvider/src/net/ess3/nms/blockmeta/BlockMetaSpawnerProvider.java
new file mode 100644
index 000000000..1282fa461
--- /dev/null
+++ b/nms/BlockMetaProvider/src/net/ess3/nms/blockmeta/BlockMetaSpawnerProvider.java
@@ -0,0 +1,45 @@
+package net.ess3.nms.blockmeta;
+
+import net.ess3.nms.SpawnerProvider;
+import org.bukkit.ChatColor;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.CreatureSpawner;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.BlockStateMeta;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class BlockMetaSpawnerProvider extends SpawnerProvider {
+ @Override
+ public ItemStack setEntityType(ItemStack is, EntityType type) {
+ BlockStateMeta bsm = (BlockStateMeta) is.getItemMeta();
+ BlockState bs = bsm.getBlockState();
+ ((CreatureSpawner) bs).setSpawnedType(type);
+ bsm.setBlockState(bs);
+ is.setItemMeta(bsm);
+ // Legacy behavior
+ is.setDurability(type.getTypeId());
+ ItemMeta meta = is.getItemMeta();
+ String displayName;
+ if (entityToDisplayName.containsKey(type)) {
+ displayName = entityToDisplayName.get(type);
+ } else {
+ displayName = type.getName();
+ }
+ meta.setDisplayName(ChatColor.RESET + displayName + " Spawner");
+ is.setItemMeta(meta);
+ return is;
+ }
+
+ @Override
+ public EntityType getEntityType(ItemStack is) {
+ BlockStateMeta bsm = (BlockStateMeta) is.getItemMeta();
+ CreatureSpawner bs = (CreatureSpawner) bsm.getBlockState();
+ return bs.getSpawnedType();
+ }
+
+ @Override
+ public String getHumanName() {
+ return "1.8.3+ BlockStateMeta provider";
+ }
+}
diff --git a/nms/LegacyProvider/pom.xml b/nms/LegacyProvider/pom.xml
new file mode 100644
index 000000000..5b4e72f92
--- /dev/null
+++ b/nms/LegacyProvider/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ EssentialsParent
+ net.ess3
+ 2.0.1
+ ../../pom.xml
+
+ 4.0.0
+
+ LegacyProvider
+
+
+
+ net.ess3
+ NMSProvider
+ 2.0.1
+
+
+
\ No newline at end of file
diff --git a/nms/LegacyProvider/src/net/ess3/nms/legacy/LegacyProvider.java b/nms/LegacyProvider/src/net/ess3/nms/legacy/LegacyProvider.java
new file mode 100644
index 000000000..f6dc44d7d
--- /dev/null
+++ b/nms/LegacyProvider/src/net/ess3/nms/legacy/LegacyProvider.java
@@ -0,0 +1,34 @@
+package net.ess3.nms.legacy;
+
+import net.ess3.nms.SpawnerProvider;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class LegacyProvider extends SpawnerProvider {
+ @Override
+ public ItemStack setEntityType(ItemStack is, EntityType type) {
+ is.getData().setData((byte) type.getTypeId());
+ ItemMeta meta = is.getItemMeta();
+ String displayName;
+ if (entityToDisplayName.containsKey(type)) {
+ displayName = entityToDisplayName.get(type);
+ } else {
+ displayName = type.getName();
+ }
+ meta.setDisplayName(ChatColor.RESET + displayName + " Spawner");
+ is.setItemMeta(meta);
+ return is;
+ }
+
+ @Override
+ public EntityType getEntityType(ItemStack is) {
+ return EntityType.fromId((int) is.getData().getData());
+ }
+
+ @Override
+ public String getHumanName() {
+ return "legacy item data provider";
+ }
+}
diff --git a/nms/NMSProvider/pom.xml b/nms/NMSProvider/pom.xml
new file mode 100644
index 000000000..6293e142a
--- /dev/null
+++ b/nms/NMSProvider/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ EssentialsParent
+ net.ess3
+ 2.0.1
+ ../../pom.xml
+
+ 4.0.0
+
+ NMSProvider
+
\ No newline at end of file
diff --git a/nms/NMSProvider/src/net/ess3/nms/SpawnerProvider.java b/nms/NMSProvider/src/net/ess3/nms/SpawnerProvider.java
new file mode 100644
index 000000000..6bac641c3
--- /dev/null
+++ b/nms/NMSProvider/src/net/ess3/nms/SpawnerProvider.java
@@ -0,0 +1,38 @@
+package net.ess3.nms;
+
+import com.google.common.collect.ImmutableMap;
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.Map;
+
+public abstract class SpawnerProvider {
+ protected Map entityToDisplayName = ImmutableMap.builder()
+ .put(EntityType.CAVE_SPIDER, "Cave Spider")
+ .put(EntityType.PIG_ZOMBIE, "Zombie Pigman")
+ .put(EntityType.MAGMA_CUBE, "Magma Cube")
+ .put(EntityType.ENDER_DRAGON, "Ender Dragon")
+ .put(EntityType.MUSHROOM_COW, "Mooshroom")
+ .put(EntityType.SNOWMAN, "Snow Golem")
+ .put(EntityType.OCELOT, "Ocelot")
+ .put(EntityType.IRON_GOLEM, "Iron Golem")
+ .put(EntityType.WITHER, "Wither")
+ .put(EntityType.HORSE, "Horse")
+ .build();
+
+ public abstract ItemStack setEntityType(ItemStack is, EntityType type) throws IllegalArgumentException;
+ public abstract EntityType getEntityType(ItemStack is) throws IllegalArgumentException;
+ public abstract String getHumanName();
+
+ public boolean tryProvider() {
+ try {
+ EntityType type = EntityType.CREEPER;
+ ItemStack is = setEntityType(new ItemStack(Material.MOB_SPAWNER), type);
+ EntityType readType = getEntityType(is);
+ return type == readType;
+ } catch (Throwable t) {
+ return false;
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 71a1977a7..191afe888 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
http://repo.ess3.net/content/groups/public
- spigot-repo
+ bukkit-repo
https://hub.spigotmc.org/nexus/content/groups/public/
@@ -41,6 +41,10 @@
EssentialsProtect
EssentialsSpawn
EssentialsXMPP
+ nms/NMSProvider
+ nms/BlockMetaProvider
+ nms/1_8_R1Provider
+ nms/LegacyProvider
@@ -48,6 +52,7 @@
org.bukkit
bukkit
1.8.7-R0.1-SNAPSHOT
+ provided
junit
@@ -59,6 +64,7 @@
org.projectlombok
lombok
1.12.2
+ provided