forked from stefatorus/LagAssist
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
387 lines
9.1 KiB
387 lines
9.1 KiB
package com.entryrise.lagassist.hoppers;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.Chunk;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockState;
|
|
import org.bukkit.block.Hopper;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.Item;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
|
import org.bukkit.inventory.Inventory;
|
|
import org.bukkit.inventory.ItemFlag;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
|
|
import com.entryrise.lagassist.Data;
|
|
import com.entryrise.lagassist.Main;
|
|
import com.entryrise.lagassist.utils.Cache;
|
|
import com.entryrise.lagassist.utils.Others;
|
|
import com.entryrise.lagassist.utils.V1_12;
|
|
import com.entryrise.lagassist.utils.V1_13;
|
|
import com.entryrise.lagassist.utils.V1_8;
|
|
import com.entryrise.lagassist.utils.VersionMgr;
|
|
|
|
public class ChunkHoppers implements Listener {
|
|
|
|
// The Cachetime represents how often the cache should be removed
|
|
// and the tiles rechecked.
|
|
|
|
private static Cache<Chunk, BlockState[]> tilecache = new Cache<Chunk, BlockState[]>(40);
|
|
|
|
public static boolean mobhoppers;
|
|
private static double multiplier;
|
|
private static List<String> reasons;
|
|
|
|
private static String hoppermode;
|
|
public static String customname;
|
|
|
|
private static Item dropplayer;
|
|
|
|
private class HopperComparator implements Comparator<Hopper> {
|
|
|
|
Location initial;
|
|
|
|
public HopperComparator(Location initial) {
|
|
this.initial = initial;
|
|
}
|
|
|
|
@Override
|
|
public int compare(Hopper h1, Hopper h2) {
|
|
return (int) h1.getLocation().distance(initial) - (int) h2.getLocation().distance(initial);
|
|
}
|
|
|
|
}
|
|
|
|
public static void Enabler(boolean reload) {
|
|
hoppermode = Main.config.getString("hopper-check.chunk-hoppers.mode");
|
|
mobhoppers = Main.config.getDouble("hopper-check.chunk-hoppers.mob-hopper.maxtps") >= 20;
|
|
multiplier = Main.config.getDouble("hopper-check.chunk-hoppers.mob-hopper.multiplier");
|
|
reasons = Main.config.getStringList("hopper-check.chunk-hoppers.mob-hopper.spawn-reasons");
|
|
|
|
customname = ChatColor.translateAlternateColorCodes('&',
|
|
Main.config.getString("hopper-check.chunk-hoppers.define"));
|
|
|
|
tilecache.clear();
|
|
|
|
if (!reload) {
|
|
Main.p.getServer().getPluginManager().registerEvents(new ChunkHoppers(), Main.p);
|
|
runTask();
|
|
}
|
|
|
|
HopperFilter.Enabler(reload);
|
|
SellHoppers.Enabler(reload);
|
|
}
|
|
|
|
private static void runTask() {
|
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.p, new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
tilecache.tick();
|
|
}
|
|
}, 1L, 1L);
|
|
}
|
|
|
|
public static void giveChunkHopper(Player p, int amount) {
|
|
Inventory inv = p.getInventory();
|
|
ItemStack itm = getCustomHopper(amount);
|
|
|
|
int empty = inv.firstEmpty();
|
|
|
|
if (empty == -1) {
|
|
p.getLocation().getWorld().dropItem(p.getLocation(), itm);
|
|
return;
|
|
}
|
|
|
|
p.getInventory().addItem(itm);
|
|
}
|
|
|
|
private static Material getMaterial(EntityType et) {
|
|
String loc = "hopper-check.chunk-hoppers.mob-hopper.filter-items." + et.toString().toLowerCase();
|
|
if (!Main.config.contains(loc)) {
|
|
return null;
|
|
}
|
|
|
|
return Material.valueOf(Main.config.getString(loc));
|
|
}
|
|
|
|
private List<Hopper> getHoppers(Chunk chk, Material mat) {
|
|
List<Hopper> hoppers = new ArrayList<Hopper>();
|
|
|
|
if (!tilecache.isCached(chk)) {
|
|
tilecache.putCached(chk, chk.getTileEntities());
|
|
}
|
|
|
|
for (BlockState b : tilecache.getCached(chk)) {
|
|
if (!(b instanceof Hopper)) {
|
|
continue;
|
|
}
|
|
|
|
Hopper h = (Hopper) b;
|
|
|
|
String stg = VersionMgr.isV1_8() ? V1_8.getHopperName(h) : V1_12.getHopperName(h);
|
|
|
|
// Check if not default; and if it isn't default; check if the string is null or
|
|
// it isn't custom and continue.
|
|
if (!customname.equalsIgnoreCase("DEFAULT") && (stg == null || !stg.equals(customname))) {
|
|
continue;
|
|
}
|
|
|
|
if (!HopperFilter.isAllowed(h.getLocation(), mat)) {
|
|
continue;
|
|
}
|
|
|
|
hoppers.add((Hopper) b);
|
|
}
|
|
|
|
return hoppers;
|
|
}
|
|
|
|
private ItemStack spreadItemInHoppers(List<Hopper> hoppers, ItemStack itm, Location loc) {
|
|
ItemStack remainder = itm.clone();
|
|
|
|
if (isCustomHopper(remainder)) {
|
|
return remainder;
|
|
}
|
|
|
|
|
|
if (hoppermode.equalsIgnoreCase("RANDOM")) {
|
|
Collections.shuffle(hoppers);
|
|
} else if (hoppermode.equalsIgnoreCase("CLOSEST")) {
|
|
Collections.sort(hoppers, new HopperComparator(loc));
|
|
}
|
|
|
|
for (Hopper hopper : hoppers) {
|
|
Inventory inv = hopper.getInventory();
|
|
|
|
if (SellHoppers.attemptSell(hopper, itm)) {
|
|
return null;
|
|
}
|
|
|
|
Map<Integer, ItemStack> remainers = inv.addItem(remainder);
|
|
|
|
|
|
|
|
if (remainers.size() < 1) {
|
|
return null;
|
|
}
|
|
|
|
remainder = remainers.get(0);
|
|
|
|
if (remainder == null) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return remainder;
|
|
}
|
|
|
|
private static ItemStack chopper;
|
|
|
|
public static boolean isCustomHopper(ItemStack itm) {
|
|
if (chopper == null) {
|
|
chopper = getCustomHopper(1);
|
|
}
|
|
|
|
itm = itm.clone();
|
|
itm.setAmount(1);
|
|
|
|
return itm.isSimilar(chopper);
|
|
}
|
|
|
|
public static ItemStack getCustomHopper(int amount) {
|
|
ItemStack itm = new ItemStack(Material.valueOf("HOPPER"), amount);
|
|
ItemMeta imeta = itm.getItemMeta();
|
|
|
|
if (!customname.equalsIgnoreCase("DEFAULT")) {
|
|
imeta.setDisplayName(customname);
|
|
}
|
|
|
|
// Make it work with the unbreakable check.
|
|
VersionMgr.setUnbreakable(imeta, true);
|
|
imeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
|
|
itm.setItemMeta(imeta);
|
|
|
|
return itm;
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
public void onPlace(BlockPlaceEvent e) {
|
|
if (e.isCancelled()) {
|
|
return;
|
|
}
|
|
|
|
if (customname.equalsIgnoreCase("DEFAULT")) {
|
|
return;
|
|
}
|
|
|
|
ItemStack itm = e.getItemInHand();
|
|
|
|
if (itm == null) {
|
|
return;
|
|
}
|
|
|
|
if (!itm.hasItemMeta()) {
|
|
return;
|
|
}
|
|
|
|
ItemMeta imeta = itm.getItemMeta();
|
|
|
|
if (!imeta.hasDisplayName()) {
|
|
return;
|
|
}
|
|
|
|
String name = imeta.getDisplayName();
|
|
|
|
if (!name.equalsIgnoreCase(customname)) {
|
|
return;
|
|
}
|
|
|
|
if (!VersionMgr.isUnbreakable(imeta)) {
|
|
e.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
// System.out.println("SET OWNER");
|
|
// Set owner
|
|
Data.setOwningPlayer(e.getBlockPlaced().getLocation(), e.getPlayer());
|
|
tilecache.remove(e.getBlockPlaced().getChunk());
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST)
|
|
public void onBreak(BlockBreakEvent e) {
|
|
if (e.isCancelled()) {
|
|
return;
|
|
}
|
|
|
|
if (customname.equalsIgnoreCase("DEFAULT")) {
|
|
return;
|
|
}
|
|
|
|
Block b = e.getBlock();
|
|
BlockState bstate = b.getState();
|
|
|
|
if (!(bstate instanceof Hopper)) {
|
|
return;
|
|
}
|
|
|
|
Hopper h = (Hopper) bstate;
|
|
|
|
String stg = VersionMgr.isV1_8() ? V1_8.getHopperName(h) : V1_12.getHopperName(h);
|
|
|
|
if (stg == null) {
|
|
return;
|
|
}
|
|
|
|
if (!stg.equals(customname)) {
|
|
return;
|
|
}
|
|
|
|
Data.deleteHopper(h);
|
|
b.setType(Material.AIR);
|
|
// dropplayer = b.getWorld().dropItemNaturally(b.getLocation(), getCustomHopper(1));
|
|
dropplayer = Others.giveOrDrop(e.getPlayer(), getCustomHopper(1));
|
|
// e.getPlayer().getInventory().addItem(getCustomHopper(1));
|
|
tilecache.remove(b.getChunk());
|
|
|
|
}
|
|
|
|
@EventHandler
|
|
public void playerDrop(PlayerDropItemEvent e) {
|
|
|
|
if (e.isCancelled()) {
|
|
return;
|
|
}
|
|
|
|
dropplayer = e.getItemDrop();
|
|
}
|
|
|
|
@EventHandler
|
|
public void onItemDrop(ItemSpawnEvent e) {
|
|
|
|
if (e.isCancelled()) {
|
|
return;
|
|
}
|
|
|
|
Item itm = e.getEntity();
|
|
|
|
ItemStack its = itm.getItemStack();
|
|
Material mat = its.getType();
|
|
|
|
if (itm.equals(dropplayer)) {
|
|
return;
|
|
}
|
|
|
|
Chunk chk = itm.getLocation().getChunk();
|
|
|
|
List<Hopper> hoppers = getHoppers(chk, mat);
|
|
|
|
if (hoppers.size() < 1) {
|
|
return;
|
|
}
|
|
|
|
ItemStack remainder = spreadItemInHoppers(hoppers, itm.getItemStack(), itm.getLocation());
|
|
if (remainder == null) {
|
|
e.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
itm.setItemStack(remainder);
|
|
|
|
}
|
|
|
|
@EventHandler
|
|
public void onCreatureSpawn(CreatureSpawnEvent e) {
|
|
if (e.isCancelled()) {
|
|
return;
|
|
}
|
|
|
|
if (!reasons.contains(e.getSpawnReason().toString())) {
|
|
return;
|
|
}
|
|
|
|
if (!mobhoppers) {
|
|
return;
|
|
}
|
|
|
|
LivingEntity ent = e.getEntity();
|
|
|
|
Material mat = getMaterial(ent.getType());
|
|
|
|
if (mat == null) {
|
|
return;
|
|
}
|
|
|
|
Chunk chk = ent.getLocation().getChunk();
|
|
|
|
List<Hopper> hoppers = getHoppers(chk, mat);
|
|
|
|
for (ItemStack itm : V1_13.getLootTable(ent)) {
|
|
ItemStack buffed = itm.clone();
|
|
buffed.setAmount((int) (itm.getAmount() * multiplier));
|
|
spreadItemInHoppers(hoppers, buffed, ent.getLocation());
|
|
}
|
|
|
|
e.setCancelled(true);
|
|
|
|
// TODO: FINISH CHECK
|
|
}
|
|
}
|