From 15c48d457a60e2f1f1a117945b98c6cc8b7a2200 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 27 Mar 2023 23:29:42 -0400 Subject: [PATCH 01/21] Add Folia providers --- Essentials/build.gradle | 2 + .../net/ess3/provider/SchedulingProvider.java | 34 ++++++ .../providers/BukkitSchedulingProvider.java | 91 +++++++++++++++ providers/FoliaProvider/build.gradle | 19 +++ .../providers/FoliaSchedulingProvider.java | 110 ++++++++++++++++++ settings.gradle.kts | 2 + 6 files changed, 258 insertions(+) create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java create mode 100644 providers/FoliaProvider/build.gradle create mode 100644 providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 2a72af81529..4d5495b163b 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -18,6 +18,7 @@ dependencies { // Providers api project(':providers:BaseProviders') api project(':providers:PaperProvider') + api project(':providers:FoliaProvider') api(project(':providers:NMSReflectionProvider')) { exclude group: "org.bukkit", module: "bukkit" } @@ -45,6 +46,7 @@ shadowJar { include (dependency('org.checkerframework:checker-qual')) include (project(':providers:BaseProviders')) include (project(':providers:PaperProvider')) + include (project(':providers:FoliaProvider')) include (project(':providers:NMSReflectionProvider')) include (project(':providers:1_8Provider')) include (project(':providers:1_12Provider')) diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java new file mode 100644 index 00000000000..83a5a62cc37 --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java @@ -0,0 +1,34 @@ +package net.ess3.provider; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; + +public interface SchedulingProvider extends Provider { + void registerInitTask(Runnable runnable); + + void runEntityTask(Entity entity, Runnable runnable); + + EssentialsTask runEntityTask(Entity entity, Runnable runnable, long delay); + + EssentialsTask runEntityTaskRepeating(Entity entity, Runnable runnable, long delay, long period); + + void runLocationalTask(Location location, Runnable runnable); + + void runLocationalTask(Location location, Runnable runnable, long delay); + + EssentialsTask runLocationalTaskRepeating(Location location, Runnable runnable, long delay, long period); + + void runGlobalLocationalTask(Runnable runnable, long delay); + + EssentialsTask runGlobalLocationalTaskRepeating(Runnable runnable, long delay, long period); + + void runAsyncTask(Runnable runnable); + + void runAsyncTaskLater(Runnable runnable, long delay); + + EssentialsTask runAsyncTaskRepeating(Runnable runnable, long delay, long period); + + interface EssentialsTask { + void cancel(); + } +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java new file mode 100644 index 00000000000..887999fea1f --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java @@ -0,0 +1,91 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.SchedulingProvider; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + +public class BukkitSchedulingProvider implements SchedulingProvider { + private final Plugin plugin; + + public BukkitSchedulingProvider(final Plugin plugin) { + this.plugin = plugin; + } + + @Override + public void registerInitTask(Runnable runnable) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, runnable); + } + + @Override + public void runEntityTask(Entity entity, Runnable runnable) { + runEntityTask(entity, runnable, 1); + } + + @Override + public EssentialsTask runEntityTask(Entity entity, Runnable runnable, long delay) { + return scheduleSyncTask(runnable, delay); + } + + @Override + public EssentialsTask runEntityTaskRepeating(Entity entity, Runnable runnable, long delay, long period) { + return scheduleSyncTaskRepeating(runnable, delay, period); + } + + @Override + public void runLocationalTask(Location location, Runnable runnable) { + runGlobalLocationalTask(runnable, 1); + } + + @Override + public void runLocationalTask(Location location, Runnable runnable, long delay) { + runGlobalLocationalTask(runnable, delay); + } + + @Override + public EssentialsTask runLocationalTaskRepeating(Location location, Runnable runnable, long delay, long period) { + return scheduleSyncTaskRepeating(runnable, delay, period); + } + + @Override + public void runGlobalLocationalTask(Runnable runnable, long delay) { + scheduleSyncTask(runnable, delay); + } + + @Override + public EssentialsTask runGlobalLocationalTaskRepeating(Runnable runnable, long delay, long period) { + return scheduleSyncTaskRepeating(runnable, delay, period); + } + + private EssentialsTask scheduleSyncTask(Runnable runnable, long delay) { + final int task = plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, runnable, delay); + return () -> plugin.getServer().getScheduler().cancelTask(task); + } + + private EssentialsTask scheduleSyncTaskRepeating(Runnable runnable, long delay, long period) { + final BukkitTask task = plugin.getServer().getScheduler().runTaskTimer(plugin, runnable, delay, period); + return task::cancel; + } + + @Override + public void runAsyncTask(Runnable runnable) { + runAsyncTaskLater(runnable, 0); + } + + @Override + public void runAsyncTaskLater(Runnable runnable, long delay) { + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay); + } + + @Override + public EssentialsTask runAsyncTaskRepeating(Runnable runnable, long delay, long period) { + final BukkitTask task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period); + return task::cancel; + } + + @Override + public String getDescription() { + return "Bukkit Scheduling Provider"; + } +} diff --git a/providers/FoliaProvider/build.gradle b/providers/FoliaProvider/build.gradle new file mode 100644 index 00000000000..42ae0f072b3 --- /dev/null +++ b/providers/FoliaProvider/build.gradle @@ -0,0 +1,19 @@ +plugins { + id("essentials.base-conventions") +} + +java { + disableAutoTargetJvm() +} + +dependencies { + implementation(project(':providers:BaseProviders')) { + exclude(module: 'spigot-api') + } + compileOnly 'dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT' +} + +essentials { + injectBukkitApi.set(false) + injectBstats.set(false) +} diff --git a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java new file mode 100644 index 00000000000..bb4697727af --- /dev/null +++ b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java @@ -0,0 +1,110 @@ +package net.ess3.provider.providers; + +import io.papermc.paper.threadedregions.RegionizedServerInitEvent; +import io.papermc.paper.threadedregions.scheduler.ScheduledTask; +import net.ess3.provider.SchedulingProvider; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class FoliaSchedulingProvider implements SchedulingProvider { + private final Plugin plugin; + private List initTasks = new ArrayList<>(); + + public FoliaSchedulingProvider(Plugin plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onServerInit(RegionizedServerInitEvent event) { + for (final Runnable tasks : initTasks) { + tasks.run(); + } + initTasks = null; + } + + @Override + public void registerInitTask(Runnable runnable) { + if (initTasks == null) { + throw new IllegalStateException(); + } + initTasks.add(runnable); + } + + @Override + public void runEntityTask(Entity entity, Runnable runnable) { + runEntityTask(entity, runnable, 1); + } + + @Override + public EssentialsTask runEntityTask(Entity entity, Runnable runnable, long delay) { + final ScheduledTask task = entity.getScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), null, delay); + if (task == null) { + throw new IllegalArgumentException("entity is removed!"); + } + return task::cancel; + } + + @Override + public EssentialsTask runEntityTaskRepeating(Entity entity, Runnable runnable, long delay, long period) { + final ScheduledTask task = entity.getScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), null, delay, period); + if (task == null) { + throw new IllegalArgumentException("entity is removed!"); + } + return task::cancel; + } + + @Override + public void runLocationalTask(Location location, Runnable runnable) { + plugin.getServer().getRegionScheduler().execute(plugin, location, runnable); + } + + @Override + public void runLocationalTask(Location location, Runnable runnable, long delay) { + plugin.getServer().getRegionScheduler().runDelayed(plugin, location, scheduledTask -> runnable.run(), delay); + } + + @Override + public EssentialsTask runLocationalTaskRepeating(Location location, Runnable runnable, long delay, long period) { + final ScheduledTask task = plugin.getServer().getRegionScheduler().runAtFixedRate(plugin, location, scheduledTask -> runnable.run(), delay, period);; + return task::cancel; + } + + @Override + public void runGlobalLocationalTask(Runnable runnable, long delay) { + plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay); + } + + @Override + public EssentialsTask runGlobalLocationalTaskRepeating(Runnable runnable, long delay, long period) { + final ScheduledTask task = plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, period); + return task::cancel; + } + + @Override + public void runAsyncTask(Runnable runnable) { + plugin.getServer().getAsyncScheduler().runNow(plugin, scheduledTask -> runnable.run()); + } + + @Override + public void runAsyncTaskLater(Runnable runnable, long delay) { + plugin.getServer().getAsyncScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS); + } + + @Override + public EssentialsTask runAsyncTaskRepeating(Runnable runnable, long delay, long period) { + final ScheduledTask task = plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, delay * 50, TimeUnit.MICROSECONDS); + return task::cancel; + } + + @Override + public String getDescription() { + return "Folia Scheduling Provider"; + } + +} diff --git a/settings.gradle.kts b/settings.gradle.kts index f133a0cd150..d6ed8b4292b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,6 +21,7 @@ dependencyResolutionManagement { content { includeGroup("net.kyori") } content { includeGroup("org.apache.logging.log4j") } } + mavenLocal() } repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) } @@ -51,5 +52,6 @@ sequenceOf( include(":providers:BaseProviders") include(":providers:NMSReflectionProvider") include(":providers:PaperProvider") +include(":providers:FoliaProvider") include(":providers:1_8Provider") include(":providers:1_12Provider") From 0e4bab24cbc62d77ff35043b553bbc01e3f680bc Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 27 Mar 2023 23:31:39 -0400 Subject: [PATCH 02/21] Get like 70% of the plugin to work --- .../earth2me/essentials/AsyncTeleport.java | 6 +- .../essentials/AsyncTimedTeleport.java | 13 +- .../java/com/earth2me/essentials/Backup.java | 13 +- .../com/earth2me/essentials/Essentials.java | 75 +++- .../essentials/EssentialsBlockListener.java | 2 +- .../essentials/EssentialsEntityListener.java | 2 +- .../essentials/EssentialsPlayerListener.java | 23 +- .../earth2me/essentials/EssentialsTimer.java | 32 +- .../com/earth2me/essentials/IEssentials.java | 35 +- .../java/com/earth2me/essentials/IUser.java | 8 - .../java/com/earth2me/essentials/Jails.java | 22 - .../earth2me/essentials/RandomTeleport.java | 2 +- .../com/earth2me/essentials/Settings.java | 4 +- .../com/earth2me/essentials/Teleport.java | 403 ------------------ .../earth2me/essentials/TimedTeleport.java | 140 ------ .../java/com/earth2me/essentials/User.java | 15 +- .../com/earth2me/essentials/api/IJails.java | 11 - .../commands/Commandbalancetop.java | 2 +- .../essentials/commands/Commandbeezooka.java | 2 +- .../essentials/commands/Commandgc.java | 2 +- .../commands/Commandkittycannon.java | 2 +- .../essentials/commands/Commandseen.java | 2 +- .../essentials/commands/Commandskull.java | 2 +- .../essentials/commands/Commandsudo.java | 2 +- .../essentials/economy/EconomyLayers.java | 2 +- .../textreader/KeywordReplacer.java | 2 +- .../essentials/utils/VersionUtil.java | 10 + Essentials/src/main/resources/plugin.yml | 1 + .../src/main/resources/plugin.yml | 2 +- EssentialsChat/src/main/resources/plugin.yml | 1 + .../discord/EssentialsDiscord.java | 2 +- .../discord/JDADiscordService.java | 2 +- .../InteractionControllerImpl.java | 2 +- .../discord/util/DiscordCommandSender.java | 7 +- .../essentialsx/discord/util/DiscordUtil.java | 6 +- .../src/main/resources/plugin.yml | 1 + .../discordlink/AccountLinkManager.java | 2 +- .../listeners/LinkBukkitListener.java | 2 +- .../src/main/resources/plugin.yml | 1 + EssentialsGeoIP/src/main/resources/plugin.yml | 1 + .../src/main/resources/plugin.yml | 1 + .../spawn/EssentialsSpawnPlayerListener.java | 6 +- EssentialsSpawn/src/main/resources/plugin.yml | 1 + 43 files changed, 155 insertions(+), 717 deletions(-) delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/Teleport.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/TimedTeleport.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java index 19ab4581815..26567ffaa5a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java @@ -192,8 +192,7 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { if (ess.getSettings().isTeleportSafetyEnabled()) { if (ess.getSettings().isForceDisableTeleportSafety()) { - //The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async. - teleportee.getBase().teleport(loc, cause); + PaperLib.teleportAsync(teleportee.getBase(), loc, cause); } else { try { //There's a chance the safer location is outside the loaded chunk so still teleport async here. @@ -209,8 +208,7 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele } } else { if (ess.getSettings().isForceDisableTeleportSafety()) { - //The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async. - teleportee.getBase().teleport(loc, cause); + PaperLib.teleportAsync(teleportee.getBase(), loc, cause); } else { if (ess.getSettings().isTeleportToCenterLocation()) { loc = LocationUtil.getRoundedDestination(loc); diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTimedTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTimedTeleport.java index e38ee162528..df3dc6932dc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTimedTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTimedTeleport.java @@ -2,6 +2,7 @@ import net.ess3.api.IEssentials; import net.ess3.api.IUser; +import net.ess3.provider.SchedulingProvider; import org.bukkit.Location; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -30,7 +31,7 @@ public class AsyncTimedTeleport implements Runnable { private final boolean timer_canMove; private final Trade timer_chargeFor; private final TeleportCause timer_cause; - private int timer_task; + private SchedulingProvider.EssentialsTask timer_task; private double timer_health; AsyncTimedTeleport(final IUser user, final IEssentials ess, final AsyncTeleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) { @@ -54,7 +55,7 @@ public class AsyncTimedTeleport implements Runnable { this.timer_respawn = respawn; this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move"); - timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId(); + timer_task = ess.runTaskTimerAsynchronously(this, 20, 20); if (future != null) { this.parentFuture = future; @@ -141,16 +142,16 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new DelayedTeleportTask()); + ess.scheduleEntityDelayedTask(teleportOwner.getBase(), new DelayedTeleportTask()); } //If we need to cancelTimer a pending teleportPlayer call this method void cancelTimer(final boolean notifyUser) { - if (timer_task == -1) { + if (timer_task == null) { return; } try { - ess.getServer().getScheduler().cancelTask(timer_task); + timer_task.cancel(); if (notifyUser) { teleportOwner.sendMessage(tl("pendingTeleportCancelled")); if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) { @@ -158,7 +159,7 @@ void cancelTimer(final boolean notifyUser) { } } } finally { - timer_task = -1; + timer_task = null; } } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/Backup.java b/Essentials/src/main/java/com/earth2me/essentials/Backup.java index 837170df7ca..8d2970cd3b5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Backup.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Backup.java @@ -1,6 +1,7 @@ package com.earth2me.essentials; import net.ess3.api.IEssentials; +import net.ess3.provider.SchedulingProvider; import org.bukkit.Server; import org.bukkit.command.CommandSender; @@ -18,7 +19,7 @@ public class Backup implements Runnable { private transient final IEssentials ess; private final AtomicBoolean pendingShutdown = new AtomicBoolean(false); private transient boolean running = false; - private transient int taskId = -1; + private transient SchedulingProvider.EssentialsTask task = null; private transient boolean active = false; private transient CompletableFuture taskLock = null; @@ -36,10 +37,10 @@ public void onPlayerJoin() { public synchronized void stopTask() { running = false; - if (taskId != -1) { - server.getScheduler().cancelTask(taskId); + if (task != null) { + task.cancel(); } - taskId = -1; + task = null; } private synchronized void startTask() { @@ -48,7 +49,7 @@ private synchronized void startTask() { if (interval < 1200) { return; } - taskId = ess.scheduleSyncRepeatingTask(this, interval, interval); + task = ess.scheduleGlobalRepeatingTask(this, interval, interval); running = true; } } @@ -123,7 +124,7 @@ public void run() { } if (!pendingShutdown.get()) { - ess.scheduleSyncDelayedTask(new BackupEnableSaveTask()); + ess.scheduleGlobalDelayedTask(new BackupEnableSaveTask()); } } }); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 287446cd324..77b24ca1fb8 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -65,6 +65,7 @@ import net.ess3.provider.PersistentDataProvider; import net.ess3.provider.PotionMetaProvider; import net.ess3.provider.ProviderListener; +import net.ess3.provider.SchedulingProvider; import net.ess3.provider.SerializationProvider; import net.ess3.provider.ServerStateProvider; import net.ess3.provider.SignDataProvider; @@ -77,9 +78,11 @@ import net.ess3.provider.providers.BasePotionDataProvider; import net.ess3.provider.providers.BlockMetaSpawnerItemProvider; import net.ess3.provider.providers.BukkitMaterialTagProvider; +import net.ess3.provider.providers.BukkitSchedulingProvider; import net.ess3.provider.providers.BukkitSpawnerBlockProvider; import net.ess3.provider.providers.FixedHeightWorldInfoProvider; import net.ess3.provider.providers.FlatSpawnEggProvider; +import net.ess3.provider.providers.FoliaSchedulingProvider; import net.ess3.provider.providers.LegacyItemUnbreakableProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; @@ -95,6 +98,7 @@ import net.ess3.provider.providers.PaperServerStateProvider; import net.essentialsx.api.v2.services.BalanceTop; import net.essentialsx.api.v2.services.mail.MailService; +import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.block.Block; @@ -104,6 +108,7 @@ import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; @@ -120,8 +125,6 @@ import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; import java.io.File; import java.io.IOException; @@ -182,6 +185,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient ItemUnbreakableProvider unbreakableProvider; private transient WorldInfoProvider worldInfoProvider; private transient SignDataProvider signDataProvider; + private transient SchedulingProvider schedulingProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; private transient UpdateChecker updateChecker; @@ -358,6 +362,12 @@ public void onEnable() { confList.add(jails); execTimer.mark("Init(Jails)"); + if (VersionUtil.FOLIA) { + schedulingProvider = new FoliaSchedulingProvider(this); + } else { + schedulingProvider = new BukkitSchedulingProvider(this); + } + EconomyLayers.onEnable(this); //Spawner item provider only uses one but it's here for legacy... @@ -464,7 +474,7 @@ public void onEnable() { alternativeCommandsHandler = new AlternativeCommandsHandler(this); timer = new EssentialsTimer(this); - scheduleSyncRepeatingTask(timer, 1000, 50); + scheduleGlobalRepeatingTask(timer, 1000, 50); Economy.setEss(this); execTimer.mark("RegHandler"); @@ -881,11 +891,6 @@ public void showError(final CommandSource sender, final Throwable exception, fin } } - @Override - public BukkitScheduler getScheduler() { - return this.getServer().getScheduler(); - } - @Override public IJails getJails() { return jails; @@ -1164,33 +1169,63 @@ private int broadcastMessage(final IUser sender, final String permission, final } @Override - public BukkitTask runTaskAsynchronously(final Runnable run) { - return this.getScheduler().runTaskAsynchronously(this, run); + public void scheduleInitTask(Runnable runnable) { + schedulingProvider.registerInitTask(runnable); + } + + @Override + public void runTaskAsynchronously(final Runnable run) { + schedulingProvider.runAsyncTask(run); + } + + @Override + public void runTaskLaterAsynchronously(final Runnable run, final long delay) { + schedulingProvider.runAsyncTaskLater(run, delay); + } + + @Override + public SchedulingProvider.EssentialsTask runTaskTimerAsynchronously(final Runnable run, final long delay, final long period) { + return schedulingProvider.runAsyncTaskRepeating(run, delay, period); + } + + @Override + public void scheduleEntityDelayedTask(Entity entity, Runnable run) { + schedulingProvider.runEntityTask(entity, run); + } + + @Override + public SchedulingProvider.EssentialsTask scheduleEntityDelayedTask(Entity entity, Runnable run, long delay) { + return schedulingProvider.runEntityTask(entity, run, delay); + } + + @Override + public SchedulingProvider.EssentialsTask scheduleEntityRepeatingTask(Entity entity, Runnable run, long delay, long period) { + return schedulingProvider.runEntityTaskRepeating(entity, run, delay, period); } @Override - public BukkitTask runTaskLaterAsynchronously(final Runnable run, final long delay) { - return this.getScheduler().runTaskLaterAsynchronously(this, run, delay); + public void scheduleLocationDelayedTask(Location location, Runnable run) { + schedulingProvider.runLocationalTask(location, run); } @Override - public BukkitTask runTaskTimerAsynchronously(final Runnable run, final long delay, final long period) { - return this.getScheduler().runTaskTimerAsynchronously(this, run, delay, period); + public void scheduleLocationDelayedTask(Location location, Runnable run, long delay) { + schedulingProvider.runLocationalTask(location, run, delay); } @Override - public int scheduleSyncDelayedTask(final Runnable run) { - return this.getScheduler().scheduleSyncDelayedTask(this, run); + public SchedulingProvider.EssentialsTask scheduleLocationRepeatingTask(Location location, Runnable run, long delay, long period) { + return schedulingProvider.runLocationalTaskRepeating(location, run, delay, period); } @Override - public int scheduleSyncDelayedTask(final Runnable run, final long delay) { - return this.getScheduler().scheduleSyncDelayedTask(this, run, delay); + public void scheduleGlobalDelayedTask(Runnable run, long delay) { + schedulingProvider.runGlobalLocationalTask(run, delay); } @Override - public int scheduleSyncRepeatingTask(final Runnable run, final long delay, final long period) { - return this.getScheduler().scheduleSyncRepeatingTask(this, run, delay, period); + public SchedulingProvider.EssentialsTask scheduleGlobalRepeatingTask(Runnable run, long delay, long period) { + return schedulingProvider.runGlobalLocationalTaskRepeating(run, delay, period); } @Override diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsBlockListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsBlockListener.java index c0a861ce737..aa44551174b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsBlockListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsBlockListener.java @@ -42,7 +42,7 @@ public void onBlockPlace(final BlockPlaceEvent event) { final User user = ess.getUser(event.getPlayer()); if (user.hasUnlimited(is) && user.getBase().getGameMode() == GameMode.SURVIVAL) { - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(user.getBase(), () -> { if (is != null && is.getType() != null && !MaterialUtil.isAir(is.getType())) { final ItemStack cloneIs = is.clone(); cloneIs.setAmount(1); diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsEntityListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsEntityListener.java index a1ab286b984..26ca4433516 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsEntityListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsEntityListener.java @@ -112,7 +112,7 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new PowerToolInteractTask()); + ess.scheduleEntityDelayedTask(attacker.getBase(), new PowerToolInteractTask()); event.setCancelled(true); return; diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index c2dff750f45..d18f0d6c91d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -15,6 +15,7 @@ import net.ess3.api.IEssentials; import net.ess3.api.events.AfkStatusChangeEvent; import net.ess3.provider.CommandSendListenerProvider; +import net.ess3.provider.SchedulingProvider; import net.ess3.provider.providers.BukkitCommandSendListenerProvider; import net.ess3.provider.providers.PaperCommandSendListenerProvider; import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent; @@ -79,7 +80,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor { private final transient IEssentials ess; - private final ConcurrentHashMap pendingMotdTasks = new ConcurrentHashMap<>(); + private final ConcurrentHashMap pendingMotdTasks = new ConcurrentHashMap<>(); public EssentialsPlayerListener(final IEssentials parent) { this.ess = parent; @@ -245,9 +246,9 @@ public void onPlayerMove(final PlayerMoveEvent event) { public void onPlayerQuit(final PlayerQuitEvent event) { final User user = ess.getUser(event.getPlayer()); - final Integer pendingId = pendingMotdTasks.remove(user.getUUID()); - if (pendingId != null) { - ess.getScheduler().cancelTask(pendingId); + final SchedulingProvider.EssentialsTask pendingTask = pendingMotdTasks.remove(user.getUUID()); + if (pendingTask != null) { + pendingTask.cancel(); } if (hideJoinQuitMessages() || (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit"))) { @@ -401,7 +402,7 @@ public void run() { final int motdDelay = ess.getSettings().getMotdDelay() / 50; final DelayMotdTask motdTask = new DelayMotdTask(user); if (motdDelay > 0) { - pendingMotdTasks.put(user.getUUID(), ess.scheduleSyncDelayedTask(motdTask, motdDelay)); + pendingMotdTasks.put(user.getUUID(), ess.scheduleEntityDelayedTask(user.getBase(), motdTask, motdDelay)); } else { motdTask.run(); } @@ -493,7 +494,7 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new DelayJoinTask()); + ess.scheduleEntityDelayedTask(player, new DelayJoinTask()); } // Makes the compass item ingame always point to the first essentials home. #EasterEgg @@ -579,7 +580,7 @@ public void onPlayerBucketEmpty(final PlayerBucketEmptyEvent event) { final User user = ess.getUser(event.getPlayer()); if (user.hasUnlimited(new ItemStack(event.getBucket()))) { event.getItemStack().setType(event.getBucket()); - ess.scheduleSyncDelayedTask(user.getBase()::updateInventory); + ess.scheduleEntityDelayedTask(user.getBase(), user.getBase()::updateInventory); } } @@ -824,7 +825,7 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new DelayedClickJumpTask()); + ess.scheduleEntityDelayedTask(user.getBase(), new DelayedClickJumpTask()); } catch (final Exception ex) { if (ess.getSettings().isDebug()) { ess.getLogger().log(Level.WARNING, ex.getMessage(), ex); @@ -855,7 +856,7 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new PowerToolUseTask()); + ess.scheduleEntityDelayedTask(user.getBase(), new PowerToolUseTask()); } } @@ -916,7 +917,7 @@ public void onInventoryClickEvent(final InventoryClickEvent event) { } if (refreshPlayer != null) { - ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1); + ess.scheduleEntityDelayedTask(refreshPlayer, refreshPlayer::updateInventory, 1); } } @@ -958,7 +959,7 @@ public void onInventoryCloseEvent(final InventoryCloseEvent event) { } if (refreshPlayer != null) { - ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1); + ess.scheduleEntityDelayedTask(refreshPlayer, refreshPlayer::updateInventory, 1); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java index fbc96e1d214..edab1924bea 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java @@ -5,7 +5,6 @@ import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -13,36 +12,19 @@ public class EssentialsTimer implements Runnable { private final transient IEssentials ess; private final transient Set onlineUsers = new HashSet<>(); // Field is necessary for hidden users - private final LinkedList history = new LinkedList<>(); - @SuppressWarnings("FieldCanBeLocal") - private final long maxTime = 10 * 1000000; - @SuppressWarnings("FieldCanBeLocal") - private final long tickInterval = 50; - private transient long lastPoll = System.nanoTime(); + private static final long maxTime = 10 * 1000000; private int skip1 = 0; private int skip2 = 0; EssentialsTimer(final IEssentials ess) { this.ess = ess; - history.add(20d); } @Override public void run() { final long startTime = System.nanoTime(); final long currentTime = System.currentTimeMillis(); - long timeSpent = (startTime - lastPoll) / 1000; - if (timeSpent == 0) { - timeSpent = 1; - } - if (history.size() > 10) { - history.remove(); - } - final double tps = tickInterval * 1000000.0 / timeSpent; - if (tps <= 21) { - history.add(tps); - } - lastPoll = startTime; + int count = 0; onlineUsers.clear(); for (final Player player : ess.getOnlinePlayers()) { @@ -99,14 +81,4 @@ public void run() { user.resetInvulnerabilityAfterTeleport(); } } - - public double getAverageTPS() { - double avg = 0; - for (final Double f : history) { - if (f != null) { - avg += f; - } - } - return avg / history.size(); - } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index d8916a958b6..59334158390 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -15,6 +15,7 @@ import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.PersistentDataProvider; +import net.ess3.provider.SchedulingProvider; import net.ess3.provider.SerializationProvider; import net.ess3.provider.ServerStateProvider; import net.ess3.provider.SignDataProvider; @@ -24,15 +25,15 @@ import net.ess3.provider.WorldInfoProvider; import net.essentialsx.api.v2.services.BalanceTop; import net.essentialsx.api.v2.services.mail.MailService; +import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; import java.util.Collection; import java.util.List; @@ -82,8 +83,6 @@ public interface IEssentials extends Plugin { ISettings getSettings(); - BukkitScheduler getScheduler(); - IJails getJails(); IWarps getWarps(); @@ -98,17 +97,33 @@ public interface IEssentials extends Plugin { UpdateChecker getUpdateChecker(); - BukkitTask runTaskAsynchronously(Runnable run); + void runTaskAsynchronously(Runnable run); + + void runTaskLaterAsynchronously(Runnable run, long delay); + + SchedulingProvider.EssentialsTask runTaskTimerAsynchronously(Runnable run, long delay, long period); + + void scheduleEntityDelayedTask(Entity entity, Runnable run); + + SchedulingProvider.EssentialsTask scheduleEntityDelayedTask(Entity entity, Runnable run, long delay); + + SchedulingProvider.EssentialsTask scheduleEntityRepeatingTask(Entity entity, Runnable run, long delay, long period); + + void scheduleLocationDelayedTask(Location location, Runnable run); + + void scheduleLocationDelayedTask(Location location, Runnable run, long delay); - BukkitTask runTaskLaterAsynchronously(Runnable run, long delay); + SchedulingProvider.EssentialsTask scheduleLocationRepeatingTask(Location location, Runnable run, long delay, long period); - BukkitTask runTaskTimerAsynchronously(Runnable run, long delay, long period); + default void scheduleGlobalDelayedTask(Runnable run) { + scheduleGlobalDelayedTask(run, 1); + } - int scheduleSyncDelayedTask(Runnable run); + void scheduleGlobalDelayedTask(Runnable run, long delay); - int scheduleSyncDelayedTask(Runnable run, long delay); + SchedulingProvider.EssentialsTask scheduleGlobalRepeatingTask(Runnable run, long delay, long period); - int scheduleSyncRepeatingTask(Runnable run, long delay, long period); + void scheduleInitTask(Runnable runnable); PermissionsHandler getPermissionsHandler(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/IUser.java b/Essentials/src/main/java/com/earth2me/essentials/IUser.java index 2625b1fc8c2..46094dd064d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IUser.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IUser.java @@ -3,7 +3,6 @@ import com.earth2me.essentials.api.IAsyncTeleport; import com.earth2me.essentials.commands.IEssentialsCommand; import com.earth2me.essentials.config.entities.CommandCooldown; -import net.ess3.api.ITeleport; import net.ess3.api.MaxMoneyException; import net.ess3.api.events.AfkStatusChangeEvent; import net.essentialsx.api.v2.services.mail.MailMessage; @@ -15,7 +14,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; - import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -71,12 +69,6 @@ public interface IUser { @Deprecated boolean hasOutstandingTeleportRequest(); - /** - * @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport} with {@link IUser#getAsyncTeleport()} - */ - @Deprecated - ITeleport getTeleport(); - IAsyncTeleport getAsyncTeleport(); BigDecimal getMoney(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Jails.java b/Essentials/src/main/java/com/earth2me/essentials/Jails.java index 123d159f3ac..677389349f8 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Jails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Jails.java @@ -140,28 +140,6 @@ public void removeJail(String jail) throws Exception { } } - /** - * @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)} - */ - @SuppressWarnings("deprecation") - @Override - @Deprecated - public void sendToJail(final IUser user, String jail) throws Exception { - if (jail == null || jail.isEmpty()) { - return; - } - - jail = jail.toLowerCase(Locale.ENGLISH); - synchronized (jails) { - if (jails.containsKey(jail)) { - if (user.getBase().isOnline()) { - user.getTeleport().now(getJail(jail), false, TeleportCause.COMMAND); - } - user.setJail(jail); - } - } - } - @Override public void sendToJail(final IUser user, final String jailName, final CompletableFuture future) throws Exception { if (jailName == null || jailName.isEmpty()) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java index f020a2cca17..f58bbef4b99 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java @@ -124,7 +124,7 @@ public CompletableFuture getRandomLocation(final Location center, fina // Prompts caching random valid locations, up to a maximum number of attempts public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) { - ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> { + ess.scheduleLocationDelayedTask(center, () -> { for (int i = 0; i < this.getFindAttempts(); ++i) { calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> { if (isValidRandomLocation(location)) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index c0b1c618245..f0757c79b6d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -708,7 +708,7 @@ public void reloadConfig() { // This is 2 because Settings are reloaded twice in the startup lifecycle if (reloadCount.get() < 2) { - ess.scheduleSyncDelayedTask(() -> _addAlternativeCommand(effectiveAlias, toDisable)); + ess.scheduleGlobalDelayedTask(() -> _addAlternativeCommand(effectiveAlias, toDisable)); } else { _addAlternativeCommand(effectiveAlias, toDisable); } @@ -721,7 +721,7 @@ public void reloadConfig() { ess.getLogger().log(Level.INFO, "Syncing commands"); } if (reloadCount.get() < 2) { - ess.scheduleSyncDelayedTask(() -> ess.getSyncCommandsProvider().syncCommands()); + ess.scheduleGlobalDelayedTask(() -> ess.getSyncCommandsProvider().syncCommands()); } else { ess.getSyncCommandsProvider().syncCommands(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/Teleport.java b/Essentials/src/main/java/com/earth2me/essentials/Teleport.java deleted file mode 100644 index 6038b2e3578..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/Teleport.java +++ /dev/null @@ -1,403 +0,0 @@ -package com.earth2me.essentials; - -import com.earth2me.essentials.utils.DateUtil; -import com.earth2me.essentials.utils.LocationUtil; -import io.papermc.lib.PaperLib; -import net.ess3.api.IEssentials; -import net.ess3.api.ITeleport; -import net.ess3.api.IUser; -import net.ess3.api.events.UserWarpEvent; -import net.ess3.api.events.teleport.PreTeleportEvent; -import net.ess3.api.events.teleport.TeleportWarmupEvent; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.math.BigDecimal; -import java.util.Calendar; -import java.util.GregorianCalendar; - -import static com.earth2me.essentials.I18n.tl; - -/** - * @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.AsyncTeleport AsyncTeleport} - */ -@Deprecated -public class Teleport implements ITeleport { - private final IUser teleportOwner; - private final IEssentials ess; - private TimedTeleport timedTeleport; - - private TeleportType tpType; - - @Deprecated - public Teleport(final IUser user, final IEssentials ess) { - this.teleportOwner = user; - this.ess = ess; - tpType = TeleportType.NORMAL; - } - - @Deprecated - public void cooldown(final boolean check) throws Exception { - final Calendar time = new GregorianCalendar(); - if (teleportOwner.getLastTeleportTimestamp() > 0) { - // Take the current time, and remove the delay from it. - final double cooldown = ess.getSettings().getTeleportCooldown(); - final Calendar earliestTime = new GregorianCalendar(); - earliestTime.add(Calendar.SECOND, -(int) cooldown); - earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0)); - // This value contains the most recent time a teleportPlayer could have been used that would allow another use. - final long earliestLong = earliestTime.getTimeInMillis(); - - // When was the last teleportPlayer used? - final long lastTime = teleportOwner.getLastTeleportTimestamp(); - - if (lastTime > time.getTimeInMillis()) { - // This is to make sure time didn't get messed up on last teleportPlayer use. - // If this happens, let's give the user the benifit of the doubt. - teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis()); - return; - } else if (lastTime > earliestLong - && cooldownApplies()) { - time.setTimeInMillis(lastTime); - time.add(Calendar.SECOND, (int) cooldown); - time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0)); - throw new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()))); - } - } - // if justCheck is set, don't update lastTeleport; we're just checking - if (!check) { - teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis()); - } - } - - @Deprecated - private boolean cooldownApplies() { - boolean applies = true; - final String globalBypassPerm = "essentials.teleport.cooldown.bypass"; - switch (tpType) { - case NORMAL: - applies = !teleportOwner.isAuthorized(globalBypassPerm); - break; - case BACK: - applies = !(teleportOwner.isAuthorized(globalBypassPerm) && - teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back")); - break; - case TPA: - applies = !(teleportOwner.isAuthorized(globalBypassPerm) && - teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa")); - break; - } - return applies; - } - - @Deprecated - private void warnUser(final IUser user, final double delay) { - final Calendar c = new GregorianCalendar(); - c.add(Calendar.SECOND, (int) delay); - c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0)); - user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis()))); - } - - //The now function is used when you want to skip tp delay when teleporting someone to a location or player. - @Override - @Deprecated - public void now(final Location loc, final boolean cooldown, final TeleportCause cause) throws Exception { - if (cooldown) { - cooldown(false); - } - final ITarget target = new LocationTarget(loc); - now(teleportOwner, target, cause); - } - - @Override - @Deprecated - public void now(final Player entity, final boolean cooldown, final TeleportCause cause) throws Exception { - if (cooldown) { - cooldown(false); - } - final ITarget target = new PlayerTarget(entity); - now(teleportOwner, target, cause); - teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ())); - } - - @Deprecated - protected void now(final IUser teleportee, final ITarget target, final TeleportCause cause) throws Exception { - cancel(false); - Location loc = target.getLocation(); - - final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - - if (teleportee.isAuthorized("essentials.back.onteleport")) { - teleportee.setLastLocation(); - } - - if (!teleportee.getBase().isEmpty()) { - if (!ess.getSettings().isTeleportPassengerDismount()) { - throw new Exception(tl("passengerTeleportFail")); - } - teleportee.getBase().eject(); - } - - if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) { - if (ess.getSettings().isTeleportSafetyEnabled()) { - if (ess.getSettings().isForceDisableTeleportSafety()) { - PaperLib.teleportAsync(teleportee.getBase(), loc, cause); - } else { - PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause); - } - } else { - throw new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); - } - } else { - if (ess.getSettings().isForceDisableTeleportSafety()) { - PaperLib.teleportAsync(teleportee.getBase(), loc, cause); - } else { - if (ess.getSettings().isTeleportToCenterLocation()) { - loc = LocationUtil.getRoundedDestination(loc); - } - PaperLib.teleportAsync(teleportee.getBase(), loc, cause); - } - } - } - - //The teleportPlayer function is used when you want to normally teleportPlayer someone to a location or player. - //This method is nolonger used internally and will be removed. - @Deprecated - @Override - public void teleport(final Location loc, final Trade chargeFor) throws Exception { - teleport(loc, chargeFor, TeleportCause.PLUGIN); - } - - @Override - @Deprecated - public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception { - teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause); - } - - //This is used when teleporting to a player - @Override - @Deprecated - public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception { - final ITarget target = new PlayerTarget(entity); - teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName())); - teleport(teleportOwner, target, chargeFor, cause); - } - - //This is used when teleporting to stored location - @Override - @Deprecated - public void teleportPlayer(final IUser teleportee, final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception { - teleport(teleportee, new LocationTarget(loc), chargeFor, cause); - } - - //This is used on /tphere - @Override - @Deprecated - public void teleportPlayer(final IUser teleportee, final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception { - final ITarget target = new PlayerTarget(entity); - teleport(teleportee, target, chargeFor, cause); - teleportee.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ())); - teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ())); - } - - @Deprecated - private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception { - double delay = ess.getSettings().getTeleportDelay(); - - final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - delay = event.getDelay(); - - Trade cashCharge = chargeFor; - - if (chargeFor != null) { - chargeFor.isAffordableFor(teleportOwner); - - //This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world. - if (!chargeFor.getCommandCost(teleportOwner).equals(BigDecimal.ZERO)) { - //By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport. - cashCharge = new Trade(chargeFor.getCommandCost(teleportOwner), ess); - } - } - - cooldown(true); - if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) { - cooldown(false); - now(teleportee, target, cause); - if (cashCharge != null) { - cashCharge.charge(teleportOwner); - } - return; - } - - cancel(false); - warnUser(teleportee, delay); - initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false); - } - - @Deprecated - private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception { - double delay = ess.getSettings().getTeleportDelay(); - - final TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - delay = event.getDelay(); - - Trade cashCharge = chargeFor; - - if (teleporter != null && chargeFor != null) { - chargeFor.isAffordableFor(teleporter); - - //This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world. - if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) { - //By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport. - cashCharge = new Trade(chargeFor.getCommandCost(teleporter), ess); - } - } - - cooldown(true); - if (delay <= 0 || teleporter == null - || teleporter.isAuthorized("essentials.teleport.timer.bypass") - || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") - || teleportee.isAuthorized("essentials.teleport.timer.bypass")) { - cooldown(false); - now(teleportee, target, cause); - if (teleporter != null && cashCharge != null) { - cashCharge.charge(teleporter); - } - return; - } - - cancel(false); - warnUser(teleportee, delay); - initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false); - } - - //The respawn function is a wrapper used to handle tp fallback, on /jail and /home - @Override - @Deprecated - public void respawn(final Trade chargeFor, final TeleportCause cause) throws Exception { - double delay = ess.getSettings().getTeleportDelay(); - - final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - delay = event.getDelay(); - - if (chargeFor != null) { - chargeFor.isAffordableFor(teleportOwner); - } - cooldown(true); - if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) { - cooldown(false); - respawnNow(teleportOwner, cause); - if (chargeFor != null) { - chargeFor.charge(teleportOwner); - } - return; - } - - cancel(false); - warnUser(teleportOwner, delay); - initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true); - } - - @Deprecated - void respawnNow(final IUser teleportee, final TeleportCause cause) throws Exception { - final Player player = teleportee.getBase(); - final Location bed = player.getBedSpawnLocation(); - if (bed != null) { - now(teleportee, new LocationTarget(bed), cause); - } else { - if (ess.getSettings().isDebug()) { - ess.getLogger().info("Could not find bed spawn, forcing respawn event."); - } - final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false); - ess.getServer().getPluginManager().callEvent(pre); - now(teleportee, new LocationTarget(pre.getRespawnLocation()), cause); - } - } - - //The warp function is a wrapper used to teleportPlayer a player to a /warp - @Override - @Deprecated - public void warp(final IUser teleportee, String warp, final Trade chargeFor, final TeleportCause cause) throws Exception { - final UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - - warp = event.getWarp(); - final Location loc = ess.getWarps().getWarp(warp); - teleportee.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); - if (!teleportee.equals(teleportOwner)) { - teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); - } - teleport(teleportee, new LocationTarget(loc), chargeFor, cause); - } - - //The back function is a wrapper used to teleportPlayer a player /back to their previous location. - @Override - @Deprecated - public void back(final Trade chargeFor) throws Exception { - back(teleportOwner, chargeFor); - } - - //This function is a wrapper over the other back function for cases where another player performs back for them - @Override - @Deprecated - public void back(final IUser teleporter, final Trade chargeFor) throws Exception { - tpType = TeleportType.BACK; - final Location loc = teleportOwner.getLastLocation(); - teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); - teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND); - } - - //This function is used to throw a user back after a jail sentence - @Override - @Deprecated - public void back() throws Exception { - now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND); - } - - @Deprecated - public void setTpType(final TeleportType tpType) { - this.tpType = tpType; - } - - //If we need to cancelTimer a pending teleportPlayer call this method - @Deprecated - private void cancel(final boolean notifyUser) { - if (timedTeleport != null) { - timedTeleport.cancelTimer(notifyUser); - timedTeleport = null; - } - } - - @Deprecated - private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) { - timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn); - } - - public enum TeleportType { - TPA, - BACK, - NORMAL - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/TimedTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/TimedTeleport.java deleted file mode 100644 index 9e731918b80..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/TimedTeleport.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.earth2me.essentials; - -import net.ess3.api.IEssentials; -import net.ess3.api.IUser; -import org.bukkit.Location; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.UUID; - -import static com.earth2me.essentials.I18n.tl; - -@Deprecated -public class TimedTeleport implements Runnable { - private static final double MOVE_CONSTANT = 0.3; - private final IUser teleportOwner; - private final IEssentials ess; - private final Teleport teleport; - private final UUID timer_teleportee; - private final long timer_started; // time this task was initiated - private final long timer_delay; // how long to delay the teleportPlayer - // note that I initially stored a clone of the location for reference, but... - // when comparing locations, I got incorrect mismatches (rounding errors, looked like) - // so, the X/Y/Z values are stored instead and rounded off - private final long timer_initX; - private final long timer_initY; - private final long timer_initZ; - private final ITarget timer_teleportTarget; - private final boolean timer_respawn; - private final boolean timer_canMove; - private final Trade timer_chargeFor; - private final TeleportCause timer_cause; - private int timer_task; - private double timer_health; - - TimedTeleport(final IUser user, final IEssentials ess, final Teleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) { - this.teleportOwner = user; - this.ess = ess; - this.teleport = teleport; - this.timer_started = System.currentTimeMillis(); - this.timer_delay = delay; - this.timer_health = teleportUser.getBase().getHealth(); - this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT); - this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT); - this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT); - this.timer_teleportee = teleportUser.getBase().getUniqueId(); - this.timer_teleportTarget = target; - this.timer_chargeFor = chargeFor; - this.timer_cause = cause; - this.timer_respawn = respawn; - this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move"); - - timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId(); - } - - @Override - public void run() { - - if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) { - cancelTimer(false); - return; - } - - final IUser teleportUser = ess.getUser(this.timer_teleportee); - - if (teleportUser == null || !teleportUser.getBase().isOnline()) { - cancelTimer(false); - return; - } - - final Location currLocation = teleportUser.getBase().getLocation(); - if (currLocation == null) { - cancelTimer(false); - return; - } - - if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) { - // user moved, cancelTimer teleportPlayer - cancelTimer(true); - return; - } - - class DelayedTeleportTask implements Runnable { - @Override - public void run() { - - timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured - final long now = System.currentTimeMillis(); - if (now > timer_started + timer_delay) { - try { - teleport.cooldown(false); - } catch (final Exception ex) { - teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage())); - if (teleportOwner != teleportUser) { - teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage())); - } - } - try { - cancelTimer(false); - teleportUser.sendMessage(tl("teleportationCommencing")); - - if (timer_chargeFor != null) { - timer_chargeFor.isAffordableFor(teleportOwner); - } - if (timer_respawn) { - teleport.respawnNow(teleportUser, timer_cause); - } else { - teleport.now(teleportUser, timer_teleportTarget, timer_cause); - } - if (timer_chargeFor != null) { - timer_chargeFor.charge(teleportOwner); - } - - } catch (final Exception ex) { - ess.showError(teleportOwner.getSource(), ex, "\\ teleport"); - } - } - } - } - - ess.scheduleSyncDelayedTask(new DelayedTeleportTask()); - } - - //If we need to cancelTimer a pending teleportPlayer call this method - void cancelTimer(final boolean notifyUser) { - if (timer_task == -1) { - return; - } - try { - ess.getServer().getScheduler().cancelTask(timer_task); - if (notifyUser) { - teleportOwner.sendMessage(tl("pendingTeleportCancelled")); - if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) { - ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled")); - } - } - } finally { - timer_task = -1; - } - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/User.java b/Essentials/src/main/java/com/earth2me/essentials/User.java index 4c63fd0be6a..b624b3097e0 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/User.java +++ b/Essentials/src/main/java/com/earth2me/essentials/User.java @@ -57,7 +57,6 @@ public class User extends UserData implements Comparable, IMessageRecipien // User modules private final IMessageRecipient messageRecipient; private transient final AsyncTeleport teleport; - private transient final Teleport legacyTeleport; // User command confirmation strings private final Map confirmingPayments = new WeakHashMap<>(); @@ -97,7 +96,6 @@ public class User extends UserData implements Comparable, IMessageRecipien public User(final Player base, final IEssentials ess) { super(base, ess); teleport = new AsyncTeleport(this, ess); - legacyTeleport = new Teleport(this, ess); if (isAfk()) { afkPosition = this.getLocation(); } @@ -550,15 +548,6 @@ public AsyncTeleport getAsyncTeleport() { return teleport; } - /** - * @deprecated This API is not asynchronous. Use {@link User#getAsyncTeleport()} - */ - @Override - @Deprecated - public Teleport getTeleport() { - return legacyTeleport; - } - public long getLastOnlineActivity() { return lastOnlineActivity; } @@ -811,9 +800,7 @@ public void updateActivityOnInteract(final boolean broadcast) { public void updateActivityOnChat(final boolean broadcast) { if (ess.getSettings().cancelAfkOnChat()) { //Chat happens async, make sure we have a sync context - ess.scheduleSyncDelayedTask(() -> { - updateActivity(broadcast, AfkStatusChangeEvent.Cause.CHAT); - }); + ess.scheduleEntityDelayedTask(base, () -> updateActivity(broadcast, AfkStatusChangeEvent.Cause.CHAT)); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java index 94947c9c298..f39179e3383 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java @@ -46,17 +46,6 @@ public interface IJails extends IConf { */ void removeJail(String jail) throws Exception; - /** - * Attempts to send the given user to the given jail - * - * @param user the user to send to jail - * @param jail the jail to send the user to - * @throws Exception if the user is offline or jail does not exist - * @deprecated Use {@link IJails#sendToJail(IUser, String, CompletableFuture)} - */ - @Deprecated - void sendToJail(IUser user, String jail) throws Exception; - /** * Attempts to send the given user to the given jail * diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbalancetop.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbalancetop.java index a0846e43dca..acdfcfc8c6e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbalancetop.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbalancetop.java @@ -38,7 +38,7 @@ private void outputCache(final CommandSource sender, final int page) { new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender); }; if (sender.getSender() instanceof BlockCommandSender) { - ess.scheduleSyncDelayedTask(runnable); + ess.scheduleGlobalDelayedTask(runnable); } else { runnable.run(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbeezooka.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbeezooka.java index bc55ef47d7e..f06679d7304 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbeezooka.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbeezooka.java @@ -25,7 +25,7 @@ protected void run(final Server server, final User user, final String commandLab final Entity bee = Mob.BEE.spawn(user.getWorld(), server, user.getBase().getEyeLocation()); bee.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2)); - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(bee, () -> { final Location loc = bee.getLocation(); bee.remove(); loc.getWorld().createExplosion(loc, 0F); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandgc.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandgc.java index 5f7392cdea3..4569bcef36f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandgc.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandgc.java @@ -21,7 +21,7 @@ public Commandgc() { @Override protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception { - final double tps = ess.getTimer().getAverageTPS(); + final double tps = 20d; //TODO final ChatColor color; if (tps >= 18.0) { color = ChatColor.GREEN; diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkittycannon.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkittycannon.java index e40234f5218..6356fe6d075 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkittycannon.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkittycannon.java @@ -42,7 +42,7 @@ private static Entity spawnCat(final Server server, final User user) throws Mob. @Override protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception { final Entity ocelot = Mob.CAT.getType() == null ? spawnOcelot(server, user) : spawnCat(server, user); - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(ocelot, () -> { final Location loc = ocelot.getLocation(); ocelot.remove(); loc.getWorld().createExplosion(loc, 0F); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandseen.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandseen.java index f6c3e2d0040..ba992ba878d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandseen.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandseen.java @@ -59,7 +59,7 @@ protected void run(final Server server, final CommandSource sender, final String return; } } - ess.getScheduler().runTaskAsynchronously(ess, new Runnable() { + ess.runTaskAsynchronously(new Runnable() { @Override public void run() { final User userFromBukkit = ess.getUsers().getUser(args[0]); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandskull.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandskull.java index 4e106554848..dfd79d32def 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandskull.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandskull.java @@ -64,7 +64,7 @@ private void editSkull(final User user, final ItemStack stack, final SkullMeta s skullMeta.setDisplayName("§fSkull of " + owner); //noinspection deprecation skullMeta.setOwner(owner); - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(user.getBase(), () -> { stack.setItemMeta(skullMeta); if (spawn) { Inventories.addItem(user.getBase(), stack); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsudo.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsudo.java index df264f4dd7b..ebdcd790045 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsudo.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandsudo.java @@ -55,7 +55,7 @@ public void run() { } } - ess.scheduleSyncDelayedTask(new SudoCommandTask()); + ess.scheduleEntityDelayedTask(user.getBase(), new SudoCommandTask()); } } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/economy/EconomyLayers.java b/Essentials/src/main/java/com/earth2me/essentials/economy/EconomyLayers.java index a4184e5588a..e1ebf5d6617 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/economy/EconomyLayers.java +++ b/Essentials/src/main/java/com/earth2me/essentials/economy/EconomyLayers.java @@ -32,7 +32,7 @@ public static void init() { } public static void onEnable(final Essentials ess) { - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleInitTask(() -> { serverStarted = true; for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { if (!plugin.isEnabled()) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/textreader/KeywordReplacer.java b/Essentials/src/main/java/com/earth2me/essentials/textreader/KeywordReplacer.java index f53d62940f3..87db4347c52 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/textreader/KeywordReplacer.java +++ b/Essentials/src/main/java/com/earth2me/essentials/textreader/KeywordReplacer.java @@ -341,7 +341,7 @@ private String replaceLine(String line, final String fullMatch, final String[] m } break; case TPS: - replacer = NumberUtil.formatDouble(ess.getTimer().getAverageTPS()); + replacer = NumberUtil.formatDouble(20d); //todo break; case UPTIME: replacer = DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()); diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java index e61786346d2..576ffe3a768 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/VersionUtil.java @@ -42,10 +42,20 @@ public final class VersionUtil { private static final Set supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01, v1_15_2_R01, v1_16_5_R01, v1_17_1_R01, v1_18_2_R01, v1_19_4_R01); public static final boolean PRE_FLATTENING = VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01); + public static final boolean FOLIA; private static final Map unsupportedServerClasses; static { + boolean isFolia; + try { + Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); + isFolia = true; + } catch (Throwable ignored) { + isFolia = false; + } + FOLIA = isFolia; + final ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); // Yatopia - Extremely volatile patch set; diff --git a/Essentials/src/main/resources/plugin.yml b/Essentials/src/main/resources/plugin.yml index 3faa7e5bb13..79c668edb33 100644 --- a/Essentials/src/main/resources/plugin.yml +++ b/Essentials/src/main/resources/plugin.yml @@ -8,6 +8,7 @@ description: Provides an essential, core set of commands for Bukkit. softdepend: [Vault, LuckPerms] authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, KHobbits, md_5, Iaccidentally, drtshock, vemacs, SupaHam, mdcfe, JRoy, pop4959] api-version: "1.13" +folia-supported: true commands: afk: description: Marks you as away-from-keyboard. diff --git a/EssentialsAntiBuild/src/main/resources/plugin.yml b/EssentialsAntiBuild/src/main/resources/plugin.yml index f7dac0e8942..1558a519cea 100644 --- a/EssentialsAntiBuild/src/main/resources/plugin.yml +++ b/EssentialsAntiBuild/src/main/resources/plugin.yml @@ -8,7 +8,7 @@ description: Provides build protection. authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, KHobbits, Iaccidentally, drtshock, mdcfe] depend: [Essentials] api-version: "1.13" - +folia-supported: true permissions: essentials.exempt.protect: default: false diff --git a/EssentialsChat/src/main/resources/plugin.yml b/EssentialsChat/src/main/resources/plugin.yml index ab1d85c5a36..7fa9d802c05 100644 --- a/EssentialsChat/src/main/resources/plugin.yml +++ b/EssentialsChat/src/main/resources/plugin.yml @@ -8,6 +8,7 @@ description: Provides chat control features for Essentials. Requires Permission authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, KHobbits, md_5, Okamosy, Iaccidentally, mdcfe, JRoy, triagonal] depend: [Essentials] api-version: 1.13 +folia-supported: true commands: toggleshout: description: Toggles whether you are talking in shout mode diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/EssentialsDiscord.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/EssentialsDiscord.java index ca288a580c2..a1f47d1ecbf 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/EssentialsDiscord.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/EssentialsDiscord.java @@ -57,7 +57,7 @@ public void onEnable() { jda = new JDADiscordService(this); try { jda.startup(); - ess.scheduleSyncDelayedTask(() -> ((InteractionControllerImpl) jda.getInteractionController()).processBatchRegistration()); + ess.scheduleInitTask(() -> ((InteractionControllerImpl) jda.getInteractionController()).processBatchRegistration()); } catch (Exception e) { getLogger().log(Level.SEVERE, tl("discordErrorLogin", e.getMessage())); if (ess.getSettings().isDebug()) { diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java index 9ce07b6fe1f..31dbf794674 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java @@ -229,7 +229,7 @@ public void startup() throws LoginException, InterruptedException { logger.log(Level.WARNING, "Error while loading the achievement/advancement listener. You will not receive achievement/advancement notifications on Discord.", e); } - getPlugin().getEss().scheduleSyncDelayedTask(() -> DiscordUtil.dispatchDiscordMessage(JDADiscordService.this, MessageType.DefaultTypes.SERVER_START, getSettings().getStartMessage(), true, null, null, null)); + getPlugin().getEss().scheduleInitTask(() -> DiscordUtil.dispatchDiscordMessage(JDADiscordService.this, MessageType.DefaultTypes.SERVER_START, getSettings().getStartMessage(), true, null, null, null)); Bukkit.getServicesManager().register(DiscordService.class, this, plugin, ServicePriority.Normal); } diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java index 28bb8c9603d..0cea35a9f10 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java @@ -61,7 +61,7 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) { interactionEvent.reply(tl("noAccessCommand")); return; } - jda.getPlugin().getEss().scheduleSyncDelayedTask(() -> command.onCommand(interactionEvent)); + //jda.getPlugin().getEss().scheduleSyncDelayedTask(() -> command.onCommand(interactionEvent)); //todo } @Override diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordCommandSender.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordCommandSender.java index f8389c9e43b..c65f375c6d6 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordCommandSender.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordCommandSender.java @@ -2,17 +2,16 @@ import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.VersionUtil; +import net.ess3.provider.SchedulingProvider; import net.ess3.provider.providers.BukkitSenderProvider; import net.ess3.provider.providers.PaperCommandSender; import net.essentialsx.discord.JDADiscordService; -import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.scheduler.BukkitTask; public class DiscordCommandSender { private final CommandSender sender; - private BukkitTask task; + private SchedulingProvider.EssentialsTask task; private String responseBuffer = ""; private long lastTime = System.currentTimeMillis(); @@ -23,7 +22,7 @@ public DiscordCommandSender(JDADiscordService jda, ConsoleCommandSender sender, }; this.sender = getCustomSender(sender, hook); - task = Bukkit.getScheduler().runTaskTimerAsynchronously(jda.getPlugin(), () -> { + task = jda.getPlugin().getEss().runTaskTimerAsynchronously(() -> { if (!responseBuffer.isEmpty() && System.currentTimeMillis() - lastTime >= 1000) { callback.onMessage(responseBuffer); responseBuffer = ""; diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java index dfe95366279..baf4052ff6c 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java @@ -214,10 +214,6 @@ public static void dispatchDiscordMessage(final JDADiscordService jda, final Mes return; } - if (Bukkit.getServer().isPrimaryThread()) { - Bukkit.getPluginManager().callEvent(event); - } else { - Bukkit.getScheduler().runTask(jda.getPlugin(), () -> Bukkit.getPluginManager().callEvent(event)); - } + jda.getPlugin().getEss().scheduleGlobalDelayedTask(() -> Bukkit.getPluginManager().callEvent(event)); } } diff --git a/EssentialsDiscord/src/main/resources/plugin.yml b/EssentialsDiscord/src/main/resources/plugin.yml index fad076db5fe..93e6c56b8cd 100644 --- a/EssentialsDiscord/src/main/resources/plugin.yml +++ b/EssentialsDiscord/src/main/resources/plugin.yml @@ -8,6 +8,7 @@ authors: [mdcfe, JRoy, pop4959, Glare] depend: [Essentials] softdepend: [EssentialsChat, PlaceholderAPI] api-version: 1.13 +folia-supported: true commands: discordbroadcast: description: Broadcasts a message to the specified Discord channel. diff --git a/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/AccountLinkManager.java b/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/AccountLinkManager.java index 10b33d9d513..bc98d44646e 100644 --- a/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/AccountLinkManager.java +++ b/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/AccountLinkManager.java @@ -139,7 +139,7 @@ private void ensureSync(final Runnable runnable) { runnable.run(); return; } - ess.getEss().scheduleSyncDelayedTask(runnable); + ess.getEss().scheduleGlobalDelayedTask(runnable); } private void ensureAsync(final Runnable runnable) { diff --git a/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/listeners/LinkBukkitListener.java b/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/listeners/LinkBukkitListener.java index 4ea071ff67e..8a1450e2a93 100644 --- a/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/listeners/LinkBukkitListener.java +++ b/EssentialsDiscordLink/src/main/java/net/essentialsx/discordlink/listeners/LinkBukkitListener.java @@ -156,7 +156,7 @@ public void onUserLinkStatusChange(final DiscordLinkStatusChangeEvent event) { if (Bukkit.isPrimaryThread()) { kickTask.run(); } else { - ess.getEss().scheduleSyncDelayedTask(kickTask); + ess.getEss().scheduleEntityDelayedTask(event.getUser().getBase(), kickTask); } break; } diff --git a/EssentialsDiscordLink/src/main/resources/plugin.yml b/EssentialsDiscordLink/src/main/resources/plugin.yml index 49df5f7f3d0..aa0568eabd7 100644 --- a/EssentialsDiscordLink/src/main/resources/plugin.yml +++ b/EssentialsDiscordLink/src/main/resources/plugin.yml @@ -7,6 +7,7 @@ description: EssentialsX Discord addon which allows you link your Minecraft and authors: [JRoy] depend: [EssentialsDiscord] api-version: 1.13 +folia-supported: true commands: link: description: Generates a code to link your Minecraft account to Discord. diff --git a/EssentialsGeoIP/src/main/resources/plugin.yml b/EssentialsGeoIP/src/main/resources/plugin.yml index 2ddee7b1201..6a52547ffad 100644 --- a/EssentialsGeoIP/src/main/resources/plugin.yml +++ b/EssentialsGeoIP/src/main/resources/plugin.yml @@ -8,3 +8,4 @@ description: Shows the country or city of a user on login and /whois. authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, kjiang, pop4959] depend: [Essentials] api-version: 1.13 +folia-supported: true diff --git a/EssentialsProtect/src/main/resources/plugin.yml b/EssentialsProtect/src/main/resources/plugin.yml index 65764be4a41..25340332643 100644 --- a/EssentialsProtect/src/main/resources/plugin.yml +++ b/EssentialsProtect/src/main/resources/plugin.yml @@ -8,3 +8,4 @@ description: Provides protection for various parts of the world. authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, KHobbits, drtshock] softdepend: [Essentials] api-version: 1.13 +folia-supported: true diff --git a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java index 59d8b4efeed..a1d8d72ac84 100644 --- a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java +++ b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/EssentialsSpawnPlayerListener.java @@ -83,7 +83,7 @@ private void delayedJoin(final Player player) { final User user = ess.getUser(player); if (ess.getSettings().isUserInSpawnOnJoinGroup(user) && !user.isAuthorized("essentials.spawn-on-join.exempt")) { - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(player, () -> { final Location spawn = spawns.getSpawn(user.getGroup()); if (spawn == null) { return; @@ -104,10 +104,10 @@ private void delayedJoin(final Player player) { final User user = ess.getUser(player); if (!"none".equalsIgnoreCase(ess.getSettings().getNewbieSpawn())) { - ess.scheduleSyncDelayedTask(new NewPlayerTeleport(user), 1L); + ess.scheduleEntityDelayedTask(player, new NewPlayerTeleport(user), 1L); } - ess.scheduleSyncDelayedTask(() -> { + ess.scheduleEntityDelayedTask(player, () -> { if (!user.getBase().isOnline()) { return; } diff --git a/EssentialsSpawn/src/main/resources/plugin.yml b/EssentialsSpawn/src/main/resources/plugin.yml index e0a7b770d05..3746812f451 100644 --- a/EssentialsSpawn/src/main/resources/plugin.yml +++ b/EssentialsSpawn/src/main/resources/plugin.yml @@ -8,6 +8,7 @@ description: Provides spawn control commands, utilizing Essentials. authors: [Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans, Xeology, KHobbits, SupaHam, mdcfe, DoNotSpamPls, JRoy] depend: [Essentials] api-version: 1.13 +folia-supported: true commands: setspawn: description: Sets the spawn point to your current position. From 07fbf930015d6cdc7ee4765f0248957713972a2b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:23:27 -0400 Subject: [PATCH 03/21] Ensure nuke commands runs on correct threads --- .../essentials/commands/Commandnuke.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandnuke.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandnuke.java index f7bf8a33c5f..54da6594ab4 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandnuke.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandnuke.java @@ -38,17 +38,19 @@ protected void run(final Server server, final CommandSource sender, final String if (player == null) { continue; } - player.sendMessage(tl("nuke")); - final Location loc = player.getLocation(); - final World world = loc.getWorld(); - if (world != null) { - for (int x = -10; x <= 10; x += 5) { - for (int z = -10; z <= 10; z += 5) { - final TNTPrimed entity = world.spawn(new Location(world, loc.getBlockX() + x, world.getHighestBlockYAt(loc) + 64, loc.getBlockZ() + z), TNTPrimed.class); - entity.setMetadata(NUKE_META_KEY, new FixedMetadataValue(ess, true)); + ess.scheduleEntityDelayedTask(player, () -> { + player.sendMessage(tl("nuke")); + final Location loc = player.getLocation(); + final World world = loc.getWorld(); + if (world != null) { + for (int x = -10; x <= 10; x += 5) { + for (int z = -10; z <= 10; z += 5) { + final TNTPrimed entity = world.spawn(new Location(world, loc.getBlockX() + x, world.getHighestBlockYAt(loc) + 64, loc.getBlockZ() + z), TNTPrimed.class); + entity.setMetadata(NUKE_META_KEY, new FixedMetadataValue(ess, true)); + } } } - } + }); } } From 20882940c52ce2b12c01f9a31b66a769dae3c95f Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:30:51 -0400 Subject: [PATCH 04/21] Actually fire init tasks in Folia --- .../net/ess3/provider/providers/FoliaSchedulingProvider.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java index bb4697727af..9ec92f9333d 100644 --- a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java +++ b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java @@ -6,18 +6,20 @@ import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -public class FoliaSchedulingProvider implements SchedulingProvider { +public class FoliaSchedulingProvider implements SchedulingProvider, Listener { private final Plugin plugin; private List initTasks = new ArrayList<>(); public FoliaSchedulingProvider(Plugin plugin) { this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); } @EventHandler From a649f978c5000f488558d579664d6c3221931252 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 28 Mar 2023 21:57:24 -0400 Subject: [PATCH 05/21] Add some thread checking helper methods pending PaperMC/Folia#5 for global region helpers --- .../java/net/ess3/provider/SchedulingProvider.java | 4 ++++ .../provider/providers/BukkitSchedulingProvider.java | 10 ++++++++++ .../provider/providers/FoliaSchedulingProvider.java | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java index 83a5a62cc37..0b4ca9c631c 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java @@ -6,6 +6,10 @@ public interface SchedulingProvider extends Provider { void registerInitTask(Runnable runnable); + boolean isEntityThread(Entity entity); + + boolean isRegionThread(Location location); + void runEntityTask(Entity entity, Runnable runnable); EssentialsTask runEntityTask(Entity entity, Runnable runnable, long delay); diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java index 887999fea1f..94433986d19 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java @@ -18,6 +18,16 @@ public void registerInitTask(Runnable runnable) { plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, runnable); } + @Override + public boolean isEntityThread(Entity entity) { + return plugin.getServer().isPrimaryThread(); + } + + @Override + public boolean isRegionThread(Location location) { + return plugin.getServer().isPrimaryThread(); + } + @Override public void runEntityTask(Entity entity, Runnable runnable) { runEntityTask(entity, runnable, 1); diff --git a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java index 9ec92f9333d..4ffdf8e93d7 100644 --- a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java +++ b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java @@ -38,6 +38,16 @@ public void registerInitTask(Runnable runnable) { initTasks.add(runnable); } + @Override + public boolean isEntityThread(Entity entity) { + return plugin.getServer().isOwnedByCurrentRegion(entity); + } + + @Override + public boolean isRegionThread(Location location) { + return plugin.getServer().isOwnedByCurrentRegion(location); + } + @Override public void runEntityTask(Entity entity, Runnable runnable) { runEntityTask(entity, runnable, 1); From 04683ee43b40f58b7c8565e9ca7fb0eeb561ac1b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 29 Mar 2023 19:57:57 -0400 Subject: [PATCH 06/21] Fix async entity dismounts --- .../java/com/earth2me/essentials/AsyncTeleport.java | 9 +++++---- .../main/java/com/earth2me/essentials/Essentials.java | 10 ++++++++++ .../main/java/com/earth2me/essentials/IEssentials.java | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java index 26567ffaa5a..16a10e1ef2f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java @@ -13,6 +13,7 @@ import net.ess3.api.events.teleport.TeleportWarmupEvent; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -141,13 +142,13 @@ public void nowUnsafe(Location loc, TeleportCause cause, CompletableFuture taskLock = new CompletableFuture<>(); - Bukkit.getScheduler().runTask(ess, () -> { + ess.scheduleEntityDelayedTask(entity, () -> { runnable.run(); taskLock.complete(new Object()); }); @@ -171,7 +172,7 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele } try { - runOnMain(() -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context. + runOnEntity(teleportee.getBase(), () -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context. } catch (final ExecutionException | InterruptedException e) { future.completeExceptionally(e); return; diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 77b24ca1fb8..aaf11837d0e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -1228,6 +1228,16 @@ public SchedulingProvider.EssentialsTask scheduleGlobalRepeatingTask(Runnable ru return schedulingProvider.runGlobalLocationalTaskRepeating(run, delay, period); } + @Override + public boolean isEntityThread(Entity entity) { + return schedulingProvider.isEntityThread(entity); + } + + @Override + public boolean isRegionThread(Location location) { + return schedulingProvider.isRegionThread(location); + } + @Override public PermissionsHandler getPermissionsHandler() { return permissionsHandler; diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index 59334158390..0f0c51a2db7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -125,6 +125,10 @@ default void scheduleGlobalDelayedTask(Runnable run) { void scheduleInitTask(Runnable runnable); + boolean isEntityThread(Entity entity); + + boolean isRegionThread(Location location); + PermissionsHandler getPermissionsHandler(); AlternativeCommandsHandler getAlternativeCommandsHandler(); From 1d93ebfddd77f6614bc53e56eed7de16d98d974e Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 29 Mar 2023 19:59:30 -0400 Subject: [PATCH 07/21] Fix moo --- .../com/earth2me/essentials/commands/Commandessentials.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java index 6fa2873afa2..2e3ae8b96bc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java @@ -502,8 +502,10 @@ private void runMoo(final Server server, final CommandSource sender, final Strin ess.getLogger().info(s); } for (final Player player : ess.getOnlinePlayers()) { - player.sendMessage(PLAYER_MOO); - player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f); + ess.scheduleEntityDelayedTask(player, () -> { + player.sendMessage(PLAYER_MOO); + player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f); + }); } } else { if (sender.isPlayer()) { From 05a8aa88838a22675306aebf35c51609c8530e6b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:06:35 -0400 Subject: [PATCH 08/21] Switch to Paper repo --- settings.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index d6ed8b4292b..65e89d2d9e0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,7 +21,6 @@ dependencyResolutionManagement { content { includeGroup("net.kyori") } content { includeGroup("org.apache.logging.log4j") } } - mavenLocal() } repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) } From 9a5ac3cad849bc7e1df56b5e9978bdcfadcacc41 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:20:29 -0400 Subject: [PATCH 09/21] Fix tests --- Essentials/src/main/java/com/earth2me/essentials/Essentials.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index aaf11837d0e..f7bac6ea2d0 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -213,6 +213,7 @@ public ISettings getSettings() { public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException { LOGGER = new BaseLoggerProvider(this, BUKKIT_LOGGER); + schedulingProvider = new BukkitSchedulingProvider(this); final File dataFolder = File.createTempFile("essentialstest", ""); if (!dataFolder.delete()) { throw new IOException(); From 4ff9286a799148fc6110a62b5d2541e99ed68813 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:28:41 -0400 Subject: [PATCH 10/21] Move over some discord things --- .../discord/listeners/DiscordCommandDispatcher.java | 2 +- .../net/essentialsx/discord/util/ConsoleInjector.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordCommandDispatcher.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordCommandDispatcher.java index 20fa1ff0a96..2ddbf8d6c65 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordCommandDispatcher.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordCommandDispatcher.java @@ -25,7 +25,7 @@ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { } final String command = event.getMessage().getContentRaw(); - Bukkit.getScheduler().runTask(jda.getPlugin(), () -> { + jda.getPlugin().getEss().scheduleGlobalDelayedTask(() -> { try { Bukkit.dispatchCommand(new DiscordCommandSender(jda, Bukkit.getConsoleSender(), message -> event.getMessage().reply(message).queue()).getSender(), command); diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/ConsoleInjector.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/ConsoleInjector.java index 3d2502770aa..5546fe849a5 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/ConsoleInjector.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/ConsoleInjector.java @@ -4,6 +4,7 @@ import com.google.common.base.Splitter; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.utils.TimeFormat; +import net.ess3.provider.SchedulingProvider; import net.essentialsx.discord.EssentialsDiscord; import net.essentialsx.discord.JDADiscordService; import org.apache.logging.log4j.LogManager; @@ -11,7 +12,6 @@ import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.appender.AbstractAppender; import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.bukkit.Bukkit; import java.time.Instant; import java.util.concurrent.BlockingQueue; @@ -26,14 +26,14 @@ public class ConsoleInjector extends AbstractAppender { private final JDADiscordService jda; private final BlockingQueue messageQueue = new LinkedBlockingQueue<>(); - private final int taskId; + private final SchedulingProvider.EssentialsTask task; private boolean removed = false; public ConsoleInjector(JDADiscordService jda) { super("EssentialsX-ConsoleInjector", null, null, false); this.jda = jda; ((Logger) LogManager.getRootLogger()).addAppender(this); - taskId = Bukkit.getScheduler().runTaskTimerAsynchronously(jda.getPlugin(), () -> { + task = jda.getPlugin().getEss().runTaskTimerAsynchronously(() -> { final StringBuilder buffer = new StringBuilder(); String curLine; while ((curLine = messageQueue.peek()) != null) { @@ -47,7 +47,7 @@ public ConsoleInjector(JDADiscordService jda) { if (buffer.length() != 0) { sendMessage(buffer.toString()); } - }, 20, 40).getTaskId(); + }, 20, 40); } private void sendMessage(String content) { @@ -92,7 +92,7 @@ public void append(LogEvent event) { public void remove() { ((Logger) LogManager.getRootLogger()).removeAppender(this); - Bukkit.getScheduler().cancelTask(taskId); + task.cancel(); messageQueue.clear(); removed = true; } From 2d8cc827b9f3046cc4ef2f50032cffbcc96c7a9a Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:31:16 -0400 Subject: [PATCH 11/21] Add method for checking the global thread --- .../src/main/java/com/earth2me/essentials/Essentials.java | 5 +++++ .../src/main/java/com/earth2me/essentials/IEssentials.java | 2 ++ .../src/main/java/net/ess3/provider/SchedulingProvider.java | 2 ++ .../ess3/provider/providers/BukkitSchedulingProvider.java | 6 ++++++ .../ess3/provider/providers/FoliaSchedulingProvider.java | 5 +++++ 5 files changed, 20 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index f7bac6ea2d0..1a3dcae411d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -1239,6 +1239,11 @@ public boolean isRegionThread(Location location) { return schedulingProvider.isRegionThread(location); } + @Override + public boolean isGlobalThread() { + return schedulingProvider.isGlobalThread(); + } + @Override public PermissionsHandler getPermissionsHandler() { return permissionsHandler; diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index 0f0c51a2db7..375aa77a181 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -129,6 +129,8 @@ default void scheduleGlobalDelayedTask(Runnable run) { boolean isRegionThread(Location location); + boolean isGlobalThread(); + PermissionsHandler getPermissionsHandler(); AlternativeCommandsHandler getAlternativeCommandsHandler(); diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java index 0b4ca9c631c..8206a16f213 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/SchedulingProvider.java @@ -10,6 +10,8 @@ public interface SchedulingProvider extends Provider { boolean isRegionThread(Location location); + boolean isGlobalThread(); + void runEntityTask(Entity entity, Runnable runnable); EssentialsTask runEntityTask(Entity entity, Runnable runnable, long delay); diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java index 94433986d19..ac21c00405a 100644 --- a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/BukkitSchedulingProvider.java @@ -1,6 +1,7 @@ package net.ess3.provider.providers; import net.ess3.provider.SchedulingProvider; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.plugin.Plugin; @@ -28,6 +29,11 @@ public boolean isRegionThread(Location location) { return plugin.getServer().isPrimaryThread(); } + @Override + public boolean isGlobalThread() { + return Bukkit.isPrimaryThread(); + } + @Override public void runEntityTask(Entity entity, Runnable runnable) { runEntityTask(entity, runnable, 1); diff --git a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java index 4ffdf8e93d7..0cc884506cd 100644 --- a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java +++ b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java @@ -48,6 +48,11 @@ public boolean isRegionThread(Location location) { return plugin.getServer().isOwnedByCurrentRegion(location); } + @Override + public boolean isGlobalThread() { + return plugin.getServer().isGlobalTickThread(); + } + @Override public void runEntityTask(Entity entity, Runnable runnable) { runEntityTask(entity, runnable, 1); From 7216fddfbe4694dc4aa1119ed48df10dcb9604b1 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 30 Mar 2023 13:40:13 -0400 Subject: [PATCH 12/21] Add helper methods for ensuring thread contexts --- .../earth2me/essentials/AsyncTeleport.java | 18 +----- .../com/earth2me/essentials/Essentials.java | 59 +++++++++++++++++++ .../com/earth2me/essentials/IEssentials.java | 6 ++ 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java index 16a10e1ef2f..25a334df03b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java @@ -13,7 +13,6 @@ import net.ess3.api.events.teleport.TeleportWarmupEvent; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -142,19 +141,6 @@ public void nowUnsafe(Location loc, TeleportCause cause, CompletableFuture taskLock = new CompletableFuture<>(); - ess.scheduleEntityDelayedTask(entity, () -> { - runnable.run(); - taskLock.complete(new Object()); - }); - taskLock.get(); - } - protected void nowAsync(final IUser teleportee, final ITarget target, final TeleportCause cause, final CompletableFuture future) { cancel(false); @@ -172,8 +158,8 @@ protected void nowAsync(final IUser teleportee, final ITarget target, final Tele } try { - runOnEntity(teleportee.getBase(), () -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context. - } catch (final ExecutionException | InterruptedException e) { + ess.ensureEntity(teleportee.getBase(), () -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context. + } catch (final RuntimeException e) { future.completeExceptionally(e); return; } diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 1a3dcae411d..a3477c6fce0 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -138,6 +138,8 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; @@ -1244,6 +1246,63 @@ public boolean isGlobalThread() { return schedulingProvider.isGlobalThread(); } + @Override + public void ensureEntity(Entity entity, Runnable runnable) { + if (isEntityThread(entity)) { + runnable.run(); + return; + } + + final CompletableFuture taskLock = new CompletableFuture<>(); + scheduleEntityDelayedTask(entity, () -> { + runnable.run(); + taskLock.complete(new Object()); + }); + try { + taskLock.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + @Override + public void ensureRegion(Location location, Runnable runnable) { + if (isRegionThread(location)) { + runnable.run(); + return; + } + + final CompletableFuture taskLock = new CompletableFuture<>(); + scheduleLocationDelayedTask(location, () -> { + runnable.run(); + taskLock.complete(new Object()); + }); + try { + taskLock.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + + @Override + public void ensureGlobal(Runnable runnable) { + if (isGlobalThread()) { + runnable.run(); + return; + } + + final CompletableFuture taskLock = new CompletableFuture<>(); + scheduleGlobalDelayedTask(() -> { + runnable.run(); + taskLock.complete(new Object()); + }); + try { + taskLock.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + @Override public PermissionsHandler getPermissionsHandler() { return permissionsHandler; diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index 375aa77a181..4c1c22c164c 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -131,6 +131,12 @@ default void scheduleGlobalDelayedTask(Runnable run) { boolean isGlobalThread(); + void ensureEntity(Entity entity, Runnable runnable); + + void ensureRegion(Location location, Runnable runnable); + + void ensureGlobal(Runnable runnable); + PermissionsHandler getPermissionsHandler(); AlternativeCommandsHandler getAlternativeCommandsHandler(); From 2ba1eb0cf9f896af7168d2ea24a721f04414c953 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 1 Apr 2023 17:42:38 -0400 Subject: [PATCH 13/21] fix "Fix moo" --- .../com/earth2me/essentials/commands/Commandessentials.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java index 2e3ae8b96bc..6fa2873afa2 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java @@ -502,10 +502,8 @@ private void runMoo(final Server server, final CommandSource sender, final Strin ess.getLogger().info(s); } for (final Player player : ess.getOnlinePlayers()) { - ess.scheduleEntityDelayedTask(player, () -> { - player.sendMessage(PLAYER_MOO); - player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f); - }); + player.sendMessage(PLAYER_MOO); + player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f); } } else { if (sender.isPlayer()) { From 7279be7850d6fbf8161ae83233403e585e56ed00 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 2 Apr 2023 20:58:56 -0400 Subject: [PATCH 14/21] allow DiscordMessageEvent calls from any context --- .../api/v2/events/discord/DiscordMessageEvent.java | 4 ++++ .../java/net/essentialsx/discord/JDADiscordService.java | 6 +----- .../main/java/net/essentialsx/discord/util/DiscordUtil.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordMessageEvent.java b/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordMessageEvent.java index c9f5f4765b3..72700c6880d 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordMessageEvent.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordMessageEvent.java @@ -1,6 +1,7 @@ package net.essentialsx.api.v2.events.discord; import net.essentialsx.api.v2.services.discord.MessageType; +import org.bukkit.Bukkit; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -10,6 +11,8 @@ /** * Fired before a message is about to be sent to a Discord channel. + *

+ * Note: This event has no guarantee of the thread it is fired on, please use {@link #isAsynchronous()}} to see if this event is off the main Bukkit thread. */ public class DiscordMessageEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -40,6 +43,7 @@ public DiscordMessageEvent(final MessageType type, final String message, final b * @param uuid The UUID of the player which caused this event or null if this wasn't a player triggered event. */ public DiscordMessageEvent(final MessageType type, final String message, final boolean allowGroupMentions, final String avatarUrl, final String name, final UUID uuid) { + super(!Bukkit.isPrimaryThread()); this.type = type; this.message = message; this.allowGroupMentions = allowGroupMentions; diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java index 31dbf794674..9de36d81e45 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java @@ -258,11 +258,7 @@ public void sendMessage(MessageType type, String message, boolean allowGroupMent logger.warning("Sending message to channel \"" + type.getKey() + "\" which is an unregistered type! If you are a plugin author, you should be registering your MessageType before using them."); } final DiscordMessageEvent event = new DiscordMessageEvent(type, FormatUtil.stripFormat(message), allowGroupMentions); - if (Bukkit.getServer().isPrimaryThread()) { - Bukkit.getPluginManager().callEvent(event); - } else { - Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getPluginManager().callEvent(event)); - } + Bukkit.getPluginManager().callEvent(event); } @Override diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java index baf4052ff6c..33737e9161b 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/util/DiscordUtil.java @@ -214,6 +214,6 @@ public static void dispatchDiscordMessage(final JDADiscordService jda, final Mes return; } - jda.getPlugin().getEss().scheduleGlobalDelayedTask(() -> Bukkit.getPluginManager().callEvent(event)); + Bukkit.getPluginManager().callEvent(event); } } From 4cb861badc015067482fa80287986e91726fc15a Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 2 Apr 2023 21:11:55 -0400 Subject: [PATCH 15/21] Run interaction commands async for now (hopefully okay) --- .../discord/interactions/InteractionControllerImpl.java | 3 ++- .../discord/interactions/commands/ExecuteCommand.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java index 0cea35a9f10..533c5575cf2 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/InteractionControllerImpl.java @@ -61,7 +61,8 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) { interactionEvent.reply(tl("noAccessCommand")); return; } - //jda.getPlugin().getEss().scheduleSyncDelayedTask(() -> command.onCommand(interactionEvent)); //todo + + command.onCommand(interactionEvent); } @Override diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/commands/ExecuteCommand.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/commands/ExecuteCommand.java index 0a856b53237..cd258931099 100644 --- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/commands/ExecuteCommand.java +++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/interactions/commands/ExecuteCommand.java @@ -22,7 +22,7 @@ public ExecuteCommand(JDADiscordService jda) { public void onCommand(final InteractionEvent event) { final String command = event.getStringArgument("command"); event.reply(tl("discordCommandExecuteReply", command)); - Bukkit.getScheduler().runTask(jda.getPlugin(), () -> { + jda.getPlugin().getEss().scheduleGlobalDelayedTask(() -> { try { Bukkit.dispatchCommand(new DiscordCommandSender(jda, Bukkit.getConsoleSender(), message -> event.reply(MessageUtil.sanitizeDiscordMarkdown(message))).getSender(), command); } catch (CommandException e) { From ec5007c07eb7e4338bc22c70d5fd8a1a398d21dd Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:45:22 -0400 Subject: [PATCH 16/21] fix wrong period/timeunit for folia scheduling --- .../net/ess3/provider/providers/FoliaSchedulingProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java index 0cc884506cd..0e5e538f507 100644 --- a/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java +++ b/providers/FoliaProvider/src/main/java/net/ess3/provider/providers/FoliaSchedulingProvider.java @@ -115,7 +115,7 @@ public void runAsyncTaskLater(Runnable runnable, long delay) { @Override public EssentialsTask runAsyncTaskRepeating(Runnable runnable, long delay, long period) { - final ScheduledTask task = plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, delay * 50, TimeUnit.MICROSECONDS); + final ScheduledTask task = plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, period * 50, TimeUnit.MILLISECONDS); return task::cancel; } From 4256909eee82fca4c0675edda01723dacf2e3a63 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Wed, 26 Apr 2023 21:28:33 -0400 Subject: [PATCH 17/21] Fix folia init tasks never getting called LOLW --- .../src/main/java/com/earth2me/essentials/Essentials.java | 6 +----- .../com/earth2me/essentials/commands/Commandessentials.java | 1 + Essentials/src/main/resources/messages.properties | 1 + 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index a3477c6fce0..319245334b2 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -467,6 +467,7 @@ public void onEnable() { } execTimer.mark("Init(Providers)"); + registerListeners(getServer().getPluginManager()); reload(); // The item spawn blacklist is loaded with all other settings, before the item @@ -526,8 +527,6 @@ public void saveConfig() { } private void registerListeners(final PluginManager pm) { - HandlerList.unregisterAll(this); - if (getSettings().isDebug()) { LOGGER.log(Level.INFO, "Registering Listeners"); } @@ -629,9 +628,6 @@ public void reload() { command.setUsage(tl(commandName + "CommandUsage")); } } - - final PluginManager pm = getServer().getPluginManager(); - registerListeners(pm); } private IEssentialsCommand loadCommand(final String path, final String name, final IEssentialsModule module, final ClassLoader classLoader) throws Exception { diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java index 6fa2873afa2..3b108b2044e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandessentials.java @@ -728,6 +728,7 @@ private void runVersion(final Server server, final CommandSource sender, final S sender.sendMessage(tl(serverMessageKey, "Server", server.getBukkitVersion() + " " + server.getVersion())); sender.sendMessage(tl(serverMessageKey, "Brand", server.getName())); + sender.sendMessage(tl("versionOutputFlags", "FOLIA:" + VersionUtil.FOLIA + ",FLAT:" + VersionUtil.PRE_FLATTENING + ",SUPSTAT:" + VersionUtil.getServerSupportStatus().name())); sender.sendMessage(tl("versionOutputFine", "EssentialsX", essVer)); for (final Plugin plugin : pm.getPlugins()) { diff --git a/Essentials/src/main/resources/messages.properties b/Essentials/src/main/resources/messages.properties index 46567df00eb..526f839f4b7 100644 --- a/Essentials/src/main/resources/messages.properties +++ b/Essentials/src/main/resources/messages.properties @@ -1483,6 +1483,7 @@ versionErrorPlayer=\u00a76Error while checking EssentialsX version information! versionFetching=\u00a76Fetching version information... versionOutputVaultMissing=\u00a74Vault is not installed. Chat and permissions may not work. versionOutputFine=\u00a76{0} version: \u00a7a{1} +versionOutputFlags=\u00a76Feature Flags: \u00a7a{0} versionOutputWarn=\u00a76{0} version: \u00a7c{1} versionOutputUnsupported=\u00a7d{0} \u00a76version: \u00a7d{1} versionOutputUnsupportedPlugins=\u00a76You are running \u00a7dunsupported plugins\u00a76! From 1a108b5e2e6864197a6292e4e3c254f112c49da3 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 27 Jul 2023 19:35:45 -0400 Subject: [PATCH 18/21] Bump folia version --- providers/FoliaProvider/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/FoliaProvider/build.gradle b/providers/FoliaProvider/build.gradle index 42ae0f072b3..fe183290bd8 100644 --- a/providers/FoliaProvider/build.gradle +++ b/providers/FoliaProvider/build.gradle @@ -10,7 +10,7 @@ dependencies { implementation(project(':providers:BaseProviders')) { exclude(module: 'spigot-api') } - compileOnly 'dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT' + compileOnly 'dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT' } essentials { From d4ebaf61d4549d64b15845a1b1cb4b058e7e7687 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 27 Jul 2023 19:38:32 -0400 Subject: [PATCH 19/21] Fix weather command --- .../essentials/commands/Commandweather.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java index 1dc9b41981d..ab7de23b28a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java @@ -31,16 +31,18 @@ public void run(final Server server, final User user, final String commandLabel, isStorm = args[0].equalsIgnoreCase("storm"); } - final World world = user.getWorld(); + ess.scheduleEntityDelayedTask(user.getBase(), () -> { + final World world = user.getWorld(); - if (args.length > 1) { + if (args.length > 1) { + world.setStorm(isStorm); + world.setWeatherDuration(Integer.parseInt(args[1]) * 20); + user.sendMessage(isStorm ? tl("weatherStormFor", world.getName(), args[1]) : tl("weatherSunFor", world.getName(), args[1])); + return; + } world.setStorm(isStorm); - world.setWeatherDuration(Integer.parseInt(args[1]) * 20); - user.sendMessage(isStorm ? tl("weatherStormFor", world.getName(), args[1]) : tl("weatherSunFor", world.getName(), args[1])); - return; - } - world.setStorm(isStorm); - user.sendMessage(isStorm ? tl("weatherStorm", world.getName()) : tl("weatherSun", world.getName())); + user.sendMessage(isStorm ? tl("weatherStorm", world.getName()) : tl("weatherSun", world.getName())); + }); } @Override @@ -55,14 +57,16 @@ protected void run(final Server server, final CommandSource sender, final String throw new Exception(tl("weatherInvalidWorld", args[0])); } - if (args.length > 2) { + ess.scheduleLocationDelayedTask(world.getSpawnLocation(), () -> { + if (args.length > 2) { + world.setStorm(isStorm); + world.setWeatherDuration(Integer.parseInt(args[2]) * 20); + sender.sendMessage(isStorm ? tl("weatherStormFor", world.getName(), args[2]) : tl("weatherSunFor", world.getName(), args[2])); + return; + } world.setStorm(isStorm); - world.setWeatherDuration(Integer.parseInt(args[2]) * 20); - sender.sendMessage(isStorm ? tl("weatherStormFor", world.getName(), args[2]) : tl("weatherSunFor", world.getName(), args[2])); - return; - } - world.setStorm(isStorm); - sender.sendMessage(isStorm ? tl("weatherStorm", world.getName()) : tl("weatherSun", world.getName())); + sender.sendMessage(isStorm ? tl("weatherStorm", world.getName()) : tl("weatherSun", world.getName())); + }); } @Override From 0c8bc16c3d8433b1e3c1d40ac18f1a6044414120 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 27 Jul 2023 19:59:56 -0400 Subject: [PATCH 20/21] Fix time command --- .../earth2me/essentials/commands/Commandtime.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java index 06c86b2da8c..3537d693cf5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java @@ -81,15 +81,17 @@ public void run(final Server server, final CommandSource sender, final String co } final StringJoiner joiner = new StringJoiner(", "); + final boolean timeAdd = add; for (final World world : worlds) { - long time = world.getTime(); - if (!add) { - time -= time % 24000; - } - world.setTime(time + (add ? 0 : 24000) + timeTick); joiner.add(world.getName()); + ess.scheduleLocationDelayedTask(world.getSpawnLocation(), () -> { + long time = world.getTime(); + if (!timeAdd) { + time -= time % 24000; + } + world.setTime(time + (timeAdd ? 0 : 24000) + timeTick); + }); } - sender.sendMessage(tl(add ? "timeWorldAdd" : "timeWorldSet", DescParseTickFormat.formatTicks(timeTick), joiner.toString())); } From d73ed137fae07a27929e68cc07b512128c83caf9 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 22 Aug 2023 12:12:33 -0400 Subject: [PATCH 21/21] Fix time/weather commands --- .../main/java/com/earth2me/essentials/commands/Commandtime.java | 2 +- .../java/com/earth2me/essentials/commands/Commandweather.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java index 3537d693cf5..7e437339c90 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtime.java @@ -84,7 +84,7 @@ public void run(final Server server, final CommandSource sender, final String co final boolean timeAdd = add; for (final World world : worlds) { joiner.add(world.getName()); - ess.scheduleLocationDelayedTask(world.getSpawnLocation(), () -> { + ess.scheduleGlobalDelayedTask(() -> { long time = world.getTime(); if (!timeAdd) { time -= time % 24000; diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java index ab7de23b28a..cfcc845baa5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandweather.java @@ -31,7 +31,7 @@ public void run(final Server server, final User user, final String commandLabel, isStorm = args[0].equalsIgnoreCase("storm"); } - ess.scheduleEntityDelayedTask(user.getBase(), () -> { + ess.scheduleGlobalDelayedTask(() -> { final World world = user.getWorld(); if (args.length > 1) {