Merge branch 'development'

This commit is contained in:
Brianna 2021-05-27 18:09:27 -05:00
commit 6906e25d50
14 changed files with 122 additions and 181 deletions

View File

@ -2,7 +2,7 @@
<groupId>com.songoda</groupId>
<artifactId>UltimateStacker</artifactId>
<modelVersion>4.0.0</modelVersion>
<version>2.1.5</version>
<version>2.1.6</version>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>UltimateStacker-${project.version}</finalName>
@ -118,7 +118,7 @@
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<version>LATEST</version>
<version>2.4.55</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -11,6 +11,7 @@ import com.songoda.core.database.DatabaseConnector;
import com.songoda.core.database.MySQLConnector;
import com.songoda.core.database.SQLiteConnector;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EntityStackerManager;
import com.songoda.core.hooks.HologramManager;
import com.songoda.core.hooks.WorldGuardHook;
import com.songoda.core.utils.TextUtils;
@ -25,6 +26,7 @@ import com.songoda.ultimatestacker.database.DataManager;
import com.songoda.ultimatestacker.database.migrations._1_InitialMigration;
import com.songoda.ultimatestacker.database.migrations._2_EntityStacks;
import com.songoda.ultimatestacker.database.migrations._3_BlockStacks;
import com.songoda.ultimatestacker.database.migrations._4_DataPurge;
import com.songoda.ultimatestacker.hook.StackerHook;
import com.songoda.ultimatestacker.hook.hooks.JobsHook;
import com.songoda.ultimatestacker.listeners.*;
@ -196,6 +198,7 @@ public class UltimateStacker extends SongodaPlugin {
stackerHooks.add(new JobsHook());
HologramManager.load(this);
EntityStackerManager.load();
// Database stuff, go!
try {
@ -222,7 +225,8 @@ public class UltimateStacker extends SongodaPlugin {
this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
new _1_InitialMigration(),
new _2_EntityStacks(),
new _3_BlockStacks());
new _3_BlockStacks(),
new _4_DataPurge());
this.dataMigrationManager.runMigrations();
}

View File

@ -46,8 +46,10 @@ public class CommandRemoveAll extends AbstractCommand {
for (Entity entityO : world.getEntities()) {
if (entityO instanceof Player) continue;
if (entityO instanceof LivingEntity && (stackManager.isStackedAndLoaded((LivingEntity)entityO) || all) && type.equalsIgnoreCase("entities")) {
if (entityO instanceof LivingEntity && (stackManager.isStackedAndLoaded((LivingEntity)entityO) || all)
&& type.equalsIgnoreCase("entities")) {
entityO.remove();
plugin.getEntityStackManager().removeStack(entityO);
amountRemoved++;
} else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) {
if (!UltimateStacker.hasCustomAmount((Item)entityO) && !all)

View File

@ -3,6 +3,7 @@ package com.songoda.ultimatestacker.database;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.database.DataManagerAbstract;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.block.BlockStack;
import com.songoda.ultimatestacker.stackable.entity.ColdEntityStack;
import com.songoda.ultimatestacker.stackable.entity.EntityStack;
@ -16,6 +17,7 @@ import org.bukkit.plugin.Plugin;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@ -152,7 +154,7 @@ public class DataManager extends DataManagerAbstract {
public void updateHost(ColdEntityStack hostStack) {
this.async(() -> this.databaseConnector.connect(connection -> {
String updateHost = "UPDATE " + this.getTablePrefix() + "host_entities SET uuid = ?, create_duplicates = ? WHERE id = ?";
String updateHost = "UPDATE " + this.getTablePrefix() + "host_entities SET uuid = ?, create_duplicates = ?, updated_at = current_timestamp WHERE id = ?";
try (PreparedStatement statement = connection.prepareStatement(updateHost)) {
if (hostStack.getHostUniqueId() == null) return;
statement.setString(1, hostStack.getHostUniqueId().toString());
@ -225,9 +227,25 @@ public class DataManager extends DataManagerAbstract {
public void getEntities(Consumer<Map<Integer, ColdEntityStack>> callback) {
this.async(() -> this.databaseConnector.connect(connection -> {
Map<Integer, ColdEntityStack> entities = new HashMap<>();
String selectOldEntities = "SELECT * FROM " + this.getTablePrefix() + "host_entities where updated_at <= date('now','-" + Settings.DATABASE_PURGE.getInt() + " day')";
try (Statement statement = connection.createStatement()) {
List<String> toDelete = new ArrayList<>();
ResultSet result = statement.executeQuery(selectOldEntities);
while (result.next()) {
int hostId = result.getInt("id");
toDelete.add(String.valueOf(hostId));
}
statement.execute("DELETE FROM " + this.getTablePrefix() + "host_entities where updated_at <= date('now','-" + Settings.DATABASE_PURGE.getInt() + " day')");
statement.execute("DELETE FROM " + this.getTablePrefix() + "stacked_entities where host IN (" + String.join(", ", toDelete) + ")");
} catch (Exception e) {
e.printStackTrace();
}
String selectEntities = "SELECT * FROM " + this.getTablePrefix() + "host_entities";
try (Statement statement = connection.createStatement()) {
ResultSet result = statement.executeQuery(selectEntities);

View File

@ -0,0 +1,23 @@
package com.songoda.ultimatestacker.database.migrations;
import com.songoda.core.database.DataMigration;
import com.songoda.core.database.MySQLConnector;
import com.songoda.ultimatestacker.UltimateStacker;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class _4_DataPurge extends DataMigration {
public _4_DataPurge() {
super(4);
}
@Override
public void migrate(Connection connection, String tablePrefix) throws SQLException {
try (Statement statement = connection.createStatement()) {
statement.execute("ALTER TABLE " + tablePrefix + "host_entities ADD COLUMN updated_at datetime DEFAULT NULL");
}
}
}

View File

@ -4,7 +4,6 @@ import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTItem;
import com.songoda.core.utils.PlayerUtils;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.events.SpawnerBreakEvent;
import com.songoda.ultimatestacker.events.SpawnerPlaceEvent;
@ -65,7 +64,7 @@ public class BlockListeners implements Listener {
if (!isStacked) plugin.getDataManager().createBlock(stack);
if (stack.getMaterial() == CompatibleMaterial.getMaterial(inHand)) {
int amountToAdd = player.isSneaking() || Settings.ALWAYS_ADD_ALL.getBoolean() ? inHand.getAmount() : 1;
if (!isStacked) amountToAdd ++;
if (!isStacked) amountToAdd++;
stack.add(amountToAdd);
event.setCancelled(true);
if (player.getGameMode() != GameMode.CREATIVE)
@ -162,7 +161,8 @@ public class BlockListeners implements Listener {
stack.setAmount(stack.getAmount() + itemAmount);
plugin.updateHologram(stack);
hand.takeItem(player);
if (player.getGameMode() != GameMode.CREATIVE)
hand.takeItem(player);
}
}
}

View File

@ -87,6 +87,8 @@ public class DeathListeners implements Listener {
private boolean shouldDrop(LivingEntity entity, Material material) {
if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) {
if (Settings.DONT_DROP_ARMOR.getBoolean())
return false;
if (finalItems.containsKey(entity.getUniqueId())) {
List<ItemStack> items = finalItems.get(entity.getUniqueId());
for (ItemStack item : items)
@ -94,7 +96,7 @@ public class DeathListeners implements Listener {
return true;
}
}
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)
&& entity instanceof ChestedHorse
&& ((ChestedHorse) entity).getInventory().contains(material))
return true;

View File

@ -1,20 +1,21 @@
package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.utils.EntityUtils;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.entity.EntityStack;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ReflectionUtil;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -23,11 +24,14 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.entity.SpawnerSpawnEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.material.SpawnEgg;
import org.bukkit.metadata.FixedMetadataValue;
public class SpawnerListeners implements Listener {
private final UltimateStacker plugin;
private static final boolean mcmmo = Bukkit.getPluginManager().isPluginEnabled("mcMMO");
public SpawnerListeners(UltimateStacker plugin) {
this.plugin = plugin;
}
@ -37,18 +41,39 @@ public class SpawnerListeners implements Listener {
if (!Settings.STACK_ENTITIES.getBoolean()
|| !plugin.spawnersEnabled()
|| plugin.getStackingTask().isWorldDisabled(event.getLocation().getWorld())) return;
SpawnerStackManager spawnerStackManager = plugin.getSpawnerStackManager();
if (!spawnerStackManager.isSpawner(event.getSpawner().getLocation())) return;
SpawnerStack spawnerStack = spawnerStackManager.getSpawner(event.getSpawner().getLocation());
Entity entity = event.getEntity();
if (entity.getType() == EntityType.FIREWORK) return;
if (entity.getVehicle() != null) {
entity.getVehicle().remove();
entity.remove();
}
spawnerStack.initialize();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
if (entity.getPassengers().size() != 0) {
for (Entity e : entity.getPassengers()) {
e.remove();
}
entity.remove();
}
}
entity.remove();
EntityStack stack = plugin.getEntityStackManager().addStack((LivingEntity)event.getEntity());
stack.createDuplicates(spawnerStack.calculateSpawnCount());
stack.updateStack();
Location location = event.getSpawner().getLocation();
plugin.getStackingTask().attemptSplit(stack, (LivingEntity) event.getEntity());
SpawnerStack spawnerStack = spawnerStackManager.getSpawner(location);
spawnerStack.spawn(spawnerStack.calculateSpawnCount(), "EXPLOSION_NORMAL", null, (e) -> {
if (Settings.NO_AI.getBoolean())
EntityUtils.setUnaware(e);
if (mcmmo)
entity.setMetadata("mcMMO: Spawned Entity", new FixedMetadataValue(plugin, true));
return true;
}, event.getEntityType());
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -92,7 +117,7 @@ public class SpawnerListeners implements Listener {
.replace("MOOSHROOM", "MUSHROOM_COW")
.replace("ZOMBIE_PIGMAN", "PIG_ZOMBIE"));
else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) {
String str = ReflectionUtil.getNBTTagCompound(ReflectionUtil.getNMSItemStack(event.getItem())).toString();
String str = NmsManager.getNbt().of(event.getItem()).toString();
if (str.contains("minecraft:"))
entityType = EntityType.fromName(str.substring(str.indexOf("minecraft:") + 10, str.indexOf("\"}")));
else
@ -113,7 +138,7 @@ public class SpawnerListeners implements Listener {
}
CreatureSpawner creatureSpawner = (CreatureSpawner) block.getState();
CreatureSpawner creatureSpawner = (CreatureSpawner) block.getState();
if (entityType == creatureSpawner.getSpawnedType()) {
plugin.getLocale().getMessage("event.egg.sametype")
@ -125,8 +150,7 @@ public class SpawnerListeners implements Listener {
creatureSpawner.update();
plugin.updateHologram(spawner);
if (player.getGameMode() != GameMode.CREATIVE) {
Methods.takeItem(player, stackSize);
}
if (player.getGameMode() != GameMode.CREATIVE)
CompatibleHand.getHand(event).takeItem(player, stackSize);
}
}

View File

@ -88,6 +88,9 @@ public class Settings {
public static final ConfigSetting NO_EXP_INSTANT_KILL = new ConfigSetting(config, "Entities.No Exp For Instant Kills", false,
"Should no experience be dropped when an instant kill is performed?");
public static final ConfigSetting DONT_DROP_ARMOR = new ConfigSetting(config, "Entities.Dont Drop Armor", false,
"Should entities not drop their armor when custom drops are enabled?");
public static final ConfigSetting STACK_CHECKS = new ConfigSetting(config, "Entities.Stack Checks", Arrays.asList(Check.values()).stream()
.filter(Check::isEnabledByDefault).map(Check::name).collect(Collectors.toList()),
"These are checks that are processed before an entity is stacked.",
@ -161,6 +164,11 @@ public class Settings {
"List the entities using their plugin name as a prefix in all lowercase.",
"Example: mythicmobs_test");
public static final ConfigSetting DATABASE_PURGE = new ConfigSetting(config, "Entities.Database purge", 14,
"How many days must an entity be dormant before it is removed",
"from the database? This setting will prevent dead entities killed incorrectly",
"by other plugins from building up inside of your database and creating lag.");
public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true,
"Should items be stacked?");
@ -231,6 +239,9 @@ public class Settings {
public static final ConfigSetting EXPLOSION_DROP_CHANCE_CREEPER = new ConfigSetting(config, "Spawners.Chance On Creeper Explosion", "100%",
"Chance of a creeper explosion dropping a spawner.");
public static final ConfigSetting NO_AI = new ConfigSetting(config, "Spawners.Nerf Spawner Mobs", false,
"If enabled mobs spawned by spawners will not move or attack.");
public static final ConfigSetting NAME_FORMAT_SPAWNER = new ConfigSetting(config, "Spawners.Name Format", "&f{TYPE} Spawner &6{AMT}x",
"The text displayed above a stacked spawner where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked.");

View File

@ -111,6 +111,15 @@ public class EntityStack extends ColdEntityStack {
preStackedDrops.addAll(drops);
}
// In versions 1.14 and below experience is not dropping. Because of this we are doing this ourselves.
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_14)) {
Location killedLocation = killed.getLocation();
if (droppedExp > 0)
killedLocation.getWorld().spawn(killedLocation, ExperienceOrb.class).setExperience(droppedExp * getAmount());
} else {
event.setDroppedExp(droppedExp * getAmount());
}
DropUtils.processStackedDrop(killed, preStackedDrops, event);
if (killed.getKiller() == null) return;
@ -123,9 +132,6 @@ public class EntityStack extends ColdEntityStack {
killed.remove();
LivingEntity newEntity = takeOneAndSpawnEntity(killed.getLocation());
//if (!EntityUtils.isAware(killed))
// EntityUtils.setUnaware(newEntity);
// In versions 1.14 and below experience is not dropping. Because of this we are doing this ourselves.
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_14)) {
Location killedLocation = killed.getLocation();

View File

@ -135,6 +135,7 @@ public class EntityStackManager {
EntityStack stack = new EntityStack(entity, coldStack);
stack.updateStack();
stacks.put(entity.getUniqueId(), stack);
plugin.getDataManager().updateHost(coldStack);
}
public void unloadStack(LivingEntity entity) {

View File

@ -1,32 +1,28 @@
package com.songoda.ultimatestacker.stackable.spawner;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.world.SSpawner;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.Hologramable;
import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ReflectionUtil;
import com.songoda.ultimatestacker.utils.Stackable;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.CreatureSpawner;
import java.util.Random;
public class SpawnerStack implements Stackable, Hologramable {
public class SpawnerStack extends SSpawner implements Stackable, Hologramable {
private int id;
private boolean initialized = false;
private final Location location;
private int amount;
private static final UltimateStacker plugin = UltimateStacker.getInstance();
public SpawnerStack(Location location, int amount) {
this.location = location;
super(location);
this.amount = amount;
}
@ -45,23 +41,6 @@ public class SpawnerStack implements Stackable, Hologramable {
plugin.getDataManager().updateSpawner(this);
}
public void updateAmount() {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (!(location.getBlock().getState() instanceof CreatureSpawner)) return;
int count = Settings.STACK_ENTITIES.getBoolean()
&& !plugin.getStackingTask().isWorldDisabled(location.getWorld()) ? 1 : calculateSpawnCount();
int maxNearby = amount > 6 ? amount + 3 : 6;
CreatureSpawner creatureSpawner = (CreatureSpawner) location.getBlock().getState();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) {
creatureSpawner.setMaxNearbyEntities(maxNearby);
creatureSpawner.setSpawnCount(count);
} else {
ReflectionUtil.updateSpawner(creatureSpawner, count, maxNearby);
}
creatureSpawner.update();
}, 1L);
}
public int calculateSpawnCount() {
Random random = new Random();
int count = 0;
@ -114,13 +93,6 @@ public class SpawnerStack implements Stackable, Hologramable {
return location.getWorld();
}
public void initialize() {
if (!initialized) {
updateAmount();
this.initialized = true;
}
}
@Override
public String toString() {
return "SpawnerStack:{"

View File

@ -130,17 +130,6 @@ public class Methods {
return TextUtils.formatText(nameFormat).trim();
}
public static void takeItem(Player player, int amount) {
if (player.getGameMode() == GameMode.CREATIVE) return;
ItemStack item = player.getInventory().getItemInHand();
int result = item.getAmount() - amount;
item.setAmount(result);
player.setItemInHand(result > 0 ? item : null);
}
public static ItemStack getSpawnerItem(EntityType entityType, int amount) {
ItemStack item = CompatibleMaterial.SPAWNER.getItem();
ItemMeta meta = item.getItemMeta();

View File

@ -1,111 +0,0 @@
package com.songoda.ultimatestacker.utils;
import org.bukkit.Bukkit;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionUtil {
private static Class<?> clazzCraftCreatureSpawner, clazzTileEntityMobSpawner = null;
private static Method methodGetTileEntity, methodGetSpawner;
private static Field fieldSpawnount, fieldMaxNearbyEntities, fieldSpawner;
public static CreatureSpawner updateSpawner(CreatureSpawner creatureSpawner, int count, int max) {
if (!Bukkit.getServer().getClass().getPackage().getName().contains("1.8")) {
try {
if (creatureSpawner == null) return null;
if (clazzCraftCreatureSpawner == null) {
String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23);
clazzCraftCreatureSpawner = Class.forName("org.bukkit.craftbukkit." + ver + ".block.CraftCreatureSpawner");
clazzTileEntityMobSpawner = Class.forName("net.minecraft.server." + ver + ".TileEntityMobSpawner");
Class<?> clazzMobSpawnerAbstract = Class.forName("net.minecraft.server." + ver + ".MobSpawnerAbstract");
methodGetTileEntity = clazzCraftCreatureSpawner.getDeclaredMethod("getTileEntity");
methodGetSpawner = clazzTileEntityMobSpawner.getDeclaredMethod("getSpawner");
fieldSpawnount = clazzMobSpawnerAbstract.getDeclaredField("spawnCount");
fieldSpawnount.setAccessible(true);
fieldMaxNearbyEntities = clazzMobSpawnerAbstract.getDeclaredField("maxNearbyEntities");
fieldMaxNearbyEntities.setAccessible(true);
}
Object objCraftCreatureSpawner = clazzCraftCreatureSpawner.cast(creatureSpawner);
Object objTileEntityMobSpawner = clazzTileEntityMobSpawner.cast(methodGetTileEntity.invoke(objCraftCreatureSpawner));
Object objMobSpawnerAbstract = methodGetSpawner.invoke(objTileEntityMobSpawner);
fieldSpawnount.set(objMobSpawnerAbstract, count);
fieldMaxNearbyEntities.set(objMobSpawnerAbstract, max);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return creatureSpawner;
} else {
try {
if (clazzCraftCreatureSpawner == null) {
String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23);
clazzCraftCreatureSpawner = Class.forName("org.bukkit.craftbukkit." + ver + ".block.CraftCreatureSpawner");
clazzTileEntityMobSpawner = Class.forName("net.minecraft.server." + ver + ".TileEntityMobSpawner");
Class<?> clazzMobSpawnerAbstract = Class.forName("net.minecraft.server." + ver + ".MobSpawnerAbstract");
methodGetSpawner = clazzTileEntityMobSpawner.getDeclaredMethod("getSpawner");
fieldSpawner = clazzCraftCreatureSpawner.getDeclaredField("spawner");
fieldSpawner.setAccessible(true);
fieldSpawnount = clazzMobSpawnerAbstract.getDeclaredField("spawnCount");
fieldSpawnount.setAccessible(true);
fieldMaxNearbyEntities = clazzMobSpawnerAbstract.getDeclaredField("maxNearbyEntities");
fieldMaxNearbyEntities.setAccessible(true);
}
Object objcraftCreatureSpawner = clazzCraftCreatureSpawner.cast(creatureSpawner);
Object objTileEntityMobSpawner = fieldSpawner.get(objcraftCreatureSpawner);
Object objMobSpawnerAbstract = methodGetSpawner.invoke(objTileEntityMobSpawner);
fieldSpawnount.set(objMobSpawnerAbstract, count);
fieldMaxNearbyEntities.set(objMobSpawnerAbstract, max);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return creatureSpawner;
}
}
public static Object getNMSItemStack(ItemStack item) {
Class<?> cis = getCraftItemStack();
java.lang.reflect.Method methodAsNMSCopy;
try {
methodAsNMSCopy = cis.getMethod("asNMSCopy", ItemStack.class);
Object answer = methodAsNMSCopy.invoke(cis, item);
return answer;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static Object getNBTTagCompound(Object nmsitem) {
Class<?> c = nmsitem.getClass();
java.lang.reflect.Method methodGetTag;
try {
methodGetTag = c.getMethod("getTag");
return methodGetTag.invoke(nmsitem);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static Class<?> getCraftItemStack() {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
try {
return Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack");
} catch (Exception ex) {
System.out.println("Error in ItemNBTAPI! (Outdated plugin?)");
ex.printStackTrace();
return null;
}
}
}