2018-11-06 04:33:10 +01:00
|
|
|
package com.songoda.ultimatestacker.tasks;
|
|
|
|
|
|
|
|
import com.songoda.ultimatestacker.UltimateStacker;
|
|
|
|
import com.songoda.ultimatestacker.entity.EntityStack;
|
|
|
|
import com.songoda.ultimatestacker.entity.EntityStackManager;
|
|
|
|
import com.songoda.ultimatestacker.utils.Methods;
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.configuration.ConfigurationSection;
|
2018-11-08 04:26:38 +01:00
|
|
|
import org.bukkit.entity.*;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.Method;
|
2018-11-08 04:26:38 +01:00
|
|
|
import java.util.ArrayList;
|
2018-11-06 04:33:10 +01:00
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
public class StackingTask extends BukkitRunnable {
|
|
|
|
|
|
|
|
private final UltimateStacker instance;
|
|
|
|
|
|
|
|
private Class<?> clazzItemStack, clazzItem, clazzCraftItemStack;
|
|
|
|
|
|
|
|
private Method methodGetItem, methodAsNMSCopy;
|
|
|
|
|
|
|
|
private Field fieldMaxStackSize;
|
|
|
|
|
|
|
|
public StackingTask(UltimateStacker instance) {
|
|
|
|
this.instance = instance;
|
|
|
|
try {
|
|
|
|
String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23);
|
|
|
|
clazzCraftItemStack = Class.forName("org.bukkit.craftbukkit." + ver + ".inventory.CraftItemStack");
|
|
|
|
clazzItemStack = Class.forName("net.minecraft.server." + ver + ".ItemStack");
|
|
|
|
clazzItem = Class.forName("net.minecraft.server." + ver + ".Item");
|
|
|
|
|
|
|
|
methodAsNMSCopy = clazzCraftItemStack.getMethod("asNMSCopy", ItemStack.class);
|
|
|
|
methodGetItem = clazzItemStack.getDeclaredMethod("getItem");
|
|
|
|
|
|
|
|
fieldMaxStackSize = clazzItem.getDeclaredField("maxStackSize");
|
|
|
|
fieldMaxStackSize.setAccessible(true);
|
|
|
|
} catch (ReflectiveOperationException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
int maxItemStackSize = instance.getConfig().getInt("Item.Max Stack Size");
|
|
|
|
int maxEntityStackSize = instance.getConfig().getInt("Entity.Max Stack Size");
|
|
|
|
|
|
|
|
EntityStackManager stackManager = instance.getEntityStackManager();
|
|
|
|
for (World world : Bukkit.getWorlds()) {
|
|
|
|
|
|
|
|
nextEntity:
|
|
|
|
for (Entity entityO : world.getEntities()) {
|
2018-12-03 01:28:08 +01:00
|
|
|
if (entityO == null || entityO instanceof Player) continue;
|
2018-11-08 04:26:38 +01:00
|
|
|
|
2018-11-06 06:09:40 +01:00
|
|
|
if (entityO instanceof Item && instance.getConfig().getBoolean("Main.Stack Items")) {
|
2018-11-06 04:33:10 +01:00
|
|
|
ItemStack item = ((Item) entityO).getItemStack();
|
|
|
|
|
2018-12-03 01:28:08 +01:00
|
|
|
if (entityO.hasMetadata("grabbed")
|
|
|
|
|| item == null
|
2019-01-10 21:27:01 +01:00
|
|
|
|| entityO.isCustomNameVisible() && !entityO.getCustomName().contains(Methods.convertToInvisibleString("IS"))
|
2018-12-03 01:28:08 +01:00
|
|
|
|| item.hasItemMeta() && item.getItemMeta().hasDisplayName())
|
2018-11-06 06:09:40 +01:00
|
|
|
continue;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2018-11-10 07:02:59 +01:00
|
|
|
int specific = instance.getItemFile().getConfig().getInt("Items." + item.getType().name() + ".Max Stack Size");
|
2018-11-10 19:44:29 +01:00
|
|
|
int max = specific == -1 && new ItemStack(item.getType()).getMaxStackSize() != 1 ? maxItemStackSize : specific;
|
|
|
|
|
|
|
|
if (max == -1) max = 1;
|
2018-11-10 07:02:59 +01:00
|
|
|
|
|
|
|
if (item.getMaxStackSize() != max && item.getMaxStackSize() != 1 && (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName()))
|
|
|
|
setMax(item, max, false);
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
int size = item.getAmount();
|
|
|
|
|
2019-01-10 21:27:01 +01:00
|
|
|
String name = Methods.convertToInvisibleString("IS") + Methods.compileItemName(item.getType(), size);
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
if (instance.getItemFile().getConfig().getBoolean("Items." + item.getType().name() + ".Has Hologram")) {
|
|
|
|
entityO.setCustomName(name);
|
|
|
|
entityO.setCustomNameVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(entityO instanceof LivingEntity) || !instance.getConfig().getBoolean("Main.Stack Entities"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
LivingEntity initalEntity = (LivingEntity) entityO;
|
|
|
|
|
|
|
|
if (initalEntity.isDead()
|
|
|
|
|| !initalEntity.isValid()
|
2018-12-17 19:32:57 +01:00
|
|
|
|| initalEntity instanceof ArmorStand
|
|
|
|
|| initalEntity.hasMetadata("inLove")) continue;
|
2018-11-08 04:26:38 +01:00
|
|
|
|
|
|
|
EntityStack initialStack = stackManager.getStack(initalEntity);
|
|
|
|
if (initialStack == null && initalEntity.getCustomName() != null) continue;
|
|
|
|
int amtToStack = initialStack != null ? initialStack.getAmount() : 1;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
ConfigurationSection configurationSection = UltimateStacker.getInstance().getMobFile().getConfig();
|
|
|
|
|
|
|
|
if (!configurationSection.getBoolean("Mobs." + initalEntity.getType().name() + ".Enabled"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (configurationSection.getInt("Mobs." + initalEntity.getType().name() + ".Max Stack Size") != -1)
|
|
|
|
maxEntityStackSize = configurationSection.getInt("Mobs." + initalEntity.getType().name() + ".Max Stack Size");
|
|
|
|
|
|
|
|
List<Entity> entityList = Methods.getSimilarEntitesAroundEntity(initalEntity);
|
|
|
|
|
2018-11-08 04:26:38 +01:00
|
|
|
for (Entity entity : new ArrayList<>(entityList)) {
|
2018-11-06 04:33:10 +01:00
|
|
|
EntityStack stack = stackManager.getStack(entity);
|
2018-11-08 04:26:38 +01:00
|
|
|
if (stack == null && entity.getCustomName() != null) {
|
|
|
|
entityList.remove(entity);
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-06 04:33:10 +01:00
|
|
|
|
|
|
|
//If a stack was found add 1 to this stack.
|
2018-11-08 04:26:38 +01:00
|
|
|
if (stack != null && (stack.getAmount() + amtToStack) <= maxEntityStackSize) {
|
|
|
|
stack.addAmount(amtToStack);
|
2018-11-06 04:33:10 +01:00
|
|
|
stack.updateStack();
|
|
|
|
initalEntity.remove();
|
|
|
|
continue nextEntity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-08 04:26:38 +01:00
|
|
|
if (initialStack != null) continue;
|
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
entityList.removeIf(stackManager::isStacked);
|
|
|
|
|
|
|
|
if (entityList.size() < instance.getConfig().getInt("Entity.Min Stack Amount") - 1) continue;
|
|
|
|
|
|
|
|
//If stack was never found make a new one.
|
|
|
|
EntityStack stack = stackManager.addStack(new EntityStack(initalEntity, entityList.size() + 1));
|
|
|
|
|
|
|
|
for (Entity entity : entityList) {
|
|
|
|
if (stackManager.isStacked(entity)) continue;
|
|
|
|
entity.remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
stack.updateStack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-10 07:02:59 +01:00
|
|
|
public ItemStack setMax(ItemStack item, int max, boolean reset) {
|
2018-11-06 04:33:10 +01:00
|
|
|
try {
|
|
|
|
Object objItemStack = methodGetItem.invoke(methodAsNMSCopy.invoke(null, item));
|
2018-11-10 07:02:59 +01:00
|
|
|
fieldMaxStackSize.set(objItemStack, reset ? new ItemStack(item.getType()).getMaxStackSize() : max);
|
2018-11-06 06:09:40 +01:00
|
|
|
} catch (ReflectiveOperationException e) {
|
2018-11-06 04:33:10 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void startTask() {
|
|
|
|
new StackingTask(instance).runTaskTimer(instance, 0, instance.getConfig().getInt("Main.Stack Search Tick Speed"));
|
|
|
|
}
|
|
|
|
}
|