diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a1c9b08..86d4551 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "EpicFurnaces" path: "/builds/$CI_PROJECT_PATH" - version: "4.2.1" + version: "4.2.2" build: stage: build diff --git a/core/src/main/java/com/songoda/epicfurnaces/EpicFurnaces.java b/core/src/main/java/com/songoda/epicfurnaces/EpicFurnaces.java index 6b076e7..e3269de 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/EpicFurnaces.java +++ b/core/src/main/java/com/songoda/epicfurnaces/EpicFurnaces.java @@ -26,12 +26,14 @@ import net.milkbowl.vault.economy.Economy; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; @@ -156,6 +158,11 @@ public class EpicFurnaces extends JavaPlugin { this.hologramManager = null; storage.doSave(); storage.closeConnection(); + + Map loadedFurnaceInventories = this.furnaceManager.getLoadedFurnaceInventories(); + for (Inventory inventory : loadedFurnaceInventories.keySet()) + loadedFurnaceInventories.get(inventory).getChunk().load(); + loadedFurnaceInventories.clear(); } private void checkStorage() { diff --git a/core/src/main/java/com/songoda/epicfurnaces/command/commands/CommandRemote.java b/core/src/main/java/com/songoda/epicfurnaces/command/commands/CommandRemote.java index 11ec30f..6392f5b 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/command/commands/CommandRemote.java +++ b/core/src/main/java/com/songoda/epicfurnaces/command/commands/CommandRemote.java @@ -35,7 +35,7 @@ public class CommandRemote extends AbstractCommand { String furnaceName = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); - for (FurnaceObject furnace : instance.getFurnaceManager().getFurnaces().values()) { + for (FurnaceObject furnace : instance.getFurnaceManager().getAllFurnaces().values()) { if (furnace.getNickname() == null) { continue; } @@ -50,6 +50,10 @@ public class CommandRemote extends AbstractCommand { } Furnace furnaceBlock = (Furnace) furnace.getLocation().getBlock().getState(); + + this.instance.getFurnaceManager().getLoadedFurnaceInventories().put(furnaceBlock.getInventory(), furnaceBlock.getLocation()); + furnaceBlock.getChunk().load(); + ((Player) sender).openInventory(furnaceBlock.getInventory()); return ReturnType.SUCCESS; } diff --git a/core/src/main/java/com/songoda/epicfurnaces/listeners/FurnaceListeners.java b/core/src/main/java/com/songoda/epicfurnaces/listeners/FurnaceListeners.java index 8fb5ee1..53da62d 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/listeners/FurnaceListeners.java +++ b/core/src/main/java/com/songoda/epicfurnaces/listeners/FurnaceListeners.java @@ -51,6 +51,5 @@ public class FurnaceListeners implements Listener { int num = level.getFuelDuration(); int per = (event.getBurnTime() / 100) * num; event.setBurnTime(event.getBurnTime() + per); - System.out.println("editting burn time"); } } \ No newline at end of file diff --git a/core/src/main/java/com/songoda/epicfurnaces/listeners/InventoryListeners.java b/core/src/main/java/com/songoda/epicfurnaces/listeners/InventoryListeners.java index ad1bd0e..a2bf55b 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/listeners/InventoryListeners.java +++ b/core/src/main/java/com/songoda/epicfurnaces/listeners/InventoryListeners.java @@ -2,15 +2,21 @@ package com.songoda.epicfurnaces.listeners; import com.songoda.epicfurnaces.EpicFurnaces; import com.songoda.epicfurnaces.objects.FurnaceObject; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Furnace; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import java.util.Map; + import static org.bukkit.event.inventory.InventoryAction.NOTHING; import static org.bukkit.event.inventory.InventoryType.*; import static org.bukkit.event.inventory.InventoryType.SlotType.CRAFTING; @@ -26,6 +32,18 @@ public class InventoryListeners implements Listener { this.instance = instance; } + @EventHandler(priority = EventPriority.MONITOR) + public void onInventoryClose(InventoryCloseEvent event) { + Inventory inventory = event.getInventory(); + Map loadedFurnaceInventories = this.instance.getFurnaceManager().getLoadedFurnaceInventories(); + Location location = loadedFurnaceInventories.get(inventory); + if (location == null) + return; + + location.getChunk().unload(); + loadedFurnaceInventories.remove(inventory); + } + @EventHandler public void onInventoryMove(InventoryMoveItemEvent event) { if (!event.getDestination().getType().equals(FURNACE) @@ -42,8 +60,7 @@ public class InventoryListeners implements Listener { if (event.getInventory().getType().equals(FURNACE) && event.getInventory().getHolder() != null && event.getSlotType() == CRAFTING) { - Block block; - block = ((Furnace) event.getInventory().getHolder()).getLocation().getBlock(); + Block block = ((Furnace) event.getInventory().getHolder()).getLocation().getBlock(); instance.getFurnaceManager().getFurnace(block.getLocation()).ifPresent(FurnaceObject::updateCook); } diff --git a/core/src/main/java/com/songoda/epicfurnaces/managers/FurnaceManager.java b/core/src/main/java/com/songoda/epicfurnaces/managers/FurnaceManager.java index cb9d756..325ef79 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/managers/FurnaceManager.java +++ b/core/src/main/java/com/songoda/epicfurnaces/managers/FurnaceManager.java @@ -10,6 +10,7 @@ import com.songoda.epicfurnaces.utils.Methods; import com.songoda.epicfurnaces.utils.gui.ItemBuilder; import org.apache.commons.lang.StringUtils; import org.bukkit.Location; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import java.util.*; @@ -19,6 +20,7 @@ import static org.bukkit.Material.FURNACE; public class FurnaceManager { private final Map registeredFurnaces = new HashMap<>(); + private final Map loadedFurnaceInventories = new HashMap<>(); private final EpicFurnaces instance; public FurnaceManager(EpicFurnaces instance) { @@ -126,7 +128,30 @@ public class FurnaceManager { getFurnaces().values().forEach(furnace -> instance.getHologramManager().ifPresent(manager -> manager.updateHologram(furnace))); } + public Map getLoadedFurnaceInventories() { + return this.loadedFurnaceInventories; + } + + /** + * Gets a Map of all furnaces that are in loaded chunks + * + * @return All furnaces in memory that are in loaded chunks + */ public Map getFurnaces() { - return Collections.unmodifiableMap(registeredFurnaces); + Map furnaces = new HashMap<>(); + for (Location location : this.registeredFurnaces.keySet()) + if (location.getWorld() != null && location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) + furnaces.put(location, this.registeredFurnaces.get(location)); + return furnaces; + } + + /** + * Gets a Map of all furnaces, regardless if they are in loaded chunks or not. + * Getting the furnace's block in an unloaded chunk will load the chunk. + * + * @return All furnaces in memory + */ + public Map getAllFurnaces() { + return Collections.unmodifiableMap(this.registeredFurnaces); } } diff --git a/core/src/main/java/com/songoda/epicfurnaces/menus/OverviewMenu.java b/core/src/main/java/com/songoda/epicfurnaces/menus/OverviewMenu.java index 52f5a98..66fd302 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/menus/OverviewMenu.java +++ b/core/src/main/java/com/songoda/epicfurnaces/menus/OverviewMenu.java @@ -165,7 +165,7 @@ public class OverviewMenu extends FastInv { event.getPlayer().sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.remote.enter")); AbstractAnvilGUI anvilGUI = new AbstractAnvilGUI(instance, event.getPlayer(), anvilEvent -> { - for (FurnaceObject other : instance.getFurnaceManager().getFurnaces().values()) { + for (FurnaceObject other : instance.getFurnaceManager().getAllFurnaces().values()) { if (other.getNickname() == null) { continue; } diff --git a/core/src/main/java/com/songoda/epicfurnaces/objects/Level.java b/core/src/main/java/com/songoda/epicfurnaces/objects/Level.java index ceec73f..3b0b871 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/objects/Level.java +++ b/core/src/main/java/com/songoda/epicfurnaces/objects/Level.java @@ -3,6 +3,7 @@ package com.songoda.epicfurnaces.objects; import com.songoda.epicfurnaces.EpicFurnaces; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Level { @@ -39,7 +40,7 @@ public class Level { public List getDescription() { - return new ArrayList<>(description); + return Collections.unmodifiableList(description); } diff --git a/core/src/main/java/com/songoda/epicfurnaces/storage/Storage.java b/core/src/main/java/com/songoda/epicfurnaces/storage/Storage.java index 10c60c3..8a675e3 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/storage/Storage.java +++ b/core/src/main/java/com/songoda/epicfurnaces/storage/Storage.java @@ -29,7 +29,7 @@ public abstract class Storage { public void updateData(EpicFurnaces instance) { // Save game data - for (FurnaceObject furnace : instance.getFurnaceManager().getFurnaces().values()) { + for (FurnaceObject furnace : instance.getFurnaceManager().getAllFurnaces().values()) { if (furnace == null || furnace.getLocation() == null || furnace.getLocation().getWorld() == null) { continue; } diff --git a/core/src/main/java/com/songoda/epicfurnaces/tasks/FurnaceTask.java b/core/src/main/java/com/songoda/epicfurnaces/tasks/FurnaceTask.java index 97cec2f..22d4faa 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/tasks/FurnaceTask.java +++ b/core/src/main/java/com/songoda/epicfurnaces/tasks/FurnaceTask.java @@ -45,13 +45,6 @@ public class FurnaceTask extends BukkitRunnable { continue; } - int x = furnaceLocation.getBlockX() >> 4; - int z = furnaceLocation.getBlockZ() >> 4; - - if (!furnaceLocation.getWorld().isChunkLoaded(x, z)) { - continue; - } - if (furnace.getLocation().getBlock().getType() != Material.FURNACE && furnace.getLocation().getBlock().getType() != instance.getBukkitEnums().getMaterial("BURNING_FURNACE").getType()) { continue; @@ -135,7 +128,7 @@ public class FurnaceTask extends BukkitRunnable { Furnace furnaceBlock = ((Furnace) block.getState()); if (furnaceBlock.getBurnTime() == 0) { - furnaceBlock.setBurnTime((short) 200); + furnaceBlock.setBurnTime((short) 205); furnaceBlock.update(); broadcastParticles(location); } diff --git a/core/src/main/java/com/songoda/epicfurnaces/tasks/HologramTask.java b/core/src/main/java/com/songoda/epicfurnaces/tasks/HologramTask.java index 2f6058f..542d3bc 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/tasks/HologramTask.java +++ b/core/src/main/java/com/songoda/epicfurnaces/tasks/HologramTask.java @@ -30,7 +30,7 @@ public class HologramTask extends BukkitRunnable { } instance.getFurnaceManager().getFurnaces().values().stream() - .filter(furnace -> furnace.getLocation() != null && furnace.getLocation().getWorld() != null && furnace.getLocation().getBlock() != null) + .filter(furnace -> furnace.getLocation().getBlock() != null) .forEach(furnace -> instance.getHologramManager().ifPresent(manager -> manager.updateHologram(furnace))); } } diff --git a/core/src/main/java/com/songoda/epicfurnaces/utils/MySQLDatabase.java b/core/src/main/java/com/songoda/epicfurnaces/utils/MySQLDatabase.java index 1352954..6c5468f 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/utils/MySQLDatabase.java +++ b/core/src/main/java/com/songoda/epicfurnaces/utils/MySQLDatabase.java @@ -39,7 +39,7 @@ public class MySQLDatabase { ")"); } catch (ClassNotFoundException | SQLException e) { - System.out.println("Database connection failed."); + instance.getLogger().severe("Database connection failed."); } } diff --git a/core/src/main/java/com/songoda/epicfurnaces/utils/gui/AbstractAnvilGUI.java b/core/src/main/java/com/songoda/epicfurnaces/utils/gui/AbstractAnvilGUI.java index ea85cc8..ff50aff 100644 --- a/core/src/main/java/com/songoda/epicfurnaces/utils/gui/AbstractAnvilGUI.java +++ b/core/src/main/java/com/songoda/epicfurnaces/utils/gui/AbstractAnvilGUI.java @@ -3,6 +3,7 @@ package com.songoda.epicfurnaces.utils.gui; import com.songoda.epicfurnaces.EpicFurnaces; import com.songoda.epicfurnaces.utils.NMSUtil; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -20,7 +21,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; -import java.util.Objects; public class AbstractAnvilGUI { private static Class BlockPositionClass; @@ -35,6 +35,7 @@ public class AbstractAnvilGUI { private static Class WorldClass; private static Class PlayerInventoryClass; private static Class ContainersClass; + private static Class CraftPlayerClass; private Player player; private Map items = new HashMap<>(); @@ -53,93 +54,86 @@ public class AbstractAnvilGUI { ContainerClass = NMSUtil.getNMSClass("Container"); WorldClass = NMSUtil.getNMSClass("World"); PlayerInventoryClass = NMSUtil.getNMSClass("PlayerInventory"); + CraftPlayerClass = NMSUtil.getCraftClass("entity.CraftPlayer"); if (NMSUtil.getVersionNumber() > 13) { ContainerAccessClass = NMSUtil.getNMSClass("ContainerAccess"); ContainersClass = NMSUtil.getNMSClass("Containers"); } } - public AbstractAnvilGUI(EpicFurnaces instance, final Player player, final AnvilClickEventHandler handler) { + + public AbstractAnvilGUI(EpicFurnaces instance, Player player, AnvilClickEventHandler handler) { this.player = player; this.listener = new Listener() { - @EventHandler(priority = EventPriority.LOWEST) + @EventHandler(priority = EventPriority.HIGHEST) public void onInventoryClick(InventoryClickEvent event) { - if (event.getWhoClicked() instanceof Player) { + if (event.getWhoClicked() instanceof Player && event.getInventory().equals(AbstractAnvilGUI.this.inv)) { + event.setCancelled(true); - if (event.getInventory().equals(inv)) { - event.setCancelled(true); + ItemStack item = event.getCurrentItem(); + int slot = event.getRawSlot(); - ItemStack item = event.getCurrentItem(); - int slot = event.getRawSlot(); - String name = ""; + if (item == null || item.getType().equals(Material.AIR) || slot != 2) + return; - if (item != null) { - if (item.hasItemMeta()) { - ItemMeta meta = item.getItemMeta(); + String name = ""; - if (meta != null && meta.hasDisplayName()) { - name = meta.getDisplayName(); - } - } - } + ItemMeta meta = item.getItemMeta(); + if (meta != null && meta.hasDisplayName()) + name = meta.getDisplayName(); - AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name); + AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name); + handler.onAnvilClick(clickEvent); - handler.onAnvilClick(clickEvent); + if (clickEvent.getWillClose()) + event.getWhoClicked().closeInventory(); - if (clickEvent.getWillClose()) { - event.getWhoClicked().closeInventory(); - } - - if (clickEvent.getWillDestroy()) { - destroy(); - } - } + if (clickEvent.getWillDestroy()) + AbstractAnvilGUI.this.destroy(); } } - @EventHandler(priority = EventPriority.LOWEST) + @EventHandler(priority = EventPriority.HIGHEST) public void onInventoryClose(InventoryCloseEvent event) { - if (event.getPlayer() instanceof Player) { + if (event.getPlayer() instanceof Player && AbstractAnvilGUI.this.inv.equals(event.getInventory())) { Inventory inv = event.getInventory(); player.setLevel(player.getLevel() - 1); - if (inv.equals(inv)) { - inv.clear(); - Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> { - if (onClose != null) onClose.onClose(player, inv); - destroy(); - }, 1L); - } + inv.clear(); + Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> { + if (AbstractAnvilGUI.this.onClose != null) + AbstractAnvilGUI.this.onClose.onClose(player, inv); + AbstractAnvilGUI.this.destroy(); + }, 1L); } } - @EventHandler(priority = EventPriority.LOWEST) + @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerQuit(PlayerQuitEvent event) { - if (event.getPlayer().equals(getPlayer())) { + if (event.getPlayer().equals(AbstractAnvilGUI.this.player)) { player.setLevel(player.getLevel() - 1); - destroy(); + AbstractAnvilGUI.this.destroy(); } } }; - Bukkit.getPluginManager().registerEvents(listener, instance); + Bukkit.getPluginManager().registerEvents(this.listener, instance); } public Player getPlayer() { - return player; + return this.player; } public void setSlot(AnvilSlot slot, ItemStack item) { - items.put(slot, item); + this.items.put(slot, item); } public void open() { - player.setLevel(player.getLevel() + 1); + this.player.setLevel(this.player.getLevel() + 1); try { - Object craftPlayer = NMSUtil.getCraftClass("entity.CraftPlayer").cast(player); - Method getHandleMethod = craftPlayer.getClass().getMethod("getHandle"); + Object craftPlayer = CraftPlayerClass.cast(this.player); + Method getHandleMethod = CraftPlayerClass.getMethod("getHandle"); Object entityPlayer = getHandleMethod.invoke(craftPlayer); Object playerInventory = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false)); Object world = NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false)); @@ -162,10 +156,10 @@ public class AbstractAnvilGUI { Method getBukkitViewMethod = container.getClass().getMethod("getBukkitView"); Object bukkitView = getBukkitViewMethod.invoke(container); Method getTopInventoryMethod = bukkitView.getClass().getMethod("getTopInventory"); - inv = (Inventory) getTopInventoryMethod.invoke(bukkitView); + this.inv = (Inventory) getTopInventoryMethod.invoke(bukkitView); - for (AnvilSlot slot : items.keySet()) { - inv.setItem(slot.getSlot(), items.get(slot)); + for (AnvilSlot slot : this.items.keySet()) { + this.inv.setItem(slot.getSlot(), this.items.get(slot)); } Method nextContainerCounterMethod = entityPlayer.getClass().getMethod("nextContainerCounter"); @@ -186,7 +180,7 @@ public class AbstractAnvilGUI { .newInstance(c, "minecraft:anvil", inventoryTitle, 0); } - NMSUtil.sendPacket(player, packet); + NMSUtil.sendPacket(this.player, packet); Field activeContainerField = NMSUtil.getField(EntityHumanClass, "activeContainer", true); @@ -206,16 +200,16 @@ public class AbstractAnvilGUI { } public void destroy() { - player = null; - items = null; + this.player = null; + this.items = null; - HandlerList.unregisterAll(listener); + HandlerList.unregisterAll(this.listener); - listener = null; + this.listener = null; } private OnClose getOnClose() { - return onClose; + return this.onClose; } public void setOnClose(OnClose onClose) { @@ -244,7 +238,7 @@ public class AbstractAnvilGUI { } public int getSlot() { - return slot; + return this.slot; } } @@ -267,15 +261,15 @@ public class AbstractAnvilGUI { } public AnvilSlot getSlot() { - return slot; + return this.slot; } public String getName() { - return name; + return this.name; } public boolean getWillClose() { - return close; + return this.close; } public void setWillClose(boolean close) { @@ -283,7 +277,7 @@ public class AbstractAnvilGUI { } public boolean getWillDestroy() { - return destroy; + return this.destroy; } public void setWillDestroy(boolean destroy) {