mirror of
https://github.com/amalthea-mc/ShopChest.git
synced 2024-12-23 01:21:47 +00:00
Performance improvements & shop updater refactor
This commit is contained in:
parent
0cf4fbf893
commit
67f12872a9
@ -185,7 +185,7 @@ public class ShopChest extends JavaPlugin {
|
||||
|
||||
if (updater != null) {
|
||||
debug("Stopping updater");
|
||||
updater.cancel();
|
||||
updater.stop();
|
||||
}
|
||||
|
||||
if (database != null) {
|
||||
@ -433,13 +433,6 @@ public class ShopChest extends JavaPlugin {
|
||||
return updater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ShopUpdater} that schedules hologram and item updates
|
||||
*/
|
||||
public void setUpdater(ShopUpdater updater) {
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the plugin 'AreaShop' is enabled
|
||||
*/
|
||||
|
@ -4,9 +4,7 @@ import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
import de.epiceric.shopchest.utils.ShopUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
@ -15,7 +13,8 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
|
||||
public class ShopItemListener implements Listener {
|
||||
@ -34,6 +33,9 @@ public class ShopItemListener implements Listener {
|
||||
if (shop.getItem() != null) {
|
||||
shop.getItem().setVisible(e.getPlayer(), false);
|
||||
}
|
||||
if (shop.getHologram() != null) {
|
||||
shop.getHologram().hidePlayer(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,10 @@
|
||||
package de.epiceric.shopchest.listeners;
|
||||
|
||||
import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.shop.Shop;
|
||||
import de.epiceric.shopchest.utils.Callback;
|
||||
import de.epiceric.shopchest.utils.ShopUpdater;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class ShopUpdateListener implements Listener {
|
||||
|
||||
@ -23,48 +14,6 @@ public class ShopUpdateListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(final PlayerTeleportEvent e) {
|
||||
// Wait till the chunk should have loaded on the client
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideShops(e.getPlayer(), true);
|
||||
plugin.getShopUtils().updateShops(e.getPlayer(), true);
|
||||
}
|
||||
}.runTaskLater(plugin, 15L);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
restartShopUpdater(e.getPlayer());
|
||||
}
|
||||
|
||||
// The Bukkit::getOnlinePlayers() list does not include players that
|
||||
// are currently respawning or chaning worlds, so when only one player is
|
||||
// online and is currently respawning, the updater will think that no player
|
||||
// is online, so it will stop. To prevent that, a delay of 1 tick is needed.
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerChangedWorld(final PlayerChangedWorldEvent e) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
restartShopUpdater(e.getPlayer());
|
||||
}
|
||||
}.runTaskLater(plugin, 1L);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerRespawn(final PlayerRespawnEvent e) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
restartShopUpdater(e.getPlayer());
|
||||
}
|
||||
}.runTaskLater(plugin, 1L);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldLoad(WorldLoadEvent e) {
|
||||
final String worldName = e.getWorld().getName();
|
||||
@ -81,24 +30,4 @@ public class ShopUpdateListener implements Listener {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void restartShopUpdater(Player p) {
|
||||
if (!plugin.getUpdater().isRunning()) {
|
||||
plugin.setUpdater(new ShopUpdater(plugin));
|
||||
plugin.getUpdater().start();
|
||||
}
|
||||
|
||||
hideShops(p, false);
|
||||
}
|
||||
|
||||
private void hideShops(Player p, boolean onlyItem) {
|
||||
for (Shop shop : plugin.getShopUtils().getShops()) {
|
||||
if (!onlyItem) {
|
||||
if (shop.getHologram() != null) shop.getHologram().hidePlayer(p);
|
||||
}
|
||||
|
||||
if (shop.getItem() != null) shop.getItem().setVisible(p, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,14 +2,14 @@ package de.epiceric.shopchest.nms;
|
||||
|
||||
import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.config.Config;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class Hologram {
|
||||
|
||||
@ -19,7 +19,7 @@ public class Hologram {
|
||||
private List<ArmorStandWrapper> wrappers = new ArrayList<>();
|
||||
private ArmorStandWrapper interactArmorStandWrapper;
|
||||
private Location location;
|
||||
private List<Player> visible = new ArrayList<>();
|
||||
private Set<UUID> visibility = new HashSet<>();
|
||||
private ShopChest plugin;
|
||||
private Config config;
|
||||
|
||||
@ -66,8 +66,11 @@ public class Hologram {
|
||||
wrappers.add(line, wrapper);
|
||||
|
||||
if (forceUpdateLine) {
|
||||
for (Player player : visible) {
|
||||
wrapper.setVisible(player, true);
|
||||
for (UUID uuid : visibility) {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
wrapper.setVisible(player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,40 +151,44 @@ public class Hologram {
|
||||
* @param p Player to which the hologram should be shown
|
||||
*/
|
||||
public void showPlayer(final Player p) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (ArmorStandWrapper wrapper : wrappers) {
|
||||
wrapper.setVisible(p, true);
|
||||
}
|
||||
if (!isVisible(p)) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (ArmorStandWrapper wrapper : wrappers) {
|
||||
wrapper.setVisible(p, true);
|
||||
}
|
||||
|
||||
if (interactArmorStandWrapper != null) {
|
||||
interactArmorStandWrapper.setVisible(p, true);
|
||||
if (interactArmorStandWrapper != null) {
|
||||
interactArmorStandWrapper.setVisible(p, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}.runTaskAsynchronously(plugin);
|
||||
|
||||
visible.add(p);
|
||||
visibility.add(p.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p Player from which the hologram should be hidden
|
||||
*/
|
||||
public void hidePlayer(final Player p) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (ArmorStandWrapper wrapper : wrappers) {
|
||||
wrapper.setVisible(p, false);
|
||||
}
|
||||
if (isVisible(p)) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (ArmorStandWrapper wrapper : wrappers) {
|
||||
wrapper.setVisible(p, false);
|
||||
}
|
||||
|
||||
if (interactArmorStandWrapper != null) {
|
||||
interactArmorStandWrapper.setVisible(p, false);
|
||||
if (interactArmorStandWrapper != null) {
|
||||
interactArmorStandWrapper.setVisible(p, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}.runTaskAsynchronously(plugin);
|
||||
|
||||
visible.remove(p);
|
||||
visibility.remove(p.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,7 +196,7 @@ public class Hologram {
|
||||
* @return Whether the hologram is visible to the player
|
||||
*/
|
||||
public boolean isVisible(Player p) {
|
||||
return visible.contains(p);
|
||||
return visibility.contains(p.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@ package de.epiceric.shopchest.shop;
|
||||
|
||||
import de.epiceric.shopchest.ShopChest;
|
||||
import de.epiceric.shopchest.utils.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -9,13 +10,14 @@ import org.bukkit.inventory.ItemStack;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ShopItem {
|
||||
|
||||
private ShopChest plugin;
|
||||
private Map<Player, Boolean> visible = new HashMap<>();
|
||||
private Set<UUID> visibility = new HashSet<>();
|
||||
private ItemStack itemStack;
|
||||
private Location location;
|
||||
|
||||
@ -88,8 +90,9 @@ public class ShopItem {
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
for (Player p : visible.keySet()) {
|
||||
if (isVisible(p)) setVisible(p, false);
|
||||
for (UUID uuid : visibility) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null) setVisible(p, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +106,7 @@ public class ShopItem {
|
||||
}
|
||||
|
||||
public boolean isVisible(Player p) {
|
||||
return visible.get(p) == null ? false : visible.get(p);
|
||||
return visibility.contains(p.getUniqueId());
|
||||
}
|
||||
|
||||
public void setVisible(final Player p, boolean visible) {
|
||||
@ -114,6 +117,7 @@ public class ShopItem {
|
||||
for (Object packet : this.creationPackets) {
|
||||
Utils.sendPacket(plugin, packet, p);
|
||||
}
|
||||
visibility.add(p.getUniqueId());
|
||||
} else {
|
||||
try {
|
||||
if (p.isOnline()) {
|
||||
@ -125,9 +129,8 @@ public class ShopItem {
|
||||
plugin.debug("Failed to destroy shop item with reflection");
|
||||
plugin.debug(e);
|
||||
}
|
||||
visibility.remove(p.getUniqueId());
|
||||
}
|
||||
|
||||
this.visible.put(p, visible);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,11 +3,9 @@ package de.epiceric.shopchest.utils;
|
||||
import de.epiceric.shopchest.ShopChest;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ShopUpdater extends BukkitRunnable {
|
||||
public class ShopUpdater {
|
||||
|
||||
public enum UpdateQuality {
|
||||
SLOWEST(31L),
|
||||
@ -18,7 +16,7 @@ public class ShopUpdater extends BukkitRunnable {
|
||||
FASTER(4L),
|
||||
FASTEST(1L);
|
||||
|
||||
private long interval;
|
||||
private final long interval;
|
||||
|
||||
UpdateQuality(long interval) {
|
||||
this.interval = interval;
|
||||
@ -29,47 +27,64 @@ public class ShopUpdater extends BukkitRunnable {
|
||||
}
|
||||
}
|
||||
|
||||
private ShopChest plugin;
|
||||
private final ShopChest plugin;
|
||||
|
||||
private boolean running;
|
||||
private long interval;
|
||||
private long interval = UpdateQuality.NORMAL.getInterval();
|
||||
|
||||
private volatile BukkitTask running;
|
||||
|
||||
public ShopUpdater(ShopChest plugin) {
|
||||
this.plugin = plugin;
|
||||
setInterval(plugin.getShopChestConfig().update_quality.getInterval());
|
||||
}
|
||||
|
||||
public synchronized void setInterval(long interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public synchronized void start() {
|
||||
super.runTaskTimerAsynchronously(plugin, interval, interval);
|
||||
running = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void cancel() {
|
||||
if (running) {
|
||||
running = false;
|
||||
super.cancel();
|
||||
/**
|
||||
* Start task, except if it is already
|
||||
*/
|
||||
public void start() {
|
||||
if (!isRunning()) {
|
||||
interval = plugin.getShopChestConfig().update_quality.getInterval();
|
||||
running = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new ShopUpdaterTask(plugin), interval, interval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop any running task then start it again
|
||||
*/
|
||||
public void restart() {
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop task properly
|
||||
*/
|
||||
public void stop() {
|
||||
if (running != null) {
|
||||
running.cancel();
|
||||
running = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether task is running or not
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
return running != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<? extends Player> players = Bukkit.getOnlinePlayers();
|
||||
private static class ShopUpdaterTask implements Runnable {
|
||||
|
||||
if (players.isEmpty()) {
|
||||
cancel();
|
||||
private final ShopChest plugin;
|
||||
|
||||
private ShopUpdaterTask(ShopChest plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
for (Player p : players) {
|
||||
plugin.getShopUtils().updateShops(p);
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
plugin.getShopUtils().updateShops(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -218,10 +218,7 @@ public class ShopUtils {
|
||||
if (reloadConfig) {
|
||||
plugin.getShopChestConfig().reload(false, true, showConsoleMessages);
|
||||
plugin.getHologramFormat().reload();
|
||||
plugin.getUpdater().cancel();
|
||||
|
||||
plugin.setUpdater(new ShopUpdater(plugin));
|
||||
plugin.getUpdater().start();
|
||||
plugin.getUpdater().restart();
|
||||
}
|
||||
|
||||
plugin.getShopDatabase().connect(new Callback(plugin) {
|
||||
@ -314,9 +311,7 @@ public class ShopUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Shop shop : getShops()) {
|
||||
updateShop(shop, player);
|
||||
}
|
||||
updateNearestShops(player);
|
||||
}
|
||||
|
||||
playerLocation.put(player, player.getLocation());
|
||||
@ -370,27 +365,36 @@ public class ShopUtils {
|
||||
double holoDistSqr = Math.pow(plugin.getShopChestConfig().maximal_distance, 2);
|
||||
double itemDistSqr = Math.pow(plugin.getShopChestConfig().maximal_item_distance, 2);
|
||||
|
||||
updateShop(shop, player, holoDistSqr, itemDistSqr);
|
||||
}
|
||||
|
||||
private void updateNearestShops(Player p) {
|
||||
double holoDistSqr = Math.pow(plugin.getShopChestConfig().maximal_distance, 2);
|
||||
double itemDistSqr = Math.pow(plugin.getShopChestConfig().maximal_item_distance, 2);
|
||||
|
||||
for (Shop shop : getShops()) {
|
||||
updateShop(shop, p, holoDistSqr, itemDistSqr);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateShop(Shop shop, Player player, double holoDistSqr, double itemDistSqr) {
|
||||
if (player.getLocation().getWorld().getName().equals(shop.getLocation().getWorld().getName())) {
|
||||
double distSqr = shop.getLocation().distanceSquared(player.getLocation());
|
||||
|
||||
if (distSqr <= holoDistSqr) {
|
||||
if (shop.getHologram() != null) {
|
||||
if (!shop.getHologram().isVisible(player)) {
|
||||
shop.getHologram().showPlayer(player);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (shop.getHologram() != null) {
|
||||
if (shop.getHologram() != null) {
|
||||
if (distSqr <= holoDistSqr) {
|
||||
shop.getHologram().showPlayer(player);
|
||||
} else {
|
||||
shop.getHologram().hidePlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (distSqr <= itemDistSqr) {
|
||||
if (shop.getItem() != null) {
|
||||
if (shop.getItem() != null) {
|
||||
if (distSqr <= itemDistSqr) {
|
||||
shop.getItem().setVisible(player, true);
|
||||
} else {
|
||||
shop.getItem().setVisible(player, false);
|
||||
}
|
||||
} else {
|
||||
if (shop.getItem() != null) shop.getItem().setVisible(player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ version: ${project.version}
|
||||
author: EpicEric
|
||||
website: ${project.url}
|
||||
description: Create your own nice-looking chest shops and sell your stuff to other players!
|
||||
softdepend: [WorldGuard, Towny, AuthMe, PlotSquared, uSkyBlock, ASkyBlock, IslandWorld, GriefPrevention, AreaShop]
|
||||
softdepend: [WorldGuard, Towny, AuthMe, PlotSquared, uSkyBlock, ASkyBlock, IslandWorld, GriefPrevention, AreaShop, Multiverse-Core, MultiWorld]
|
||||
depend: [Vault]
|
||||
|
||||
permissions:
|
||||
|
Loading…
Reference in New Issue
Block a user