From 35cde870ffd33151b2d469451731feb7c2f1b0d2 Mon Sep 17 00:00:00 2001 From: nossr50 Date: Thu, 23 Jul 2020 20:59:34 -0700 Subject: [PATCH] Reworked a lot of stuff to do with Smelting --- Changelog.txt | 10 +- .../nossr50/listeners/BlockListener.java | 16 +- .../nossr50/listeners/InventoryListener.java | 218 ++++-------------- src/main/java/com/gmail/nossr50/mcMMO.java | 10 +- .../runnables/skills/FurnaceCleanupTask.java | 22 ++ .../nossr50/skills/smelting/Smelting.java | 20 +- .../nossr50/util/skills/SmeltingTracker.java | 65 ++++++ 7 files changed, 165 insertions(+), 196 deletions(-) create mode 100644 src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java create mode 100644 src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java diff --git a/Changelog.txt b/Changelog.txt index fbb3d3b22..9aa772a11 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,5 @@ Version 2.1.134 - Smelting furnaces are now more flexible about who they consider their owner (see notes) + Furnaces now change ownership to the last player who clicks in their inventory and is legally allowed to break the furnace Smelting now has a Bonus Drops section in config.yml Smelting now only doubles smelting results for items which have bonus drop entries in config.yml Minor code cleanup @@ -17,14 +17,8 @@ Version 2.1.134 Fixed a locale mistake in locale ru NOTES: - Furnaces give XP to their owner while smelting - You become the owner of a Furnace by doing one of the following - 1) Opening an empty furnace - 2) Interacting with a furnace - It used to be that Furnaces would assign an owner and that would be their owner until the server shutdown, now owners will change based on who last had their hands on the furnace. - - You won't become the owner if you are not allowed to view the inventory of a furnace + You won't become the owner if you are not allowed to view the inventory of a furnace, or break the furnace, or interact with the contents of the furnace Version 2.1.133 A fix for an 'array out of bounds' error related to players clicking outside the inventory windows has been fixed diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 7f751502e..6fee064e9 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -18,6 +18,7 @@ import com.gmail.nossr50.skills.herbalism.HerbalismManager; import com.gmail.nossr50.skills.mining.MiningManager; import com.gmail.nossr50.skills.repair.Repair; import com.gmail.nossr50.skills.salvage.Salvage; +import com.gmail.nossr50.skills.smelting.Smelting; import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager; import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.EventUtils; @@ -535,16 +536,6 @@ public class BlockListener implements Listener { } } - private Player getPlayerFromFurnace(Block furnaceBlock) { - List metadata = furnaceBlock.getMetadata(mcMMO.furnaceMetadataKey); - - if (metadata.isEmpty()) { - return null; - } - - return plugin.getServer().getPlayerExact(metadata.get(0).asString()); - } - /** * Handle BlockDamage events where the event is modified. * @@ -628,7 +619,6 @@ public class BlockListener implements Listener { return; } - BlockState blockState = event.getBlock().getState(); ItemStack heldItem = player.getInventory().getItemInMainHand(); @@ -673,10 +663,10 @@ public class BlockListener implements Listener { if(blockState instanceof Furnace) { Furnace furnace = (Furnace) blockState; - if(furnace.hasMetadata(mcMMO.furnaceMetadataKey)) + if(mcMMO.getSmeltingTracker().isFurnaceOwned(furnace)) { player.sendMessage("[mcMMO DEBUG] This furnace has a registered owner"); - Player furnacePlayer = getPlayerFromFurnace(furnace.getBlock()); + OfflinePlayer furnacePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace); if(furnacePlayer != null) { player.sendMessage("[mcMMO DEBUG] This furnace is owned by player "+furnacePlayer.getName()); diff --git a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java index 0cc7fd227..196131717 100644 --- a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java @@ -2,11 +2,13 @@ package com.gmail.nossr50.listeners; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.WorldBlacklist; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.events.fake.FakeBrewEvent; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask; +import com.gmail.nossr50.runnables.skills.FurnaceCleanupTask; import com.gmail.nossr50.skills.alchemy.Alchemy; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; import com.gmail.nossr50.util.ItemUtils; @@ -15,8 +17,10 @@ import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.worldguard.WorldGuardManager; import com.gmail.nossr50.worldguard.WorldGuardUtils; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.BrewingStand; @@ -28,10 +32,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.*; import org.bukkit.inventory.*; -import org.bukkit.metadata.MetadataValue; -import org.jetbrains.annotations.Nullable; - -import java.util.List; public class InventoryListener implements Listener { private final mcMMO plugin; @@ -40,82 +40,6 @@ public class InventoryListener implements Listener { this.plugin = plugin; } - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onInventoryOpen(InventoryOpenEvent event) { - /* WORLD BLACKLIST CHECK */ - if(WorldBlacklist.isWorldBlacklisted(event.getPlayer().getWorld())) - return; - - HumanEntity humanEntity = event.getPlayer(); - Player player = (Player) humanEntity; - - //Profile not loaded - if(UserManager.getPlayer(player) == null) - { - return; - } - - if(event.getInventory() instanceof Furnace) { - - } - Furnace furnace = getFurnace(event.getInventory()); - - if (furnace != null) { - if(isFurnaceAvailable(furnace, player)) { - assignFurnace(furnace, player); - } - } - } - - public boolean isFurnaceAvailable(Furnace furnace, Player player) { - if(!furnace.hasMetadata(mcMMO.furnaceMetadataKey) - && furnace.getMetadata(mcMMO.furnaceMetadataKey).size() == 0) { - return true; - } else { - if(player != getPlayerFromFurnace(furnace)) { - - if(isFurnaceResultEmpty(furnace)) { - return true; - } else { - return false; - } - } - } - - return false; - } - - public boolean isFurnaceResultEmpty(Furnace furnace) { - return furnace.getInventory().getResult() == null; - } - - public void assignFurnace(Furnace furnace, Player player) { - - if(furnace.hasMetadata(mcMMO.furnaceMetadataKey)) { - furnace.removeMetadata(mcMMO.furnaceMetadataKey, mcMMO.p); - } - - furnace.setMetadata(mcMMO.furnaceMetadataKey, UserManager.getPlayer(player).getPlayerMetadata()); - - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onInventoryClose(InventoryCloseEvent event) { - /* WORLD BLACKLIST CHECK */ - if(WorldBlacklist.isWorldBlacklisted(event.getPlayer().getWorld())) - return; - - if(event.getInventory() instanceof FurnaceInventory) { - if(getFurnace(event.getInventory()) != null) { - Furnace furnace = getFurnace(event.getInventory()); - - if(isFurnaceOwned(furnace) && isFurnaceResultEmpty(furnace)) { - removeFurnaceOwner(furnace); - } - } - } - } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onFurnaceBurnEvent(FurnaceBurnEvent event) { /* WORLD BLACKLIST CHECK */ @@ -132,26 +56,27 @@ public class InventoryListener implements Listener { Furnace furnace = (Furnace) furnaceState; - Player player = getPlayerFromFurnace(furnace); + OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace); - /* WORLD GUARD MAIN FLAG CHECK */ - if(WorldGuardUtils.isWorldGuardLoaded()) - { - if(!WorldGuardManager.getInstance().hasMainFlag(player)) - return; + if(offlinePlayer != null && offlinePlayer.isOnline()) { + + Player player = Bukkit.getPlayer(offlinePlayer.getUniqueId()); + + if(player != null) { + if (!Permissions.isSubSkillEnabled(player, SubSkillType.SMELTING_FUEL_EFFICIENCY)) { + return; + } + + //Profile doesn't exist + if(UserManager.getOfflinePlayer(offlinePlayer) == null) + { + return; + } + + event.setBurnTime(UserManager.getPlayer(player).getSmeltingManager().fuelEfficiency(event.getBurnTime())); + } } - if (!UserManager.hasPlayerDataKey(player) || !Permissions.isSubSkillEnabled(player, SubSkillType.SMELTING_FUEL_EFFICIENCY)) { - return; - } - - //Profile not loaded - if(UserManager.getPlayer(player) == null) - { - return; - } - - event.setBurnTime(UserManager.getPlayer(player).getSmeltingManager().fuelEfficiency(event.getBurnTime())); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -160,35 +85,28 @@ public class InventoryListener implements Listener { if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld())) return; - Block furnaceBlock = event.getBlock(); + BlockState blockState = event.getBlock().getState(); //Furnaces can only be cast from a BlockState not a Block ItemStack smelting = event.getSource(); if (!ItemUtils.isSmeltable(smelting)) { return; } - if(furnaceBlock instanceof Furnace) - { - Player player = getPlayerFromFurnace((Furnace) furnaceBlock); + if(blockState instanceof Furnace) { + Furnace furnace = (Furnace) blockState; + OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace); - /* WORLD GUARD MAIN FLAG CHECK */ - if(WorldGuardUtils.isWorldGuardLoaded()) - { - if(!WorldGuardManager.getInstance().hasMainFlag(player)) - return; + if(offlinePlayer != null) { + + McMMOPlayer offlineProfile = UserManager.getOfflinePlayer(offlinePlayer); + + //Profile doesn't exist + if(offlineProfile != null) { + event.setResult(offlineProfile.getSmeltingManager().smeltProcessing(smelting, event.getResult())); + } } - if (!UserManager.hasPlayerDataKey(player) || !PrimarySkillType.SMELTING.getPermissions(player)) { - return; - } - - //Profile not loaded - if(UserManager.getPlayer(player) == null) - { - return; - } - - event.setResult(UserManager.getPlayer(player).getSmeltingManager().smeltProcessing(smelting, event.getResult())); + new FurnaceCleanupTask(furnace).runTaskLater(mcMMO.p, 1); } } @@ -198,16 +116,15 @@ public class InventoryListener implements Listener { if(WorldBlacklist.isWorldBlacklisted(event.getPlayer().getWorld())) return; - Block furnaceBlock = event.getBlock(); + BlockState furnaceBlock = event.getBlock().getState(); if (!ItemUtils.isSmelted(new ItemStack(event.getItemType(), event.getItemAmount()))) { return; } - if(furnaceBlock instanceof Furnace) { - Furnace furnace = (Furnace) furnaceBlock; - Player player = getPlayerFromFurnace(furnace); + Player player = event.getPlayer(); + if(furnaceBlock instanceof Furnace) { /* WORLD GUARD MAIN FLAG CHECK */ if(WorldGuardUtils.isWorldGuardLoaded()) { @@ -237,26 +154,22 @@ public class InventoryListener implements Listener { if(WorldBlacklist.isWorldBlacklisted(event.getWhoClicked().getWorld())) return; + //We should never care to do processing if the player clicks outside the window +// if(isOutsideWindowClick(event)) +// return; + Inventory inventory = event.getInventory(); - if(event.getWhoClicked() instanceof Player) + Player player = ((Player) event.getWhoClicked()).getPlayer(); + + if(event.getInventory() instanceof FurnaceInventory) { - Player player = ((Player) event.getWhoClicked()).getPlayer(); - Furnace furnace = getFurnace(event.getInventory()); + Furnace furnace = mcMMO.getSmeltingTracker().getFurnaceFromInventory(event.getInventory()); if (furnace != null) { - if (isFurnaceOwned(furnace)) { - removeFurnaceOwner(furnace); - } - - //Profile not loaded - if(UserManager.getPlayer(player) == null) - { - return; - } - - assignFurnace(furnace, player); + //Switch owners + mcMMO.getSmeltingTracker().processFurnaceOwnership(furnace, player); } } @@ -276,8 +189,6 @@ public class InventoryListener implements Listener { return; } - Player player = (Player) whoClicked; - /* WORLD GUARD MAIN FLAG CHECK */ if(WorldGuardUtils.isWorldGuardLoaded()) { @@ -362,13 +273,10 @@ public class InventoryListener implements Listener { } } - public boolean isFurnaceOwned(Furnace furnace) { - return furnace.getMetadata(mcMMO.furnaceMetadataKey).size() > 0; + public boolean isOutsideWindowClick(InventoryClickEvent event) { + return event.getHotbarButton() == -1; } - public void removeFurnaceOwner(Furnace furnace) { - furnace.removeMetadata(mcMMO.furnaceMetadataKey, mcMMO.p); - } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInventoryDragEvent(InventoryDragEvent event) { @@ -480,7 +388,7 @@ public class InventoryListener implements Listener { public void onInventoryClickEvent(InventoryClickEvent event) { SkillUtils.removeAbilityBuff(event.getCurrentItem()); if (event.getAction() == InventoryAction.HOTBAR_SWAP) { - if(event.getHotbarButton() == -1) + if(isOutsideWindowClick(event)) return; PlayerInventory playerInventory = event.getWhoClicked().getInventory(); @@ -525,28 +433,4 @@ public class InventoryListener implements Listener { new PlayerUpdateInventoryTask((Player) whoClicked).runTaskLater(plugin, 0); } - private Furnace getFurnace(Inventory inventory) { - if (!(inventory instanceof FurnaceInventory)) { - return null; - } - - Furnace furnace = (Furnace) inventory.getHolder(); - - if (furnace == null) { - return null; - } - - return furnace; - } - - @Nullable - private Player getPlayerFromFurnace(Furnace furnace) { - List metadata = furnace.getMetadata(mcMMO.furnaceMetadataKey); - - if (metadata.isEmpty()) { - return null; - } - - return plugin.getServer().getPlayerExact(metadata.get(0).asString()); - } } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 90e16ea7b..697e91439 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -46,6 +46,7 @@ import com.gmail.nossr50.util.player.PlayerLevelUtils; import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.scoreboards.ScoreboardManager; import com.gmail.nossr50.util.skills.RankUtils; +import com.gmail.nossr50.util.skills.SmeltingTracker; import com.gmail.nossr50.util.upgrade.UpgradeManager; import com.gmail.nossr50.worldguard.WorldGuardManager; import com.google.common.base.Charsets; @@ -78,6 +79,7 @@ public class mcMMO extends JavaPlugin { private static UpgradeManager upgradeManager; private static MaterialMapStore materialMapStore; private static PlayerLevelUtils playerLevelUtils; + private static SmeltingTracker smeltingTracker; /* Blacklist */ private static WorldBlacklist worldBlacklist; @@ -116,7 +118,6 @@ public class mcMMO extends JavaPlugin { public static final String COTW_TEMPORARY_SUMMON = "mcMMO: COTW Entity"; public final static String entityMetadataKey = "mcMMO: Spawned Entity"; public final static String blockMetadataKey = "mcMMO: Piston Tracking"; - public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace"; public final static String tntMetadataKey = "mcMMO: Tracked TNT"; public final static String funfettiMetadataKey = "mcMMO: Funfetti"; public final static String customNameKey = "mcMMO: Custom Name"; @@ -266,6 +267,9 @@ public class mcMMO extends JavaPlugin { //Init the blacklist worldBlacklist = new WorldBlacklist(this); + + //Init smelting tracker + smeltingTracker = new SmeltingTracker(); } public static PlayerLevelUtils getPlayerLevelUtils() { @@ -670,4 +674,8 @@ public class mcMMO extends JavaPlugin { public static PlatformManager getPlatformManager() { return platformManager; } + + public static SmeltingTracker getSmeltingTracker() { + return smeltingTracker; + } } diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java new file mode 100644 index 000000000..341a51ac4 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java @@ -0,0 +1,22 @@ +package com.gmail.nossr50.runnables.skills; + +import com.gmail.nossr50.mcMMO; +import org.bukkit.block.Furnace; +import org.bukkit.scheduler.BukkitRunnable; + +public class FurnaceCleanupTask extends BukkitRunnable { + + private final Furnace furnace; + + public FurnaceCleanupTask(Furnace furnace) { + this.furnace = furnace; + } + + @Override + public void run() { + if(furnace != null && furnace.getInventory().getResult() == null) { + //Furnace is empty so stop tracking it + mcMMO.getSmeltingTracker().untrackFurnace(furnace); + } + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java b/src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java index 11b43d7d8..e196eb4ef 100644 --- a/src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java +++ b/src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java @@ -4,19 +4,25 @@ import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.EventUtils; +import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.skills.RankUtils; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Furnace; import org.bukkit.entity.Player; +import org.bukkit.inventory.FurnaceInventory; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.MetadataValue; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; public class Smelting { - public static int getRank(Player player) - { - return RankUtils.getRank(player, SubSkillType.SMELTING_UNDERSTANDING_THE_ART); - } - - //public static int fluxMiningUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.SMELTING_FLUX_MINING); - protected static int getResourceXp(ItemStack smelting) { return mcMMO.getModManager().isCustomOre(smelting.getType()) ? mcMMO.getModManager().getBlock(smelting.getType()).getSmeltingXpGain() : ExperienceConfig.getInstance().getXp(PrimarySkillType.SMELTING, smelting.getType()); } diff --git a/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java b/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java new file mode 100644 index 000000000..eb8fa5261 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java @@ -0,0 +1,65 @@ +package com.gmail.nossr50.util.skills; + +import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.skills.smelting.Smelting; +import com.gmail.nossr50.util.EventUtils; +import com.gmail.nossr50.util.Permissions; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Furnace; +import org.bukkit.entity.Player; +import org.bukkit.inventory.FurnaceInventory; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +public class SmeltingTracker { + + private HashMap furnaceOwners; + + public SmeltingTracker() { + furnaceOwners = new HashMap<>(); + } + + private void changeFurnaceOwnership(Furnace furnace, Player player) { + furnaceOwners.put(furnace, player); + } + + @Nullable + public Furnace getFurnaceFromInventory(Inventory inventory) { + if (!(inventory instanceof FurnaceInventory)) { + return null; + } + + return (Furnace) inventory.getHolder(); + } + + @Nullable + public OfflinePlayer getPlayerFromFurnace(Furnace furnace) { + return furnaceOwners.get(furnace); + } + + public boolean isFurnaceOwned(Furnace furnace) { + return furnaceOwners.get(furnace) != null; + } + + public void removeFurnaceOwner(Furnace furnace) { + furnaceOwners.remove(furnace); + } + + public void processFurnaceOwnership(Furnace furnace, Player player) { + if(!Permissions.skillEnabled(player, PrimarySkillType.SMELTING)) + return; + + //If the player is legally allowed to break the block then they can steal ownership + if(EventUtils.simulateBlockBreak(furnace.getBlock(), player, true)) { + changeFurnaceOwnership(furnace, player); + } + } + + public void untrackFurnace(Furnace furnace) { + furnaceOwners.remove(furnace); + } +}