From 5c2c3169b67b85b74c14db0800f5e9cdbc67150d Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 29 Jul 2018 21:52:54 +0200 Subject: [PATCH] Change shop updater logic I'm not sure if this better or worse, but it's worth a try. --- .../de/epiceric/shopchest/config/Config.java | 7 - .../epiceric/shopchest/utils/ShopUpdater.java | 66 +++------ .../epiceric/shopchest/utils/ShopUtils.java | 125 +++++++----------- src/main/resources/config.yml | 7 - 4 files changed, 68 insertions(+), 137 deletions(-) diff --git a/src/main/java/de/epiceric/shopchest/config/Config.java b/src/main/java/de/epiceric/shopchest/config/Config.java index 4bf07e2..a65694f 100644 --- a/src/main/java/de/epiceric/shopchest/config/Config.java +++ b/src/main/java/de/epiceric/shopchest/config/Config.java @@ -4,7 +4,6 @@ import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.language.LanguageUtils; import de.epiceric.shopchest.sql.Database; import de.epiceric.shopchest.utils.ItemUtils; -import de.epiceric.shopchest.utils.ShopUpdater; import de.epiceric.shopchest.utils.Utils; import org.bukkit.configuration.InvalidConfigurationException; @@ -22,11 +21,6 @@ import java.util.Set; public class Config { - /** - * The quality of hologram and item updating (performance saving, or better quality) - **/ - public static ShopUpdater.UpdateQuality updateQuality; - /** * The item with which a player can click a shop to retrieve information **/ @@ -460,7 +454,6 @@ public class Config { public void reload(boolean firstLoad, boolean langReload, boolean showMessages) { plugin.reloadConfig(); - updateQuality = ShopUpdater.UpdateQuality.valueOf(plugin.getConfig().getString("update-quality")); shopInfoItem = ItemUtils.getItemStack(plugin.getConfig().getString("shop-info-item")); wgAllowCreateShopDefault = plugin.getConfig().getBoolean("worldguard-default-flag-values.create-shop"); wgAllowUseAdminShopDefault = plugin.getConfig().getBoolean("worldguard-default-flag-values.use-admin-shop"); diff --git a/src/main/java/de/epiceric/shopchest/utils/ShopUpdater.java b/src/main/java/de/epiceric/shopchest/utils/ShopUpdater.java index de09030..42146f5 100644 --- a/src/main/java/de/epiceric/shopchest/utils/ShopUpdater.java +++ b/src/main/java/de/epiceric/shopchest/utils/ShopUpdater.java @@ -1,40 +1,18 @@ package de.epiceric.shopchest.utils; import de.epiceric.shopchest.ShopChest; -import de.epiceric.shopchest.config.Config; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitTask; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class ShopUpdater { - - public enum UpdateQuality { - SLOWEST(31L), - SLOWER(24L), - SLOW(17L), - NORMAL(10L), - FAST(7L), - FASTER(4L), - FASTEST(1L); - - private final long interval; - - UpdateQuality(long interval) { - this.interval = interval; - } - - public long getInterval() { - return interval; - } - } - + private final ShopChest plugin; private final Queue beforeNext = new ConcurrentLinkedQueue<>(); - private volatile BukkitTask running; + private volatile Thread thread; public ShopUpdater(ShopChest plugin) { this.plugin = plugin; @@ -45,8 +23,19 @@ public class ShopUpdater { */ public void start() { if (!isRunning()) { - long interval = Config.updateQuality.getInterval(); - running = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new ShopUpdaterTask(), interval, interval); + thread = new Thread(() -> { + while (!Thread.interrupted()) { + for (Runnable runnable : beforeNext) { + runnable.run(); + } + beforeNext.clear(); + + for (Player p : Bukkit.getOnlinePlayers()) { + plugin.getShopUtils().updateShops(p); + } + } + }, "Shop Updater"); + thread.start(); } } @@ -62,9 +51,9 @@ public class ShopUpdater { * Stop task properly */ public void stop() { - if (running != null) { - running.cancel(); - running = null; + if (thread != null) { + thread.interrupt(); + thread = null; } } @@ -72,7 +61,7 @@ public class ShopUpdater { * @return whether task is running or not */ public boolean isRunning() { - return running != null; + return thread != null; } /** @@ -83,21 +72,4 @@ public class ShopUpdater { public void beforeNext(Runnable runnable) { beforeNext.add(runnable); } - - private class ShopUpdaterTask implements Runnable { - - @Override - public void run() { - if (!beforeNext.isEmpty()) { - for (Runnable runnable : beforeNext) { - runnable.run(); - } - beforeNext.clear(); - } - - for (Player p : Bukkit.getOnlinePlayers()) { - plugin.getShopUtils().updateShops(p); - } - } - } } diff --git a/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java b/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java index e290d06..ffffc19 100644 --- a/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java +++ b/src/main/java/de/epiceric/shopchest/utils/ShopUtils.java @@ -307,105 +307,78 @@ public class ShopUtils { playerLocation.remove(player.getUniqueId()); } - private static final double TARGET_THRESHOLD = 1; - private void updateVisibleShops(Player player) { double itemDistSquared = Math.pow(Config.maximalItemDistance, 2); - double hologramDistSquared = Math.pow(Config.maximalDistance, 2); + boolean firstShopInSight = Config.onlyShowFirstShopInSight; + double maxDist = Config.maximalDistance; - boolean firstShopInSight =Config.onlyShowFirstShopInSight; - - // used if onlyShowFirstShopInSight - List otherShopsInSight = firstShopInSight ? new ArrayList() : null; - double nearestDistance = 0; + List shopsInSight = new ArrayList<>(); + double nearestDistSquared = Double.MAX_VALUE; Shop nearestShop = null; Location pLoc = player.getEyeLocation(); - double pX = pLoc.getX(); - double pY = pLoc.getY(); - double pZ = pLoc.getZ(); Vector pDir = pLoc.getDirection(); - double dirLength = pDir.length(); + + // Display holograms based on sight + for (double i = 0; i <= maxDist; i++) { + Location loc = pLoc.clone(); + Vector dir = pDir.clone(); + double factor = Math.min(i, maxDist); + + loc.add(dir.multiply(factor)); + Location locBelow = loc.clone().subtract(0, 1, 0); + + // Check block below as player may look at hologram + Shop shop = getShop(loc); + if (shop == null) { + shop = getShop(locBelow); + } + + if (shop != null && shop.hasHologram()) { + shopsInSight.add(shop); + double distSquared = pLoc.distanceSquared(loc); + if (distSquared < nearestDistSquared) { + nearestDistSquared = distSquared; + nearestShop = shop; + } + } + } for (Shop shop : getShops()) { + if (firstShopInSight) { + if (!shop.equals(nearestShop) && shop.hasHologram()) { + shop.getHologram().hidePlayer(player); + } + } else { + if (!shopsInSight.contains(shop)) { + shop.getHologram().hidePlayer(player); + } + } + + // Display item based on distance Location shopLocation = shop.getLocation(); - if (shopLocation.getWorld().getName().equals(player.getWorld().getName())) { - double distanceSquared = shop.getLocation().distanceSquared(player.getLocation()); + double distSquared = shop.getLocation().distanceSquared(player.getLocation()); - // Display item based on distance if (shop.hasItem()) { - if (distanceSquared <= itemDistSquared) { + if (distSquared <= itemDistSquared) { shop.getItem().showPlayer(player); } else { shop.getItem().hidePlayer(player); } } - - // Display hologram based on sight - if (shop.hasHologram()) { - if (distanceSquared < hologramDistSquared) { - Location holoLocation = shop.getHologram().getLocation(); - - double x = holoLocation.getX() - pX; - double y = shopLocation.getY() - pY + 1.15; // chest block + item offset - double z = holoLocation.getZ() - pZ; - - // See: org.bukkit.util.Vector#angle(Vector) - double angle = FastMath.acos( - (x * pDir.getX() + y * pDir.getY() + z * pDir.getZ()) - / (FastMath.sqrt(x * x + y * y + z * z) * dirLength) - ); - - double distance = FastMath.sqrt(distanceSquared); - - // Check if is targeted - if (angle * distance < TARGET_THRESHOLD) { - // Display even if not the nearest - if (!firstShopInSight) { - shop.getHologram().showPlayer(player); - continue; - } - - if (nearestShop == null) { - // nearestShop is null - // => we guess this one will be the nearest - nearestShop = shop; - nearestDistance = distance; - continue; - } else if (distance < nearestDistance) { - // nearestShop is NOT null && this shop is nearest - // => we'll hide nearestShop, and guess this one will be the nearest - otherShopsInSight.add(nearestShop); - nearestShop = shop; - nearestDistance = distance; - continue; - } else if (nearestShop.getLocation().equals(shop.getLocation())) { - // shops are the same (double chest) - // => skip since it's already been handled - continue; - } - // else: hologram is farther than nearest, so we hide it - } - } - - // If not in sight - shop.getHologram().hidePlayer(player); - } } } - if (firstShopInSight) { - // we hide other shop as we wan't to display only the first - for (Shop shop : otherShopsInSight) { - // we already checked hasHologram() before adding it - shop.getHologram().hidePlayer(player); - } - } - - if (nearestShop != null && nearestShop.hasHologram()) { + if (nearestShop != null) { nearestShop.getHologram().showPlayer(player); } + + if (!firstShopInSight) { + for (Shop otherShop : shopsInSight) { + otherShop.getHologram().showPlayer(player); + } + } } private void updateNearestShops(Player p) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 573304b..2ddca6c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,13 +16,6 @@ language-file: "en_US" # Set whether the floating shop items on top of the chest should be shown show-shop-items: true -# Set the quality (speed) for hologram and item updating. -# Valid values are (from slowest to fastest): -# 'SLOWEST', 'SLOWER', 'SLOW', 'NORMAL', 'FAST', 'FASTER', 'FASTEST' -# The faster the value, the more performance will be used, which -# may lead to TPS loss. -update-quality: NORMAL - # Set the item with which a player can click a shop to retrieve information. # You can set this to an empty string to disable this feature. shop-info-item: "STICK"