From 69426c76dd507790b2b966489dfa29a562ea81c7 Mon Sep 17 00:00:00 2001 From: Thorinwasher Date: Wed, 21 Feb 2024 13:00:42 +0100 Subject: [PATCH] Refactor scheduling for stargate --- .../stargate/database/SQLDatabase.java | 26 +++--- .../org/sgrewritten/stargate/gate/Gate.java | 79 +++++++++++-------- .../stargate/gate/structure/GateIris.java | 31 ++++---- .../listener/PlayerEventListener.java | 42 ++++++---- .../network/StargateNetworkManager.java | 52 +++++++----- .../stargate/network/StargateRegistry.java | 30 ++++--- .../network/portal/AbstractPortal.java | 56 +++++++++---- .../network/portal/NetworkedPortal.java | 28 ++++--- .../stargate/network/portal/Teleporter.java | 69 +++++++++------- .../proxy/BukkitPluginMessageInterface.java | 17 ++-- .../thread/task/StargateAsyncTask.java | 24 ++++-- .../thread/task/StargateEntityTask.java | 17 +++- .../thread/task/StargateGlobalTask.java | 55 ++++++++----- .../thread/task/StargateQueuedAsyncTask.java | 36 +++++++-- .../thread/task/StargateRegionTask.java | 22 ++++-- .../stargate/thread/task/StargateTask.java | 33 ++++---- .../stargate/util/BungeeHelper.java | 7 ++ .../thread/task/StargateGlobalTaskTest.java | 63 +++++++++++---- 18 files changed, 444 insertions(+), 243 deletions(-) diff --git a/src/main/java/org/sgrewritten/stargate/database/SQLDatabase.java b/src/main/java/org/sgrewritten/stargate/database/SQLDatabase.java index 145fb4bf..3c8e5085 100644 --- a/src/main/java/org/sgrewritten/stargate/database/SQLDatabase.java +++ b/src/main/java/org/sgrewritten/stargate/database/SQLDatabase.java @@ -15,7 +15,6 @@ import org.sgrewritten.stargate.config.TableNameConfiguration; import org.sgrewritten.stargate.database.property.StoredPropertiesAPI; import org.sgrewritten.stargate.database.property.StoredProperty; -import org.sgrewritten.stargate.exception.GateConflictException; import org.sgrewritten.stargate.exception.InvalidStructureException; import org.sgrewritten.stargate.exception.PortalLoadException; import org.sgrewritten.stargate.exception.StargateInitializationException; @@ -289,18 +288,21 @@ private void loadPortal(PortalData portalData, StargateAPI stargateAPI) throws S final List portalPositions = getPortalPositions(portalData, network.getId()); //Actually register the gate and its positions - new StargateRegionTask(portalData.gateData().topLeft(), () -> { - try { - registerPortalGate(portalData, network, stargateAPI, portalPositions); - } catch (TranslatableException e) { - Stargate.log(e); - } catch (InvalidStructureException e) { - Stargate.log(Level.WARNING, String.format( - "The portal %s in %snetwork %s located at %s is in an invalid state, and could therefore not be recreated", - portalData.name(), (portalData.portalType() == StorageType.INTER_SERVER ? "inter-server-" : ""), portalData.networkName(), - portalData.gateData().topLeft())); + new StargateRegionTask(portalData.gateData().topLeft()) { + @Override + public void run() { + try { + registerPortalGate(portalData, network, stargateAPI, portalPositions); + } catch (TranslatableException e) { + Stargate.log(e); + } catch (InvalidStructureException e) { + Stargate.log(Level.WARNING, String.format( + "The portal %s in %snetwork %s located at %s is in an invalid state, and could therefore not be recreated", + portalData.name(), (portalData.portalType() == StorageType.INTER_SERVER ? "inter-server-" : ""), portalData.networkName(), + portalData.gateData().topLeft())); + } } - }).run(); + }.runNow(); } /** diff --git a/src/main/java/org/sgrewritten/stargate/gate/Gate.java b/src/main/java/org/sgrewritten/stargate/gate/Gate.java index 2ccc4262..2f6a6542 100644 --- a/src/main/java/org/sgrewritten/stargate/gate/Gate.java +++ b/src/main/java/org/sgrewritten/stargate/gate/Gate.java @@ -145,19 +145,22 @@ private void drawSigns(final SignLine[] signLines) { List activePortalPositions = getActivePortalPositions(PositionType.SIGN); for (PortalPosition portalPosition : activePortalPositions) { Location signLocation = getLocation(portalPosition.getRelativePositionLocation()); - new StargateRegionTask(signLocation, () -> { - Stargate.log(Level.FINER, "Drawing sign at location " + signLocation); - BlockState signState = signLocation.getBlock().getState(); - if (!(signState instanceof Sign sign)) { - Stargate.log(Level.FINE, "Could not find sign at position " + signLocation); - return; + new StargateRegionTask(signLocation){ + @Override + public void run() { + Stargate.log(Level.FINER, "Drawing sign at location " + signLocation); + BlockState signState = signLocation.getBlock().getState(); + if (!(signState instanceof Sign sign)) { + Stargate.log(Level.FINE, "Could not find sign at position " + signLocation); + return; + } + StargateSignFormatPortalEvent event = new StargateSignFormatPortalEvent(portal, signLines, portalPosition, signLocation); + Bukkit.getPluginManager().callEvent(event); + SignLine[] newSignLines = event.getLines(); + setSignLines(sign, newSignLines); + sign.update(); } - StargateSignFormatPortalEvent event = new StargateSignFormatPortalEvent(portal, signLines, portalPosition, signLocation); - Bukkit.getPluginManager().callEvent(event); - SignLine[] newSignLines = event.getLines(); - setSignLines(sign, newSignLines); - sign.update(); - }).run(); + }.runNow(); } } @@ -179,19 +182,22 @@ private void setSignLines(Sign sign, SignLine[] signLines) { private void drawButtons() { for (PortalPosition portalPosition : getActivePortalPositions(PositionType.BUTTON)) { Location buttonLocation = getLocation(portalPosition.getRelativePositionLocation()); - new StargateRegionTask(buttonLocation, () -> { - Material blockType = buttonLocation.getBlock().getType(); - if (ButtonHelper.isButton(blockType)) { - return; - } - Material buttonMaterial = ButtonHelper.getButtonMaterial(buttonLocation); - Stargate.log(Level.FINEST, "buttonMaterial: " + buttonMaterial); - Directional buttonData = (Directional) Bukkit.createBlockData(buttonMaterial); - buttonData.setFacing(facing); + new StargateRegionTask(buttonLocation) { + @Override + public void run() { + Material blockType = buttonLocation.getBlock().getType(); + if (ButtonHelper.isButton(blockType)) { + return; + } + Material buttonMaterial = ButtonHelper.getButtonMaterial(buttonLocation); + Stargate.log(Level.FINEST, "buttonMaterial: " + buttonMaterial); + Directional buttonData = (Directional) Bukkit.createBlockData(buttonMaterial); + buttonData.setFacing(facing); - buttonLocation.getBlock().setBlockData(buttonData); - BlockDropManager.disableBlockDrops(buttonLocation.getBlock()); - }).run(); + buttonLocation.getBlock().setBlockData(buttonData); + BlockDropManager.disableBlockDrops(buttonLocation.getBlock()); + } + }.runNow(); } } @@ -295,19 +301,22 @@ private void setIrisMaterial(Material material) { for (BlockLocation blockLocation : locations) { Block block = blockLocation.getLocation().getBlock(); - new StargateRegionTask(block.getLocation(), ()->{ - block.setBlockData(blockData); - if (material == Material.END_GATEWAY) {// force a location to prevent exit gateway generation - EndGateway gateway = (EndGateway) block.getState(); - // https://github.com/stargate-bukkit/Stargate-Bukkit/issues/36 - gateway.setAge(-9223372036854775808L); - if (block.getWorld().getEnvironment() == World.Environment.THE_END) { - gateway.setExitLocation(block.getLocation()); - gateway.setExactTeleport(true); + new StargateRegionTask(block.getLocation()) { + @Override + public void run() { + block.setBlockData(blockData); + if (material == Material.END_GATEWAY) {// force a location to prevent exit gateway generation + EndGateway gateway = (EndGateway) block.getState(); + // https://github.com/stargate-bukkit/Stargate-Bukkit/issues/36 + gateway.setAge(-9223372036854775808L); + if (block.getWorld().getEnvironment() == World.Environment.THE_END) { + gateway.setExitLocation(block.getLocation()); + gateway.setExactTeleport(true); + } + gateway.update(false, false); } - gateway.update(false, false); } - }).run(); + }.runNow(); } } diff --git a/src/main/java/org/sgrewritten/stargate/gate/structure/GateIris.java b/src/main/java/org/sgrewritten/stargate/gate/structure/GateIris.java index 3ba55c8b..099d4145 100644 --- a/src/main/java/org/sgrewritten/stargate/gate/structure/GateIris.java +++ b/src/main/java/org/sgrewritten/stargate/gate/structure/GateIris.java @@ -77,23 +77,26 @@ protected boolean isValidBlock(BlockVector blockVector, Material material) { public void generateStructure(VectorOperation converter, Location topLeft) { // (Clear all blocks that are in the portal iris) Material[] irisClosedList = irisClosed.toArray(new Material[0]); - for(BlockVector blockVector : this.blocks){ + for (BlockVector blockVector : this.blocks) { int target = RANDOM.nextInt(irisClosedList.length); Material chosenType = irisClosedList[target]; - Location location = VectorUtils.getLocation(topLeft,converter,blockVector); - new StargateRegionTask(location, () -> { - Block block = location.getBlock(); - if(chosenType == block.getType()){ - return; + Location location = VectorUtils.getLocation(topLeft, converter, blockVector); + new StargateRegionTask(location) { + @Override + public void run() { + Block block = location.getBlock(); + if (chosenType == block.getType()) { + return; + } + BlockData blockData = chosenType.createBlockData(); + // Over-engineering :) + if (blockData instanceof Orientable orientable) { + orientable.setAxis(converter.getIrisNormal()); + } + block.setBlockData(blockData); + BlockDropManager.disableBlockDrops(block); } - BlockData blockData = chosenType.createBlockData(); - // Over-engineering :) - if(blockData instanceof Orientable orientable){ - orientable.setAxis(converter.getIrisNormal()); - } - block.setBlockData(blockData); - BlockDropManager.disableBlockDrops(block); - }).run(); + }.runNow(); } } diff --git a/src/main/java/org/sgrewritten/stargate/listener/PlayerEventListener.java b/src/main/java/org/sgrewritten/stargate/listener/PlayerEventListener.java index 2e51027b..e3e59f2d 100644 --- a/src/main/java/org/sgrewritten/stargate/listener/PlayerEventListener.java +++ b/src/main/java/org/sgrewritten/stargate/listener/PlayerEventListener.java @@ -197,18 +197,23 @@ public void onPlayerJoin(PlayerJoinEvent event) { */ private void getBungeeServerName() { //Action for loading bungee server id - Runnable action = (() -> { - try { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); - dataOutputStream.writeUTF(PluginChannel.GET_SERVER.getChannel()); - Bukkit.getServer().sendPluginMessage(Stargate.getInstance(), PluginChannel.BUNGEE.getChannel(), - byteArrayOutputStream.toByteArray()); - } catch (IOException e) { - Stargate.log(e); + new StargateGlobalTask() { + @Override + public void run() { + if(Bukkit.getServer().getOnlinePlayers().isEmpty()){ + return; + } + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + dataOutputStream.writeUTF(PluginChannel.GET_SERVER.getChannel()); + Bukkit.getServer().sendPluginMessage(Stargate.getInstance(), PluginChannel.BUNGEE.getChannel(), + byteArrayOutputStream.toByteArray()); + } catch (IOException e) { + Stargate.log(e); + } + this.cancel(); } - }); - new StargateGlobalTask(action).run(true); + }.runTaskTimer(0,20); //Update the server name in the database once it's known @@ -219,13 +224,16 @@ private void getBungeeServerName() { * Updates this server's name in the database if necessary */ private void updateServerName() { - new StargateGlobalTask(() -> { - try { - storageAPI.startInterServerConnection(); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateGlobalTask(true) { + @Override + public void run() { + try { + storageAPI.startInterServerConnection(); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(true); + }.runNow(); } /** diff --git a/src/main/java/org/sgrewritten/stargate/network/StargateNetworkManager.java b/src/main/java/org/sgrewritten/stargate/network/StargateNetworkManager.java index 2226fcf1..23698e4d 100644 --- a/src/main/java/org/sgrewritten/stargate/network/StargateNetworkManager.java +++ b/src/main/java/org/sgrewritten/stargate/network/StargateNetworkManager.java @@ -161,13 +161,16 @@ public Network createNetwork(String name, NetworkType type, StorageType storageT if (network != null && network.getType() != type) { String newId = registry.getValidNewName(network); registry.renameNetwork(newId, network.getId(), network.getStorageType()); - new StargateQueuedAsyncTask(() -> { - try { - storageAPI.updateNetworkName(newId, network.getName(), network.getStorageType()); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateQueuedAsyncTask() { + @Override + public void run() { + try { + storageAPI.updateNetworkName(newId, network.getName(), network.getStorageType()); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(); + }.runNow(); } } throw new NameConflictException("network of id '" + name + "' already exists", true); @@ -213,7 +216,12 @@ public void loadPortals(StargateAPI stargateAPI) { * region scheduler. Temporary solution right now is to just have a large delay here. * TODO: come up with a general solution */ - new StargateGlobalTask(registry::updateAllPortals).runDelayed(20); + new StargateGlobalTask() { + @Override + public void run() { + registry.updateAllPortals(); + } + }.runDelayed(20); } @Override @@ -238,13 +246,16 @@ public void rename(Portal portal, String newName) throws NameConflictException { @Override public void savePortal(RealPortal portal, Network network) throws NameConflictException { network.addPortal(portal); - new StargateQueuedAsyncTask(() -> { - try { - storageAPI.savePortalToStorage(portal); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateQueuedAsyncTask() { + @Override + public void run() { + try { + storageAPI.savePortalToStorage(portal); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(); + }.runNow(); network.getPluginMessageSender().sendCreatePortal(portal); network.updatePortals(); } @@ -256,13 +267,16 @@ public void destroyPortal(RealPortal portal) { portal.destroy(); registry.unregisterPortal(portal); network.updatePortals(); - new StargateQueuedAsyncTask(() -> { - try { - storageAPI.removePortalFromStorage(portal); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateQueuedAsyncTask() { + @Override + public void run() { + try { + storageAPI.removePortalFromStorage(portal); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(); + }.runNow(); portal.getNetwork().getPluginMessageSender().sendDeletePortal(portal); } diff --git a/src/main/java/org/sgrewritten/stargate/network/StargateRegistry.java b/src/main/java/org/sgrewritten/stargate/network/StargateRegistry.java index 44251fca..47e440e9 100644 --- a/src/main/java/org/sgrewritten/stargate/network/StargateRegistry.java +++ b/src/main/java/org/sgrewritten/stargate/network/StargateRegistry.java @@ -311,13 +311,16 @@ public Map getPortalPositionsOwnedByPlugin(Plugin public PortalPosition savePortalPosition(RealPortal portal, Location location, PositionType type, Plugin plugin) { BlockVector relativeVector = portal.getGate().getRelativeVector(location).toBlockVector(); PortalPosition portalPosition = new PortalPosition(type, relativeVector, plugin.getName()); - new StargateQueuedAsyncTask(() -> { - try { - storageAPI.addPortalPosition(portal, portal.getStorageType(), portalPosition); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateQueuedAsyncTask(){ + @Override + public void run() { + try { + storageAPI.addPortalPosition(portal, portal.getStorageType(), portalPosition); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(); + }.runNow(); return portalPosition; } @@ -332,13 +335,16 @@ public void removePortalPosition(Location location) { portalPositionPluginNameMap.get(portalPosition.getPluginName()).remove(blockLocation); RealPortal portal = portalPosition.getPortal(); portal.getGate().removePortalPosition(portalPosition); - new StargateQueuedAsyncTask(() -> { - try { - storageAPI.removePortalPosition(portal, portal.getStorageType(), portalPosition); - } catch (StorageWriteException e) { - Stargate.log(e); + new StargateQueuedAsyncTask() { + @Override + public void run() { + try { + storageAPI.removePortalPosition(portal, portal.getStorageType(), portalPosition); + } catch (StorageWriteException e) { + Stargate.log(e); + } } - }).run(); + }.runNow(); } @Override diff --git a/src/main/java/org/sgrewritten/stargate/network/portal/AbstractPortal.java b/src/main/java/org/sgrewritten/stargate/network/portal/AbstractPortal.java index 1f11479d..14037174 100644 --- a/src/main/java/org/sgrewritten/stargate/network/portal/AbstractPortal.java +++ b/src/main/java/org/sgrewritten/stargate/network/portal/AbstractPortal.java @@ -202,7 +202,12 @@ public void open(Player actor) { final long openTimeForAction = System.currentTimeMillis(); this.openTime = openTimeForAction; - new StargateGlobalTask(() -> close(openTimeForAction)).runDelayed(OPEN_DELAY); + new StargateGlobalTask() { + @Override + public void run() { + close(openTimeForAction); + } + }.runDelayed(OPEN_DELAY); } @Override @@ -434,28 +439,37 @@ public void setSignColor(@Nullable DyeColor changedColor) { continue; } Location location = gate.getLocation(portalPosition.getRelativePositionLocation()); - new StargateRegionTask(location, () -> - updateColorDrawer(location, changedColor, portalPosition) - ).run(); + new StargateRegionTask(location) { + @Override + public void run() { + updateColorDrawer(location, changedColor, portalPosition); + } + }.runNow(); } // Has to be done one tick later to avoid a bukkit bug if (changedColor == null) { gate.getPortalPositions().stream().filter(portalPosition -> portalPosition.getPositionType() == PositionType.SIGN).forEach(portalPosition -> { final Block signBlock = gate.getLocation(portalPosition.getRelativePositionLocation()).getBlock(); - new StargateRegionTask(signBlock.getLocation(), () -> { - if (Tag.WALL_SIGNS.isTagged(signBlock.getType())) { - Sign sign = (Sign) signBlock.getState(); - sign.setColor(ColorRegistry.DEFAULT_DYE_COLOR); - sign.update(); + new StargateRegionTask(signBlock.getLocation()) { + @Override + public void run() { + if (Tag.WALL_SIGNS.isTagged(signBlock.getType())) { + Sign sign = (Sign) signBlock.getState(); + sign.setColor(ColorRegistry.DEFAULT_DYE_COLOR); + sign.update(); + } } - }).run(); + }.runNow(); }); } - new StargateGlobalTask(() -> { - SignLine[] lines = this.getDrawnControlLines(); - getGate().drawControlMechanisms(lines, !hasFlag(PortalFlag.ALWAYS_ON)); - }).runDelayed(2); + new StargateGlobalTask() { + @Override + public void run() { + SignLine[] lines = getDrawnControlLines(); + getGate().drawControlMechanisms(lines, !hasFlag(PortalFlag.ALWAYS_ON)); + } + }.runDelayed(2); } private void updateColorDrawer(Location location, DyeColor changedColor, PortalPosition portalPosition) { @@ -560,7 +574,12 @@ public void onSignClick(PlayerInteractEvent event) { new TextLine(this.colorDrawer.formatLine(Bukkit.getOfflinePlayer(ownerUUID).getName())), new TextLine(this.colorDrawer.formatLine(INTERNAL_FLAG.matcher(getAllFlagsString()).replaceAll(""))) }; - new StargateGlobalTask(() -> gate.drawControlMechanisms(lines, false)).run(); + new StargateGlobalTask() { + @Override + public void run() { + gate.drawControlMechanisms(lines, false); + } + }.runNow(); activate(event.getPlayer()); } @@ -571,7 +590,12 @@ public void activate(Player player) { this.activatedTime = activationTime; //Schedule for deactivation - new StargateGlobalTask(() -> deactivate(activationTime)).runDelayed(ACTIVE_DELAY); + new StargateGlobalTask() { + @Override + public void run() { + deactivate(activationTime); + } + }.runDelayed(ACTIVE_DELAY); } diff --git a/src/main/java/org/sgrewritten/stargate/network/portal/NetworkedPortal.java b/src/main/java/org/sgrewritten/stargate/network/portal/NetworkedPortal.java index e0da1672..3bc36231 100644 --- a/src/main/java/org/sgrewritten/stargate/network/portal/NetworkedPortal.java +++ b/src/main/java/org/sgrewritten/stargate/network/portal/NetworkedPortal.java @@ -392,17 +392,25 @@ private void setSelectedDestination(int selectedDestination) { /** * Avoid unnecessary database spam whenever the destination has changed. */ - new StargateGlobalTask(() -> { - Portal destination = getDestination(); - if (currentTime == previousDestinationSelectionTime && destination != null) { - /* - * setSelectedDestination(int) can be called multiple times within the same millisecond, this avoids - * duplicate unnecessary calls - */ - previousDestinationSelectionTime = -1; - new StargateQueuedAsyncTask(() -> super.setMetadata(new JsonPrimitive(destination.getId()), MetadataType.DESTINATION.name())).run(); + new StargateGlobalTask() { + @Override + public void run() { + Portal destination = getDestination(); + if (currentTime == previousDestinationSelectionTime && destination != null) { + /* + * setSelectedDestination(int) can be called multiple times within the same millisecond, this avoids + * duplicate unnecessary calls + */ + previousDestinationSelectionTime = -1; + new StargateQueuedAsyncTask() { + @Override + public void run() { + setMetadata(new JsonPrimitive(destination.getId()), MetadataType.DESTINATION.name()); + } + }.runNow(); + } } - }).runDelayed(20); + }.runDelayed(20); } this.selectedDestination = selectedDestination; } diff --git a/src/main/java/org/sgrewritten/stargate/network/portal/Teleporter.java b/src/main/java/org/sgrewritten/stargate/network/portal/Teleporter.java index be7a93e4..c31343eb 100644 --- a/src/main/java/org/sgrewritten/stargate/network/portal/Teleporter.java +++ b/src/main/java/org/sgrewritten/stargate/network/portal/Teleporter.java @@ -134,7 +134,12 @@ public void teleport(Entity target) { entitiesToTeleport.forEach(entity -> entity.sendMessage(worldBorderInterfereMessage)); return; } - new StargateEntityTask(baseEntity, () -> betterTeleport(baseEntity, exit, rotation)).run(); + new StargateEntityTask(baseEntity) { + @Override + public void run() { + betterTeleport(baseEntity, exit, rotation); + } + }.runNow(); } /** @@ -242,11 +247,13 @@ private void betterTeleport(Entity target, Location exit, double rotation) { */ private void teleportPassengers(Entity target, Location exit, List passengers) { for (Entity passenger : passengers) { - Runnable action = () -> { - betterTeleport(passenger, exit, rotation); - target.addPassenger(passenger); - }; - new StargateEntityTask(target, action).runDelayed(1); + new StargateEntityTask(target) { + @Override + public void run() { + betterTeleport(passenger, exit, rotation); + target.addPassenger(passenger); + } + }.runDelayed(1); } } @@ -268,12 +275,14 @@ private void teleportNearbyLeashedEntities(Entity holder, Location exit, double modifiedExit = exit; } if (entity.isLeashed() && entity.getLeashHolder() == holder) { - Runnable action = () -> { - entity.setLeashHolder(null); - betterTeleport(entity, modifiedExit, rotation); - entity.setLeashHolder(holder); - }; - new StargateEntityTask(entity, action).run(); + new StargateEntityTask(entity) { + @Override + public void run() { + entity.setLeashHolder(null); + betterTeleport(entity, modifiedExit, rotation); + entity.setLeashHolder(holder); + } + }.runNow(); } } } @@ -335,24 +344,26 @@ private void teleportPoweredMinecart(PoweredMinecart poweredMinecart, Vector tar teleport(poweredMinecart, exit); poweredMinecart.setFuel(fuel); - new StargateEntityTask(poweredMinecart, () -> { - //Re-apply fuel and velocity - Stargate.log(Level.FINEST, "Setting new velocity " + targetVelocity); - poweredMinecart.setVelocity(targetVelocity); - - //Use the paper-only methods for setting the powered minecart's actual push - if (NonLegacyMethod.PUSH_X.isImplemented() && NonLegacyMethod.PUSH_Z.isImplemented()) { - Vector direction = destinationFace.getDirection(); - double pushX = -direction.getBlockX(); - double pushZ = -direction.getBlockZ(); - Stargate.log(Level.FINEST, "Setting push: X = " + pushX + " Z = " + pushZ); - NonLegacyMethod.PUSH_X.invoke(poweredMinecart, pushX); - NonLegacyMethod.PUSH_Z.invoke(poweredMinecart, pushZ); - } else { - Stargate.log(Level.FINE, String.format("Unable to restore Furnace Minecart Momentum at %S --" + - " use Paper 1.18.2+ for this feature.", location)); + new StargateEntityTask(poweredMinecart) { + @Override + public void run() { + Stargate.log(Level.FINEST, "Setting new velocity " + targetVelocity); + poweredMinecart.setVelocity(targetVelocity); + + //Use the paper-only methods for setting the powered minecart's actual push + if (NonLegacyMethod.PUSH_X.isImplemented() && NonLegacyMethod.PUSH_Z.isImplemented()) { + Vector direction = destinationFace.getDirection(); + double pushX = -direction.getBlockX(); + double pushZ = -direction.getBlockZ(); + Stargate.log(Level.FINEST, "Setting push: X = " + pushX + " Z = " + pushZ); + NonLegacyMethod.PUSH_X.invoke(poweredMinecart, pushX); + NonLegacyMethod.PUSH_Z.invoke(poweredMinecart, pushZ); + } else { + Stargate.log(Level.FINE, String.format("Unable to restore Furnace Minecart Momentum at %S --" + + " use Paper 1.18.2+ for this feature.", location)); + } } - }).runDelayed(1); + }.runDelayed(1); } /** diff --git a/src/main/java/org/sgrewritten/stargate/network/proxy/BukkitPluginMessageInterface.java b/src/main/java/org/sgrewritten/stargate/network/proxy/BukkitPluginMessageInterface.java index 3064be81..de240115 100644 --- a/src/main/java/org/sgrewritten/stargate/network/proxy/BukkitPluginMessageInterface.java +++ b/src/main/java/org/sgrewritten/stargate/network/proxy/BukkitPluginMessageInterface.java @@ -18,14 +18,17 @@ public void scheduleSendMessage(String message, PluginChannel channel) { Stargate stargate = Stargate.getInstance(); - new StargateGlobalTask(() -> { - try { - this.sendMessage(message, channel, stargate); - } catch (IOException e) { - Stargate.log(Level.WARNING, "Error sending BungeeCord connect packet"); - Stargate.log(e); + new StargateGlobalTask(true) { + @Override + public void run() { + try { + sendMessage(message, channel, stargate); + } catch (IOException e) { + Stargate.log(Level.WARNING, "Error sending BungeeCord connect packet"); + Stargate.log(e); + } } - }).run(true); + }.runNow(); } diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateAsyncTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateAsyncTask.java index 94614474..2440edcd 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateAsyncTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateAsyncTask.java @@ -5,17 +5,17 @@ import java.util.concurrent.TimeUnit; -public class StargateAsyncTask extends StargateTask{ +public abstract class StargateAsyncTask extends StargateTask { private final Stargate plugin; - public StargateAsyncTask(Runnable runnable){ - super(runnable); + protected StargateAsyncTask() { this.plugin = Stargate.getInstance(); } + @Override - public void run() { - if(USING_FOLIA){ + public void runNow() { + if (USING_FOLIA) { super.registerFoliaTask(Bukkit.getServer().getAsyncScheduler().runNow(plugin, super::runTask)); } else { super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskAsynchronously(plugin); @@ -24,10 +24,20 @@ public void run() { @Override public void runDelayed(long delay) { - if(USING_FOLIA){ - super.registerFoliaTask(Bukkit.getServer().getAsyncScheduler().runDelayed(plugin, super::runTask,delay, TimeUnit.MILLISECONDS)); + if (USING_FOLIA) { + super.registerFoliaTask(Bukkit.getServer().getAsyncScheduler().runDelayed(plugin, super::runTask, delay, TimeUnit.MILLISECONDS)); } else { super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskLaterAsynchronously(plugin, delay); } } + + @Override + public void runTaskTimer(long period, long delay) { + super.setRepeatable(); + if (USING_FOLIA) { + super.registerFoliaTask(Bukkit.getServer().getAsyncScheduler().runAtFixedRate(plugin, super::runTask, delay, period, TimeUnit.MILLISECONDS)); + } else { + super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskTimer(plugin, delay, period); + } + } } diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateEntityTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateEntityTask.java index b3492831..c44deb30 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateEntityTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateEntityTask.java @@ -3,19 +3,18 @@ import org.bukkit.entity.Entity; import org.sgrewritten.stargate.Stargate; -public class StargateEntityTask extends StargateTask { +public abstract class StargateEntityTask extends StargateTask { private final Entity entity; private final Stargate plugin; - public StargateEntityTask(Entity entity, Runnable runnable) { - super(runnable); + protected StargateEntityTask(Entity entity) { this.entity = entity; this.plugin = Stargate.getInstance(); } @Override - public void run() { + public void runNow() { if (USING_FOLIA) { entity.getScheduler().run(plugin, super::runTask, null); } else { @@ -31,4 +30,14 @@ public void runDelayed(long delay) { super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskLater(plugin, delay); } } + + @Override + public void runTaskTimer(long period, long delay) { + super.setRepeatable(); + if (USING_FOLIA) { + entity.getScheduler().runAtFixedRate(plugin, super::runTask, null, delay, period); + } else { + super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskTimer(plugin,delay,period); + } + } } diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateGlobalTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateGlobalTask.java index f6fceabe..b56a8b3d 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateGlobalTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateGlobalTask.java @@ -2,44 +2,59 @@ import org.bukkit.Bukkit; import org.sgrewritten.stargate.Stargate; +import org.sgrewritten.stargate.util.BungeeHelper; -public class StargateGlobalTask extends StargateTask { +public abstract class StargateGlobalTask extends StargateTask { private final Stargate plugin; + private boolean bungee = false; - public StargateGlobalTask(Runnable runnable){ - super(runnable); + protected StargateGlobalTask() { this.plugin = Stargate.getInstance(); } - public void run(boolean bungee) { - // if no players are online, then no bungee messages can be sent (wait 10 second until a player joins) - if(bungee && Bukkit.getServer().getOnlinePlayers().isEmpty()){ - runDelayed(200, () -> run(true)); - return; + protected StargateGlobalTask(boolean bungee) { + this.plugin = Stargate.getInstance(); + this.bungee = bungee; + } + + @Override + public void runDelayed(long delay) { + if (USING_FOLIA) { + super.registerFoliaTask(Bukkit.getServer().getGlobalRegionScheduler().runDelayed(plugin, super::runTask, delay)); + } else { + super.registerBukkitTask(new StargateBukkitRunnable(super::runTask)).runTaskLater(plugin, delay); } + } - if(USING_FOLIA){ + @Override + public void runNow() { + if (bungee && !BungeeHelper.canSendBungeeMessages()) { + runTaskTimer(20, 20, () -> { + if (BungeeHelper.canSendBungeeMessages()) { + this.runNow(); + this.cancel(); + } + }); + return; + } + if (USING_FOLIA) { super.registerFoliaTask(Bukkit.getServer().getGlobalRegionScheduler().run(plugin, this::runTask)); } else { super.registerBukkitTask(new StargateBukkitRunnable(this::runTask)).runTask(plugin); } } - private void runDelayed(long delay, Runnable runnable) { - if(USING_FOLIA){ - super.registerFoliaTask(Bukkit.getServer().getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay)); + public void runTaskTimer(long period, long delay, Runnable runnable) { + super.setRepeatable(); + if (USING_FOLIA) { + super.registerFoliaTask(Bukkit.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, ignored -> runnable.run(), delay, period)); } else { - super.registerBukkitTask(new StargateBukkitRunnable(runnable)).runTaskLater(plugin, delay); + super.registerBukkitTask(new StargateBukkitRunnable(this::runTask)).runTaskTimer(plugin, delay, period); } } @Override - public void runDelayed(long delay) { - runDelayed(delay, super::runTask); - } - - @Override - public void run() { - run(false); + public void runTaskTimer(long period, long delay) { + runTaskTimer(period, delay, super::runTask); } } diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateQueuedAsyncTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateQueuedAsyncTask.java index b7d139e0..7de5a1ed 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateQueuedAsyncTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateQueuedAsyncTask.java @@ -5,21 +5,26 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -public class StargateQueuedAsyncTask extends StargateTask { +public abstract class StargateQueuedAsyncTask extends StargateTask { private static final BlockingQueue asyncQueue = new LinkedBlockingQueue<>(); private static boolean asyncQueueThreadIsEnabled = false; - public StargateQueuedAsyncTask(Runnable runnable) { - super(runnable); + protected StargateQueuedAsyncTask() { } @Override - void runDelayed(long delay) { - new StargateAsyncTask(this).runDelayed(delay); + public void runDelayed(long delay) { + StargateQueuedAsyncTask task = this; + new StargateAsyncTask() { + @Override + public void run() { + task.run(); + } + }.runDelayed(delay); } @Override - public void run() { + public void runNow() { try { super.registerTask(); asyncQueue.put(super::runTask); @@ -29,6 +34,18 @@ public void run() { } } + @Override + public void runTaskTimer(long period, long delay) { + super.setRepeatable(); + StargateQueuedAsyncTask task = this; + new StargateAsyncTask() { + @Override + public void run() { + task.run(); + } + }.runTaskTimer(period, delay); + } + public static void disableAsyncQueue() { try { asyncQueue.put(new DisableQueueTask()); @@ -43,7 +60,12 @@ public static void enableAsyncQueue() { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } - new StargateAsyncTask(StargateQueuedAsyncTask::cycleThroughAsyncQueue).run(); + new StargateAsyncTask() { + @Override + public void run() { + StargateQueuedAsyncTask.cycleThroughAsyncQueue(); + } + }.runNow(); } private static void cycleThroughAsyncQueue() { diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateRegionTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateRegionTask.java index 6f385876..d180903c 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateRegionTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateRegionTask.java @@ -7,7 +7,7 @@ import org.sgrewritten.stargate.Stargate; import org.sgrewritten.stargate.thread.SynchronousPopulator; -public class StargateRegionTask extends StargateTask { +public abstract class StargateRegionTask extends StargateTask { private final Location location; private final Stargate plugin; @@ -15,19 +15,18 @@ public class StargateRegionTask extends StargateTask { private final boolean bungee; - public StargateRegionTask(Location location, Runnable runnable, boolean bungee) { - super(runnable); + protected StargateRegionTask(Location location, boolean bungee) { this.location = location; this.plugin = Stargate.getInstance(); this.bungee = bungee; } - public StargateRegionTask(Location location, Runnable runnable) { - this(location, runnable, false); + protected StargateRegionTask(Location location) { + this(location, false); } @Override - public void run() { + public void runNow() { if (USING_FOLIA) { ScheduledTask theTask = Bukkit.getServer().getRegionScheduler().run(plugin, location, super::runTask); super.registerFoliaTask(theTask); @@ -46,6 +45,17 @@ public void runDelayed(long delay) { } } + @Override + public void runTaskTimer(long period, long delay) { + super.setRepeatable(); + if (USING_FOLIA) { + ScheduledTask theTask = Bukkit.getServer().getRegionScheduler().runAtFixedRate(plugin, location, super::runTask, delay, period); + super.registerFoliaTask(theTask); + } else { + super.registerBukkitTask(new StargateBukkitRunnable(this::runPopulatorTask)).runTaskTimer(plugin, delay, period); + } + } + private void runPopulatorTask() { populator.addAction(super::runTask, bungee); super.registerTask(); diff --git a/src/main/java/org/sgrewritten/stargate/thread/task/StargateTask.java b/src/main/java/org/sgrewritten/stargate/thread/task/StargateTask.java index 6eb2d83c..f3752e2d 100644 --- a/src/main/java/org/sgrewritten/stargate/thread/task/StargateTask.java +++ b/src/main/java/org/sgrewritten/stargate/thread/task/StargateTask.java @@ -9,22 +9,23 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -public abstract class StargateTask implements Runnable { +public abstract class StargateTask implements Runnable{ protected static final boolean USING_FOLIA = NonLegacyClass.REGIONIZED_SERVER.isImplemented(); private static final int MAXIMUM_SHUTDOWN_CYCLES = 10; - private final Runnable runnable; - private boolean taskIsRegistered; - private volatile boolean cancelled; - private volatile boolean running; + private boolean taskIsRegistered = false; + private volatile boolean cancelled = false; + private volatile boolean running = false; private ScheduledTask scheduledTask; private BukkitRunnable scheduledBukkitTask; private static final Queue tasks = new ConcurrentLinkedQueue<>(); + private boolean repeatable = false; - abstract void runDelayed(long delay); + public abstract void runDelayed(long delay); + + public abstract void runNow(); + + public abstract void runTaskTimer(long period, long delay); - protected StargateTask(Runnable runnable) { - this.runnable = runnable; - } public void cancel() { this.cancelled = true; @@ -36,7 +37,7 @@ protected void registerTask() { return; } taskIsRegistered = true; - tasks.add(runnable); + tasks.add(this); } protected void registerFoliaTask(ScheduledTask scheduledTask) { @@ -64,7 +65,7 @@ private void cancelIfTaskHasBeenScheduled(boolean bukkit) { } else if (scheduledTask != null) { scheduledTask.cancel(); } - tasks.remove(runnable); + tasks.remove(this); } /** @@ -90,12 +91,12 @@ public static void forceRunAllTasks() { * Run the task if not already been running (should be threadsafe) */ protected void runTask() { - if (running || cancelled) { + if ((running && ! repeatable)|| cancelled) { return; } running = true; - tasks.remove(runnable); - runnable.run(); + tasks.remove(this); + this.run(); } /** @@ -109,4 +110,8 @@ protected void runTask(ScheduledTask scheduledTask) { } this.runTask(); } + + protected void setRepeatable(){ + this.repeatable = true; + } } diff --git a/src/main/java/org/sgrewritten/stargate/util/BungeeHelper.java b/src/main/java/org/sgrewritten/stargate/util/BungeeHelper.java index bb30cf63..1c7b8d24 100644 --- a/src/main/java/org/sgrewritten/stargate/util/BungeeHelper.java +++ b/src/main/java/org/sgrewritten/stargate/util/BungeeHelper.java @@ -2,6 +2,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import org.bukkit.Bukkit; import org.jetbrains.annotations.Nullable; import org.sgrewritten.stargate.Stargate; import org.sgrewritten.stargate.api.network.Network; @@ -140,4 +141,10 @@ public static String generateTeleportJsonMessage(String player, Portal portal) { public static String generateLegacyTeleportMessage(String player, Portal portal) { return player + "#@#" + portal.getName(); } + + + + public static boolean canSendBungeeMessages() { + return (Bukkit.getServer().getOnlinePlayers().isEmpty() || !Stargate.knowsServerName()); + } } diff --git a/src/test/java/org/sgrewritten/stargate/thread/task/StargateGlobalTaskTest.java b/src/test/java/org/sgrewritten/stargate/thread/task/StargateGlobalTaskTest.java index d75fbf05..8f09e7f0 100644 --- a/src/test/java/org/sgrewritten/stargate/thread/task/StargateGlobalTaskTest.java +++ b/src/test/java/org/sgrewritten/stargate/thread/task/StargateGlobalTaskTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.sgrewritten.stargate.Stargate; class StargateGlobalTaskTest { @@ -24,19 +23,17 @@ void tearDown() { @Test void run_noDuplicates() { - TestRunnable runnable = new TestRunnable(); - StargateGlobalTask task = new StargateGlobalTask(runnable); - task.run(); - task.run(); + TestRunnable runnable = new TestRunnable(true); + runnable.runNow(); + runnable.runNow(); serverMock.getScheduler().performOneTick(); Assertions.assertTrue(runnable.hasRunBefore); } @Test void run_bungee_noDuplicates() { - TestRunnable runnable = new TestRunnable(); - StargateGlobalTask task = new StargateGlobalTask(runnable); - task.run(true); + TestRunnable runnable = new TestRunnable(true, true); + runnable.run(); serverMock.getScheduler().performTicks(1000); Assertions.assertFalse(runnable.hasRunBefore); // Necessary to add a player here to avoid recursion loop @@ -47,21 +44,59 @@ void run_bungee_noDuplicates() { @Test void runDelayed_noDuplicates() { - TestRunnable runnable = new TestRunnable(); - StargateGlobalTask task = new StargateGlobalTask(runnable); - task.runDelayed(2); - task.runDelayed(2); + TestRunnable runnable = new TestRunnable(true); + runnable.runDelayed(2); + runnable.runDelayed(2); serverMock.getScheduler().performTicks(2); Assertions.assertTrue(runnable.hasRunBefore); } - private class TestRunnable implements Runnable { + @Test + void runTaskTimer(){ + TestRunnable runnable = new TestRunnable(false); + runnable.runTaskTimer(1,0); + serverMock.getScheduler().performTicks(20); + Assertions.assertEquals(20, runnable.runCount); + } + + @Test + void runTaskTimer_cancelled(){ + TestRunnable runnable = new TestRunnable(false) { + @Override + public void run() { + super.run(); + if(runCount > 9){ + this.cancel(); + } + Assertions.assertTrue(runCount < 11); + } + }; + runnable.runTaskTimer(1,0); + serverMock.getScheduler().performTicks(20); + Assertions.assertEquals(10, runnable.runCount); + } + + private static class TestRunnable extends StargateGlobalTask { + private final boolean onlyAllowOneRun; boolean hasRunBefore = false; + int runCount = 0; + + TestRunnable(boolean onlyAllowOneRun) { + this(false, onlyAllowOneRun); + } + + TestRunnable(boolean bungee,boolean onlyAllowOneRun) { + super(bungee); + this.onlyAllowOneRun = onlyAllowOneRun; + } @Override public void run() { - Assertions.assertFalse(hasRunBefore); + if(onlyAllowOneRun){ + Assertions.assertFalse(hasRunBefore); + } hasRunBefore = true; + runCount++; } } } \ No newline at end of file