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> <groupId>com.songoda</groupId>
<artifactId>UltimateStacker</artifactId> <artifactId>UltimateStacker</artifactId>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<version>2.1.5</version> <version>2.1.6</version>
<build> <build>
<defaultGoal>clean install</defaultGoal> <defaultGoal>clean install</defaultGoal>
<finalName>UltimateStacker-${project.version}</finalName> <finalName>UltimateStacker-${project.version}</finalName>
@ -118,7 +118,7 @@
<dependency> <dependency>
<groupId>com.songoda</groupId> <groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId> <artifactId>SongodaCore</artifactId>
<version>LATEST</version> <version>2.4.55</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<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.MySQLConnector;
import com.songoda.core.database.SQLiteConnector; import com.songoda.core.database.SQLiteConnector;
import com.songoda.core.gui.GuiManager; import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EntityStackerManager;
import com.songoda.core.hooks.HologramManager; import com.songoda.core.hooks.HologramManager;
import com.songoda.core.hooks.WorldGuardHook; import com.songoda.core.hooks.WorldGuardHook;
import com.songoda.core.utils.TextUtils; 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._1_InitialMigration;
import com.songoda.ultimatestacker.database.migrations._2_EntityStacks; import com.songoda.ultimatestacker.database.migrations._2_EntityStacks;
import com.songoda.ultimatestacker.database.migrations._3_BlockStacks; 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.StackerHook;
import com.songoda.ultimatestacker.hook.hooks.JobsHook; import com.songoda.ultimatestacker.hook.hooks.JobsHook;
import com.songoda.ultimatestacker.listeners.*; import com.songoda.ultimatestacker.listeners.*;
@ -196,6 +198,7 @@ public class UltimateStacker extends SongodaPlugin {
stackerHooks.add(new JobsHook()); stackerHooks.add(new JobsHook());
HologramManager.load(this); HologramManager.load(this);
EntityStackerManager.load();
// Database stuff, go! // Database stuff, go!
try { try {
@ -222,7 +225,8 @@ public class UltimateStacker extends SongodaPlugin {
this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager, this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
new _1_InitialMigration(), new _1_InitialMigration(),
new _2_EntityStacks(), new _2_EntityStacks(),
new _3_BlockStacks()); new _3_BlockStacks(),
new _4_DataPurge());
this.dataMigrationManager.runMigrations(); this.dataMigrationManager.runMigrations();
} }

View File

@ -46,8 +46,10 @@ public class CommandRemoveAll extends AbstractCommand {
for (Entity entityO : world.getEntities()) { for (Entity entityO : world.getEntities()) {
if (entityO instanceof Player) continue; 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(); entityO.remove();
plugin.getEntityStackManager().removeStack(entityO);
amountRemoved++; amountRemoved++;
} else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) { } else if (entityO.getType() == EntityType.DROPPED_ITEM && type.equalsIgnoreCase("items")) {
if (!UltimateStacker.hasCustomAmount((Item)entityO) && !all) 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.compatibility.CompatibleMaterial;
import com.songoda.core.database.DataManagerAbstract; import com.songoda.core.database.DataManagerAbstract;
import com.songoda.core.database.DatabaseConnector; import com.songoda.core.database.DatabaseConnector;
import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.block.BlockStack; import com.songoda.ultimatestacker.stackable.block.BlockStack;
import com.songoda.ultimatestacker.stackable.entity.ColdEntityStack; import com.songoda.ultimatestacker.stackable.entity.ColdEntityStack;
import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStack;
@ -16,6 +17,7 @@ import org.bukkit.plugin.Plugin;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -152,7 +154,7 @@ public class DataManager extends DataManagerAbstract {
public void updateHost(ColdEntityStack hostStack) { public void updateHost(ColdEntityStack hostStack) {
this.async(() -> this.databaseConnector.connect(connection -> { 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)) { try (PreparedStatement statement = connection.prepareStatement(updateHost)) {
if (hostStack.getHostUniqueId() == null) return; if (hostStack.getHostUniqueId() == null) return;
statement.setString(1, hostStack.getHostUniqueId().toString()); statement.setString(1, hostStack.getHostUniqueId().toString());
@ -225,9 +227,25 @@ public class DataManager extends DataManagerAbstract {
public void getEntities(Consumer<Map<Integer, ColdEntityStack>> callback) { public void getEntities(Consumer<Map<Integer, ColdEntityStack>> callback) {
this.async(() -> this.databaseConnector.connect(connection -> { this.async(() -> this.databaseConnector.connect(connection -> {
Map<Integer, ColdEntityStack> entities = new HashMap<>(); 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"; String selectEntities = "SELECT * FROM " + this.getTablePrefix() + "host_entities";
try (Statement statement = connection.createStatement()) { try (Statement statement = connection.createStatement()) {
ResultSet result = statement.executeQuery(selectEntities); 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.compatibility.CompatibleMaterial;
import com.songoda.core.nms.NmsManager; import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTItem; import com.songoda.core.nms.nbt.NBTItem;
import com.songoda.core.utils.PlayerUtils;
import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.events.SpawnerBreakEvent; import com.songoda.ultimatestacker.events.SpawnerBreakEvent;
import com.songoda.ultimatestacker.events.SpawnerPlaceEvent; import com.songoda.ultimatestacker.events.SpawnerPlaceEvent;
@ -65,7 +64,7 @@ public class BlockListeners implements Listener {
if (!isStacked) plugin.getDataManager().createBlock(stack); if (!isStacked) plugin.getDataManager().createBlock(stack);
if (stack.getMaterial() == CompatibleMaterial.getMaterial(inHand)) { if (stack.getMaterial() == CompatibleMaterial.getMaterial(inHand)) {
int amountToAdd = player.isSneaking() || Settings.ALWAYS_ADD_ALL.getBoolean() ? inHand.getAmount() : 1; int amountToAdd = player.isSneaking() || Settings.ALWAYS_ADD_ALL.getBoolean() ? inHand.getAmount() : 1;
if (!isStacked) amountToAdd ++; if (!isStacked) amountToAdd++;
stack.add(amountToAdd); stack.add(amountToAdd);
event.setCancelled(true); event.setCancelled(true);
if (player.getGameMode() != GameMode.CREATIVE) if (player.getGameMode() != GameMode.CREATIVE)
@ -162,7 +161,8 @@ public class BlockListeners implements Listener {
stack.setAmount(stack.getAmount() + itemAmount); stack.setAmount(stack.getAmount() + itemAmount);
plugin.updateHologram(stack); 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) { private boolean shouldDrop(LivingEntity entity, Material material) {
if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) { if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) {
if (Settings.DONT_DROP_ARMOR.getBoolean())
return false;
if (finalItems.containsKey(entity.getUniqueId())) { if (finalItems.containsKey(entity.getUniqueId())) {
List<ItemStack> items = finalItems.get(entity.getUniqueId()); List<ItemStack> items = finalItems.get(entity.getUniqueId());
for (ItemStack item : items) for (ItemStack item : items)
@ -94,7 +96,7 @@ public class DeathListeners implements Listener {
return true; return true;
} }
} }
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11) if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)
&& entity instanceof ChestedHorse && entity instanceof ChestedHorse
&& ((ChestedHorse) entity).getInventory().contains(material)) && ((ChestedHorse) entity).getInventory().contains(material))
return true; return true;

View File

@ -1,20 +1,21 @@
package com.songoda.ultimatestacker.listeners; package com.songoda.ultimatestacker.listeners;
import com.songoda.core.compatibility.CompatibleHand;
import com.songoda.core.compatibility.ServerVersion; import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager; import com.songoda.core.nms.NmsManager;
import com.songoda.core.utils.EntityUtils;
import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings; 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.SpawnerStack;
import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.utils.Methods; import org.bukkit.Bukkit;
import com.songoda.ultimatestacker.utils.ReflectionUtil;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; 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.entity.SpawnerSpawnEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.material.SpawnEgg; import org.bukkit.material.SpawnEgg;
import org.bukkit.metadata.FixedMetadataValue;
public class SpawnerListeners implements Listener { public class SpawnerListeners implements Listener {
private final UltimateStacker plugin; private final UltimateStacker plugin;
private static final boolean mcmmo = Bukkit.getPluginManager().isPluginEnabled("mcMMO");
public SpawnerListeners(UltimateStacker plugin) { public SpawnerListeners(UltimateStacker plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
@ -37,18 +41,39 @@ public class SpawnerListeners implements Listener {
if (!Settings.STACK_ENTITIES.getBoolean() if (!Settings.STACK_ENTITIES.getBoolean()
|| !plugin.spawnersEnabled() || !plugin.spawnersEnabled()
|| plugin.getStackingTask().isWorldDisabled(event.getLocation().getWorld())) return; || plugin.getStackingTask().isWorldDisabled(event.getLocation().getWorld())) return;
SpawnerStackManager spawnerStackManager = plugin.getSpawnerStackManager(); SpawnerStackManager spawnerStackManager = plugin.getSpawnerStackManager();
if (!spawnerStackManager.isSpawner(event.getSpawner().getLocation())) return; 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()); Location location = event.getSpawner().getLocation();
stack.createDuplicates(spawnerStack.calculateSpawnCount());
stack.updateStack();
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) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@ -92,7 +117,7 @@ public class SpawnerListeners implements Listener {
.replace("MOOSHROOM", "MUSHROOM_COW") .replace("MOOSHROOM", "MUSHROOM_COW")
.replace("ZOMBIE_PIGMAN", "PIG_ZOMBIE")); .replace("ZOMBIE_PIGMAN", "PIG_ZOMBIE"));
else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) { 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:")) if (str.contains("minecraft:"))
entityType = EntityType.fromName(str.substring(str.indexOf("minecraft:") + 10, str.indexOf("\"}"))); entityType = EntityType.fromName(str.substring(str.indexOf("minecraft:") + 10, str.indexOf("\"}")));
else else
@ -113,7 +138,7 @@ public class SpawnerListeners implements Listener {
} }
CreatureSpawner creatureSpawner = (CreatureSpawner) block.getState(); CreatureSpawner creatureSpawner = (CreatureSpawner) block.getState();
if (entityType == creatureSpawner.getSpawnedType()) { if (entityType == creatureSpawner.getSpawnedType()) {
plugin.getLocale().getMessage("event.egg.sametype") plugin.getLocale().getMessage("event.egg.sametype")
@ -125,8 +150,7 @@ public class SpawnerListeners implements Listener {
creatureSpawner.update(); creatureSpawner.update();
plugin.updateHologram(spawner); plugin.updateHologram(spawner);
if (player.getGameMode() != GameMode.CREATIVE) { if (player.getGameMode() != GameMode.CREATIVE)
Methods.takeItem(player, stackSize); 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, 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?"); "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() 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()), .filter(Check::isEnabledByDefault).map(Check::name).collect(Collectors.toList()),
"These are checks that are processed before an entity is stacked.", "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.", "List the entities using their plugin name as a prefix in all lowercase.",
"Example: mythicmobs_test"); "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, public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true,
"Should items be stacked?"); "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%", 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."); "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", 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 text displayed above a stacked spawner where {TYPE} refers to",
"The entities type and {AMT} is the amount currently stacked."); "The entities type and {AMT} is the amount currently stacked.");

View File

@ -111,6 +111,15 @@ public class EntityStack extends ColdEntityStack {
preStackedDrops.addAll(drops); 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); DropUtils.processStackedDrop(killed, preStackedDrops, event);
if (killed.getKiller() == null) return; if (killed.getKiller() == null) return;
@ -123,9 +132,6 @@ public class EntityStack extends ColdEntityStack {
killed.remove(); killed.remove();
LivingEntity newEntity = takeOneAndSpawnEntity(killed.getLocation()); 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. // In versions 1.14 and below experience is not dropping. Because of this we are doing this ourselves.
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_14)) { if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_14)) {
Location killedLocation = killed.getLocation(); Location killedLocation = killed.getLocation();

View File

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

View File

@ -1,32 +1,28 @@
package com.songoda.ultimatestacker.stackable.spawner; package com.songoda.ultimatestacker.stackable.spawner;
import com.songoda.core.compatibility.CompatibleMaterial; 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.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings; import com.songoda.ultimatestacker.settings.Settings;
import com.songoda.ultimatestacker.stackable.Hologramable; import com.songoda.ultimatestacker.stackable.Hologramable;
import com.songoda.ultimatestacker.utils.Methods; import com.songoda.ultimatestacker.utils.Methods;
import com.songoda.ultimatestacker.utils.ReflectionUtil;
import com.songoda.ultimatestacker.utils.Stackable; import com.songoda.ultimatestacker.utils.Stackable;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
import java.util.Random; import java.util.Random;
public class SpawnerStack implements Stackable, Hologramable { public class SpawnerStack extends SSpawner implements Stackable, Hologramable {
private int id; private int id;
private boolean initialized = false;
private final Location location;
private int amount; private int amount;
private static final UltimateStacker plugin = UltimateStacker.getInstance(); private static final UltimateStacker plugin = UltimateStacker.getInstance();
public SpawnerStack(Location location, int amount) { public SpawnerStack(Location location, int amount) {
this.location = location; super(location);
this.amount = amount; this.amount = amount;
} }
@ -45,23 +41,6 @@ public class SpawnerStack implements Stackable, Hologramable {
plugin.getDataManager().updateSpawner(this); 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() { public int calculateSpawnCount() {
Random random = new Random(); Random random = new Random();
int count = 0; int count = 0;
@ -114,13 +93,6 @@ public class SpawnerStack implements Stackable, Hologramable {
return location.getWorld(); return location.getWorld();
} }
public void initialize() {
if (!initialized) {
updateAmount();
this.initialized = true;
}
}
@Override @Override
public String toString() { public String toString() {
return "SpawnerStack:{" return "SpawnerStack:{"

View File

@ -130,17 +130,6 @@ public class Methods {
return TextUtils.formatText(nameFormat).trim(); 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) { public static ItemStack getSpawnerItem(EntityType entityType, int amount) {
ItemStack item = CompatibleMaterial.SPAWNER.getItem(); ItemStack item = CompatibleMaterial.SPAWNER.getItem();
ItemMeta meta = item.getItemMeta(); 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;
}
}
}