From 89f8a7edbddd42037d634b6954649746e54f6fc1 Mon Sep 17 00:00:00 2001 From: OsipXD Date: Sun, 22 Apr 2018 14:53:26 +0300 Subject: [PATCH 1/8] Fix error on login --- .../ru/endlesscode/rpginventory/api/PetAPI.java | 10 +++++++--- .../event/listener/CraftListener.java | 14 ++++++++++---- .../event/listener/InventoryListener.java | 12 ++++++------ .../rpginventory/inventory/InventoryManager.java | 15 ++++++--------- .../rpginventory/utils/StringUtils.java | 14 +++----------- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/api/PetAPI.java b/src/main/java/ru/endlesscode/rpginventory/api/PetAPI.java index ea529d7..ba1550a 100644 --- a/src/main/java/ru/endlesscode/rpginventory/api/PetAPI.java +++ b/src/main/java/ru/endlesscode/rpginventory/api/PetAPI.java @@ -35,21 +35,25 @@ @SuppressWarnings({"unused", "WeakerAccess"}) public class PetAPI { /** - * Get pet spawn item from RPGInventory of specific player + * Get pet spawn item from RPGInventory of specific player. * * @param player - not null player * @return ItemStack if player have pet spawn item, null - otherwise */ @Nullable public static ItemStack getPetItem(Player player) { + if (!InventoryManager.playerIsLoaded(player) || !PetManager.isEnabled()) { + return null; + } + PlayerWrapper playerWrapper = InventoryManager.get(player); - ItemStack petItem = PetManager.isEnabled() && playerWrapper != null ? playerWrapper.getInventory().getItem(PetManager.getPetSlotId()) : null; + ItemStack petItem = playerWrapper.getInventory().getItem(PetManager.getPetSlotId()); return ItemUtils.isEmpty(petItem) ? null : petItem; } /** - * Get Pet of specific player + * Get Pet of specific player. * * @param player - not null player * @return Pet if player have pet, null - otherwise diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java index a638251..7c9c2c6 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java @@ -60,7 +60,7 @@ public void onPacketSending(@NotNull PacketEvent event) { Player player = event.getPlayer(); //noinspection ConstantConditions if (event.isCancelled() || !InventoryManager.playerIsLoaded(player) - || isNotNeededHere(player)) { + || isExtensionsNotNeededHere(player)) { return; } @@ -84,7 +84,7 @@ public void onInventoryOpen(@NotNull InventoryOpenEvent event) { final Player player = (Player) event.getPlayer(); if (!InventoryManager.playerIsLoaded(player) || event.getInventory().getType() != InventoryType.WORKBENCH - || isNotNeededHere(player)) { + || isExtensionsNotNeededHere(player)) { return; } @@ -98,7 +98,7 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { //noinspection ConstantConditions if (!InventoryManager.playerIsLoaded(player) || event.getInventory().getType() != InventoryType.WORKBENCH - || isNotNeededHere(player)) { + || isExtensionsNotNeededHere(player)) { return; } @@ -114,7 +114,13 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { } } - private boolean isNotNeededHere(Player player) { + /** + * Checks that inventory extensions not needed there. + * It always used after `InventoryManager.playerIsLoaded(player)` check. + * + * @param player Player to check + */ + private boolean isExtensionsNotNeededHere(Player player) { return !InventoryManager.get(player).isPocketCraft() && !Config.getConfig().getBoolean("craft.workbench", true); } diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/InventoryListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/InventoryListener.java index 13b5e9f..ab0070d 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/InventoryListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/InventoryListener.java @@ -262,13 +262,15 @@ public void onInventoryClick(@NotNull final InventoryClickEvent event) { // Crafting area if (inventory.getType() == InventoryType.CRAFTING) { - if (InventoryManager.get(player).isOpened()) { + PlayerWrapper playerWrapper = InventoryManager.get(player); + + if (playerWrapper.isOpened()) { return; } switch (event.getSlotType()) { case CRAFTING: - InventoryManager.get(player).openInventory(true); + playerWrapper.openInventory(true); case QUICKBAR: // Shield slot is QUICKBAR and has rawId - 45 o.O if (rawSlot != 45) { @@ -491,10 +493,8 @@ public void onWorldChanged(@NotNull PlayerChangedWorldEvent event) { if (!InventoryManager.isAllowedWorld(player.getWorld())) { InventoryManager.unloadPlayerInventory(player); - } else { - if (InventoryManager.get(player).hasPet()) { - PetManager.respawnPet(player); - } + } else if (InventoryManager.get(player).hasPet()) { + PetManager.respawnPet(player); } } } diff --git a/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java b/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java index 6211978..c3fe449 100644 --- a/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java +++ b/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java @@ -18,6 +18,7 @@ package ru.endlesscode.rpginventory.inventory; +import com.comphenix.protocol.*; import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.World; @@ -52,10 +53,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; @SuppressWarnings("ResultOfMethodCallIgnored") public class InventoryManager { @@ -549,14 +547,13 @@ public static void savePlayerInventory(@NotNull Player player) { } } - public static PlayerWrapper get(@Nullable OfflinePlayer player) { - if (player == null) { - throw new IllegalArgumentException("OfflinePlayer can not be null!"); - } + @NotNull + public static PlayerWrapper get(@NotNull OfflinePlayer player) { PlayerWrapper playerWrapper = InventoryManager.INVENTORIES.get(player.getUniqueId()); if (playerWrapper == null) { - throw new IllegalArgumentException(player.getName() + "'s inventory is not loaded!"); + throw new IllegalStateException("Player should be initialized!"); } + return playerWrapper; } diff --git a/src/main/java/ru/endlesscode/rpginventory/utils/StringUtils.java b/src/main/java/ru/endlesscode/rpginventory/utils/StringUtils.java index 72a67c9..137d3f7 100644 --- a/src/main/java/ru/endlesscode/rpginventory/utils/StringUtils.java +++ b/src/main/java/ru/endlesscode/rpginventory/utils/StringUtils.java @@ -23,8 +23,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.*; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.external.EZPlaceholderHook; @@ -76,9 +75,7 @@ public static String setPlaceholders(@NotNull Player player, @NotNull String lin line = line.replaceAll("%HP%", Utils.round(player.getHealth(), 1) + ""); line = line.replaceAll("%MAX_HP%", player.getMaxHealth() + ""); - PlayerWrapper playerWrapper = InventoryManager.get(player); - if (playerWrapper != null) { - + if (InventoryManager.playerIsLoaded(player)) { // Modifiers line = line.replaceAll("%DAMAGE%", ItemManager.getModifier(player, ItemStat.StatType.DAMAGE).toString()); line = line.replaceAll("%BOW_DAMAGE%", ItemManager.getModifier(player, ItemStat.StatType.BOW_DAMAGE).toString()); @@ -100,12 +97,7 @@ public Placeholders() { @Override public String onPlaceholderRequest(@Nullable Player player, @NotNull String identifier) { - if (player == null) { - return ""; - } - - PlayerWrapper playerWrapper = InventoryManager.get(player); - if (playerWrapper == null) { + if (!InventoryManager.playerIsLoaded(player)) { return ""; } From 58ad1954d5da49cd496a43c448b93ddb99cf84d2 Mon Sep 17 00:00:00 2001 From: OsipXD Date: Sun, 22 Apr 2018 14:58:14 +0300 Subject: [PATCH 2/8] Clarify previous commit --- .../endlesscode/rpginventory/event/listener/CraftListener.java | 2 +- .../ru/endlesscode/rpginventory/inventory/InventoryManager.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java index 7c9c2c6..294533c 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/CraftListener.java @@ -116,7 +116,7 @@ public void onInventoryClick(@NotNull InventoryClickEvent event) { /** * Checks that inventory extensions not needed there. - * It always used after `InventoryManager.playerIsLoaded(player)` check. + * It always should be used after `InventoryManager.playerIsLoaded(player)` check. * * @param player Player to check */ diff --git a/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java b/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java index c3fe449..a75e04d 100644 --- a/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java +++ b/src/main/java/ru/endlesscode/rpginventory/inventory/InventoryManager.java @@ -551,7 +551,7 @@ public static void savePlayerInventory(@NotNull Player player) { public static PlayerWrapper get(@NotNull OfflinePlayer player) { PlayerWrapper playerWrapper = InventoryManager.INVENTORIES.get(player.getUniqueId()); if (playerWrapper == null) { - throw new IllegalStateException("Player should be initialized!"); + throw new IllegalStateException("" + player.getName() + "'s inventory should be initialized!"); } return playerWrapper; From ac62f7adeb08c8b6cd98aa41f4105f3b3900dc7e Mon Sep 17 00:00:00 2001 From: Dereku Date: Tue, 17 Apr 2018 16:41:58 +0700 Subject: [PATCH 3/8] This_happens.gif --- .../inventory/slot/SlotManager.java | 3 +- .../rpginventory/pet/CooldownTimer.java | 2 + .../rpginventory/pet/CooldownsTimer.java | 132 ++++++++++++++++++ .../rpginventory/pet/PetManager.java | 5 +- 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java diff --git a/src/main/java/ru/endlesscode/rpginventory/inventory/slot/SlotManager.java b/src/main/java/ru/endlesscode/rpginventory/inventory/slot/SlotManager.java index 406b587..ae831f4 100644 --- a/src/main/java/ru/endlesscode/rpginventory/inventory/slot/SlotManager.java +++ b/src/main/java/ru/endlesscode/rpginventory/inventory/slot/SlotManager.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.logging.Level; /** * Created by OsipXD on 05.09.2015 @@ -79,7 +80,7 @@ public static boolean init() { try { SlotManager.slotManager = new SlotManager(); } catch (Exception e) { - e.printStackTrace(); + RPGInventory.getPluginLogger().log(Level.WARNING, "Failed to initialize SlotManager", e); return false; } diff --git a/src/main/java/ru/endlesscode/rpginventory/pet/CooldownTimer.java b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownTimer.java index 93ecc0a..78c6920 100644 --- a/src/main/java/ru/endlesscode/rpginventory/pet/CooldownTimer.java +++ b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownTimer.java @@ -35,10 +35,12 @@ * It is part of the RpgInventory. * All rights reserved 2014 - 2016 © «EndlessCode Group» */ +@Deprecated class CooldownTimer extends BukkitRunnable { private final Player player; private final ItemStack petItem; + @Deprecated public CooldownTimer(Player player, ItemStack petItem) { this.player = player; this.petItem = petItem; diff --git a/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java new file mode 100644 index 0000000..8451756 --- /dev/null +++ b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java @@ -0,0 +1,132 @@ +package ru.endlesscode.rpginventory.pet; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; +import ru.endlesscode.rpginventory.RPGInventory; +import ru.endlesscode.rpginventory.inventory.InventoryManager; +import ru.endlesscode.rpginventory.inventory.slot.Slot; +import ru.endlesscode.rpginventory.inventory.slot.SlotManager; +import ru.endlesscode.rpginventory.utils.ItemUtils; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by Dereku on 17.04.2018 + * It is part of the RpgInventory. + * All rights reserved 2014 - 2018 © «EndlessCode Group» + */ +public class CooldownsTimer extends BukkitRunnable { + + public final static int TICK_PERIOD = 5; + private final static int TICK_RATE = 20 / CooldownsTimer.TICK_PERIOD; + //temporaryMap for avoid CME. + private final HashMap petItemsByPlayer = new HashMap<>(), temporaryMap = new HashMap<>(); + private final RPGInventory plugin; + private final Slot petSlot; + + @SuppressWarnings("WeakerAccess") + public CooldownsTimer(RPGInventory pluginInstance) { + this.plugin = pluginInstance; + this.petSlot = Objects.requireNonNull(SlotManager.instance().getPetSlot(), "Pet slot can't be null!"); + } + + public void addPetCooldown(Player player, ItemStack itemStack) { + if (player == null || itemStack == null || itemStack.getType() == Material.AIR) { + //throw new IllegalArgumentException? + return; + } + + if (PetManager.getPetFromItem(itemStack) == null) { + //throw new IllegalArgumentException? + return; + } + + this.temporaryMap.put(player.getUniqueId(), new ValuePair(itemStack, new AtomicInteger(0))); + + } + + @Override + public void run() { + //Because there is no safe way to iterate map. + if (!this.temporaryMap.isEmpty()) { + this.petItemsByPlayer.putAll(this.temporaryMap); + this.temporaryMap.clear(); + } + + final Iterator> iterator = this.petItemsByPlayer.entrySet().iterator(); + while (iterator.hasNext()) { + final Map.Entry next = iterator.next(); + int ticks = next.getValue().getTimer().incrementAndGet(); + + if (ticks % CooldownsTimer.TICK_RATE != 0) { + continue; + } + + final Player player = this.plugin.getServer().getPlayer(next.getKey()); + if (player == null || !InventoryManager.playerIsLoaded(player)) { + iterator.remove(); + continue; + } + + final Inventory inventory = InventoryManager.get(player).getInventory(); + if (inventory == null || inventory.getItem(PetManager.getPetSlotId()) == null) { + iterator.remove(); + continue; + } + + //Future bug fix of multiple pets cooldown + if (!inventory.getItem(PetManager.getPetSlotId()).isSimilar(next.getValue().getItemStack())) { + iterator.remove(); + continue; + } + + int cooldown = PetManager.getCooldown(next.getValue().getItemStack()); + if (1 > cooldown) { + PetManager.saveDeathTime(next.getValue().getItemStack(), 0); + PetManager.spawnPet(player, next.getValue().getItemStack()); + inventory.setItem(PetManager.getPetSlotId(), next.getValue().getItemStack()); + iterator.remove(); + } else if (60 >= cooldown) { + final ItemStack item = next.getValue().getItemStack().clone(); + final ItemMeta itemMeta = item.getItemMeta(); + itemMeta.setDisplayName( + itemMeta.getDisplayName() + RPGInventory.getLanguage().getMessage("pet.cooldown", cooldown) + ); + item.setItemMeta(itemMeta); + PetManager.addGlow(item); + + String itemTag = ItemUtils.getTag(item, ItemUtils.PET_TAG); + if (itemTag != null) { + ItemUtils.setTag(item, ItemUtils.PET_TAG, itemTag); + inventory.setItem(PetManager.getPetSlotId(), item); + } else { + inventory.setItem(PetManager.getPetSlotId(), this.petSlot.getCup()); + iterator.remove(); + } + } + } + } + + private class ValuePair { + private final ItemStack itemStack; + private final AtomicInteger timer; + + private ValuePair(ItemStack itemStack, AtomicInteger timer) { + this.itemStack = itemStack; + this.timer = timer; + } + + private ItemStack getItemStack() { + return itemStack; + } + + private AtomicInteger getTimer() { + return timer; + } + } +} diff --git a/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java b/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java index 4327410..0276726 100644 --- a/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java +++ b/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java @@ -71,6 +71,7 @@ public class PetManager { private static final Map PETS = new HashMap<>(); private static final Map PET_FOOD = new HashMap<>(); private static final String DEATH_TIME_TAG = "pet.deathTime"; + private static CooldownsTimer COOLDOWNS_TIMER; private static int SLOT_PET; private PetManager() { @@ -114,6 +115,8 @@ public static boolean init(@NotNull RPGInventory instance) { // Register events instance.getServer().getPluginManager().registerEvents(new PetListener(), instance); + PetManager.COOLDOWNS_TIMER = new CooldownsTimer(instance); + PetManager.COOLDOWNS_TIMER.runTaskTimer(instance,20, CooldownsTimer.TICK_PERIOD); return true; } @@ -171,7 +174,7 @@ public static List getFoodList() { } public static void startCooldownTimer(Player player, ItemStack petItem) { - new CooldownTimer(player, petItem).runTaskTimer(RPGInventory.getInstance(), 20, 20); + PetManager.COOLDOWNS_TIMER.addPetCooldown(player, petItem); } public static void spawnPet(@NotNull final Player player, @NotNull ItemStack petItem) { From e49c1373c1da0e6897966bb805223fd57f251133 Mon Sep 17 00:00:00 2001 From: Dereku Date: Tue, 17 Apr 2018 16:54:17 +0700 Subject: [PATCH 4/8] Possible fix #110 --- .../event/listener/PetListener.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java index e23a322..4433e8b 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java @@ -34,10 +34,7 @@ import org.bukkit.event.entity.EntityTargetLivingEntityEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.*; import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.inventory.HorseInventory; import org.bukkit.inventory.Inventory; @@ -119,6 +116,21 @@ public void onPlayerRespawn(@NotNull PlayerRespawnEvent event) { } } + //Possible fix #110 + @EventHandler + public void onPlayerTeleport(@NotNull PlayerTeleportEvent event) { + Player player = event.getPlayer(); + + if (!InventoryManager.playerIsLoaded(player) || !PetManager.isEnabled()) { + return; + } + + ItemStack petItem = InventoryManager.get(player).getInventory().getItem(PetManager.getPetSlotId()); + if (!ItemUtils.isEmpty(petItem)) { + PetManager.spawnPet(player, petItem); + } + } + @EventHandler public void onPetFeed(@NotNull PlayerInteractEntityEvent event) { Player player = event.getPlayer(); From 809266b569b0baaabb5781ccb8899f1fc40d8fd7 Mon Sep 17 00:00:00 2001 From: Dereku Date: Mon, 23 Apr 2018 00:18:19 +0700 Subject: [PATCH 5/8] Fix of Fix of Possible fix #110 --- .../event/listener/PetListener.java | 37 +++++++++++------- .../rpginventory/pet/CooldownsTimer.java | 5 ++- .../rpginventory/pet/PetManager.java | 24 +++++++++--- .../rpginventory/utils/EntityUtils.java | 38 +++++++++++-------- .../rpginventory/utils/LocationUtils.java | 17 ++++++--- 5 files changed, 79 insertions(+), 42 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java index 4433e8b..3c02ecc 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java @@ -18,21 +18,13 @@ package ru.endlesscode.rpginventory.event.listener; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.Sound; +import org.bukkit.*; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.EntityPortalEnterEvent; -import org.bukkit.event.entity.EntityTargetLivingEntityEvent; -import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.*; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.player.*; import org.bukkit.event.vehicle.VehicleEnterEvent; @@ -40,7 +32,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; import ru.endlesscode.rpginventory.RPGInventory; import ru.endlesscode.rpginventory.inventory.InventoryManager; import ru.endlesscode.rpginventory.inventory.PlayerWrapper; @@ -125,10 +117,27 @@ public void onPlayerTeleport(@NotNull PlayerTeleportEvent event) { return; } - ItemStack petItem = InventoryManager.get(player).getInventory().getItem(PetManager.getPetSlotId()); - if (!ItemUtils.isEmpty(petItem)) { - PetManager.spawnPet(player, petItem); + if (!InventoryManager.get(player).hasPet()) { + return; } + + //Ugly trick to avoid infinite pet spawning when player teleports from non-solid/non-cuboid block + final Location from = event.getFrom(); + final Location to = event.getTo(); + if (from.getBlockX() == to.getBlockX() && from.getBlockZ() == to.getBlockZ()) { + if (from.distance(to) < 0.775D) { + return; + } + } + + final double maxDistance = (event.getPlayer().getServer().getViewDistance() / 2.0D) * 15.75D; + final ItemStack item = InventoryManager.get(player).getInventory().getItem(PetManager.getPetSlotId()); + if (from.distance(to) > maxDistance && item != null) { + PetManager.spawnPet(player, item); + } else { + PetManager.teleportPet(player, to); + } + } @EventHandler diff --git a/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java index 8451756..160e51e 100644 --- a/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java +++ b/src/main/java/ru/endlesscode/rpginventory/pet/CooldownsTimer.java @@ -80,10 +80,11 @@ public void run() { } //Future bug fix of multiple pets cooldown - if (!inventory.getItem(PetManager.getPetSlotId()).isSimilar(next.getValue().getItemStack())) { + //TODO: Improve that. If we need it, ofc. + /*if (!inventory.getItem(PetManager.getPetSlotId()).isSimilar(next.getValue().getItemStack())) { iterator.remove(); continue; - } + }*/ int cooldown = PetManager.getCooldown(next.getValue().getItemStack()); if (1 > cooldown) { diff --git a/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java b/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java index 0276726..b7a46d5 100644 --- a/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java +++ b/src/main/java/ru/endlesscode/rpginventory/pet/PetManager.java @@ -48,10 +48,7 @@ import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import ru.endlesscode.rpginventory.RPGInventory; import ru.endlesscode.rpginventory.event.listener.PetListener; @@ -177,8 +174,23 @@ public static void startCooldownTimer(Player player, ItemStack petItem) { PetManager.COOLDOWNS_TIMER.addPetCooldown(player, petItem); } + public static void teleportPet(@NotNull final Player player, @Nullable final Location to) { + if (!InventoryManager.playerIsLoaded(player) || !PetManager.isEnabled()) { + return; + } + + final PlayerWrapper playerWrapper = InventoryManager.get(player); + if (!playerWrapper.hasPet()) { + return; + } + + Location baseLocation = to != null ? to : player.getLocation(); + Location newPetLoc = LocationUtils.getLocationNearPoint(baseLocation, 3); + playerWrapper.getPet().teleport(newPetLoc); + } + public static void spawnPet(@NotNull final Player player, @NotNull ItemStack petItem) { - if (!InventoryManager.playerIsLoaded(player)) { + if (!InventoryManager.playerIsLoaded(player) || !PetManager.isEnabled()) { return; } @@ -193,7 +205,7 @@ public static void spawnPet(@NotNull final Player player, @NotNull ItemStack pet } PetManager.despawnPet(player); - Location petLoc = LocationUtils.getLocationNearPlayer(player, 3); + Location petLoc = LocationUtils.getLocationNearPoint(player.getLocation(), 3); Animals pet = (Animals) player.getWorld().spawnEntity(petLoc, petType.getSkin()); pet.teleport(petLoc); EffectUtils.playSpawnEffect(pet); diff --git a/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java b/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java index 68caf36..23c2733 100644 --- a/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java +++ b/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java @@ -19,25 +19,38 @@ package ru.endlesscode.rpginventory.utils; import com.comphenix.protocol.utility.MinecraftReflection; - import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; import ru.endlesscode.rpginventory.inventory.InventoryManager; import ru.endlesscode.rpginventory.pet.PetManager; import ru.endlesscode.rpginventory.pet.PetType; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + /** * Created by OsipXD on 02.12.2015 * It is part of the RpgInventory. * All rights reserved 2014 - 2016 © «EndlessCode Group» */ public class EntityUtils { + + private static Method craftEntity_getHandle, navigationAbstract_a, entityInsentient_getNavigation; + private static Class entityInsentientClass = MinecraftReflection.getMinecraftClass("EntityInsentient"); + + static { + try { + craftEntity_getHandle = MinecraftReflection.getCraftEntityClass().getDeclaredMethod("getHandle"); + entityInsentient_getNavigation = entityInsentientClass.getDeclaredMethod("getNavigation"); + navigationAbstract_a = MinecraftReflection.getMinecraftClass("NavigationAbstract") + .getDeclaredMethod("a", double.class, double.class, double.class, double.class); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + public static void goPetToPlayer(@NotNull final Player player, @NotNull final LivingEntity entity) { if (!InventoryManager.playerIsLoaded(player) || !player.isOnline() || entity.isDead()) { return; @@ -53,16 +66,11 @@ public static void goPetToPlayer(@NotNull final Player player, @NotNull final Li PetType petType = PetManager.getPetFromEntity(entity, player); double speedModifier = petType == null ? 1.0 : 0.4 / petType.getSpeed(); - Class entityInsentientClass = MinecraftReflection.getMinecraftClass("EntityInsentient"); - Class navigationAbstractClass = MinecraftReflection.getMinecraftClass("NavigationAbstract"); - try { - Method getHandle = MinecraftReflection.getCraftEntityClass().getDeclaredMethod("getHandle"); - Object insentient = entityInsentientClass.cast(getHandle.invoke(entity)); - Object navigation = entityInsentientClass.getDeclaredMethod("getNavigation").invoke(insentient); - navigationAbstractClass.getDeclaredMethod("a", double.class, double.class, double.class, double.class) - .invoke(navigation, target.getX(), target.getY(), target.getZ(), speedModifier); - } catch (@NotNull IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + Object insentient = entityInsentientClass.cast(craftEntity_getHandle.invoke(entity)); + Object navigation = entityInsentient_getNavigation.invoke(insentient); + navigationAbstract_a.invoke(navigation, target.getX(), target.getY(), target.getZ(), speedModifier); + } catch (@NotNull IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } diff --git a/src/main/java/ru/endlesscode/rpginventory/utils/LocationUtils.java b/src/main/java/ru/endlesscode/rpginventory/utils/LocationUtils.java index eea38e2..f52342c 100644 --- a/src/main/java/ru/endlesscode/rpginventory/utils/LocationUtils.java +++ b/src/main/java/ru/endlesscode/rpginventory/utils/LocationUtils.java @@ -26,7 +26,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -38,11 +38,18 @@ * All rights reserved 2014 - 2016 © «EndlessCode Group» */ public class LocationUtils { + private static final Random RANDOM = new Random(); + + @Deprecated public static Location getLocationNearPlayer(Player player, int radius) { - Block playerBlock = player.getLocation().getBlock(); + return LocationUtils.getLocationNearPoint(player.getLocation(), radius); + } + + public static Location getLocationNearPoint(Location location, int radius) { + Block playerBlock = location.getBlock(); List availableLocations = new ArrayList<>(); - World world = player.getWorld(); + World world = location.getWorld(); for (int x = playerBlock.getX() - radius; x < playerBlock.getX() + radius; x++) { for (int y = playerBlock.getY() - radius; y < playerBlock.getY() + radius; y++) { for (int z = playerBlock.getZ() - radius; z < playerBlock.getZ() + radius; z++) { @@ -50,7 +57,7 @@ public static Location getLocationNearPlayer(Player player, int radius) { if (loc.getBlock().isEmpty()) { Block underBlock = loc.clone().subtract(0, 1, 0).getBlock(); if (!underBlock.isEmpty() && !underBlock.isLiquid()) { - loc.setYaw((float) (-180 + Math.random() * 360)); + loc.setYaw(-180 + LocationUtils.RANDOM.nextFloat() * 360); availableLocations.add(loc); } } @@ -62,7 +69,7 @@ public static Location getLocationNearPlayer(Player player, int radius) { return getBlockCenter(playerBlock.getLocation().clone()); } - return availableLocations.get(new Random().nextInt(availableLocations.size())); + return availableLocations.get(LocationUtils.RANDOM.nextInt(availableLocations.size())); } public static Location getBlockCenter(Location loc) { From 9d343d7c3320cfc2bd58f5e18b1b9f69d1a11806 Mon Sep 17 00:00:00 2001 From: Dereku Date: Mon, 23 Apr 2018 02:17:40 +0700 Subject: [PATCH 6/8] Fixes #120 12Feb18 --- .../rpginventory/utils/EntityUtils.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java b/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java index 23c2733..b9faede 100644 --- a/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java +++ b/src/main/java/ru/endlesscode/rpginventory/utils/EntityUtils.java @@ -57,9 +57,17 @@ public static void goPetToPlayer(@NotNull final Player player, @NotNull final Li } Location target = player.getLocation(); - if (target.distance(entity.getLocation()) > 20) { - PetManager.respawnPet(player); - } else if (target.distance(entity.getLocation()) < 4) { + + //Issue #120, by 12 Feb 18 : https://github.com/EndlessCodeGroup/RPGInventory/issues/120#issuecomment-364834420 + if (!target.getWorld().getName().equals(entity.getLocation().getWorld().getName())) { + PetManager.teleportPet(player, null); + return; + } + + final double distance = target.distance(entity.getLocation()); + if (distance > 20D) { + PetManager.teleportPet(player, null); + } else if (distance < 4D) { return; } From 27e716f9053f6cb48664775b879206c919bb8ff2 Mon Sep 17 00:00:00 2001 From: Dereku Date: Wed, 25 Apr 2018 17:05:50 +0700 Subject: [PATCH 7/8] Oops --- .../ru/endlesscode/rpginventory/event/listener/PetListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java index 3c02ecc..fc206ab 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java @@ -109,7 +109,7 @@ public void onPlayerRespawn(@NotNull PlayerRespawnEvent event) { } //Possible fix #110 - @EventHandler + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) public void onPlayerTeleport(@NotNull PlayerTeleportEvent event) { Player player = event.getPlayer(); From 193bcd53b655770866c0f01d57007980d3b206ba Mon Sep 17 00:00:00 2001 From: Dereku Date: Wed, 25 Apr 2018 18:47:02 +0700 Subject: [PATCH 8/8] "Not up to standards." --- .../rpginventory/event/listener/PetListener.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java index fc206ab..f16a56b 100644 --- a/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java +++ b/src/main/java/ru/endlesscode/rpginventory/event/listener/PetListener.java @@ -124,10 +124,11 @@ public void onPlayerTeleport(@NotNull PlayerTeleportEvent event) { //Ugly trick to avoid infinite pet spawning when player teleports from non-solid/non-cuboid block final Location from = event.getFrom(); final Location to = event.getTo(); - if (from.getBlockX() == to.getBlockX() && from.getBlockZ() == to.getBlockZ()) { - if (from.distance(to) < 0.775D) { - return; - } + if (from.getBlockX() != to.getBlockX() || from.getBlockZ() != to.getBlockZ()) { + return; + } + if (from.distance(to) < 0.775D) { + return; } final double maxDistance = (event.getPlayer().getServer().getViewDistance() / 2.0D) * 15.75D;