From 6a80b27eb4d89f63e6be4ea1946f64fb52c1c07d Mon Sep 17 00:00:00 2001 From: Sekwah Date: Tue, 18 Jul 2023 02:55:44 +0100 Subject: [PATCH] feat: add Folia support (highly experimental) Folia support may break at times, and currently they do not implement required events to handle nether portals properly, so please stick to non portal materials such as AIR, WATER or LAVA --- .github/workflows/gradle.yml | 2 +- build.gradle | 22 ++++++---- .../advancedportals/bukkit/Selection.java | 14 +++--- .../bukkit/listeners/Listeners.java | 13 ++++-- .../bukkit/metrics/Metrics.java | 8 +++- .../bukkit/portals/Portal.java | 12 ++++- .../bukkit/util/FoliaHandler.java | 44 +++++++++++++++++-- 7 files changed, 91 insertions(+), 24 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 61d2f71b..6afc9a8c 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -25,7 +25,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 8 + java-version: 17 - name: Use Node.js 12.x uses: actions/setup-node@v2 with: diff --git a/build.gradle b/build.gradle index d10fd550..b21b5fab 100644 --- a/build.gradle +++ b/build.gradle @@ -145,11 +145,12 @@ task discordupload { } minecraftServerConfig { - //jarUrl.set('https://download.getbukkit.org/spigot/spigot-1.13.2.jar') - //jarUrl.set('https://download.getbukkit.org/spigot/spigot-1.20.1.jar') + // The oldest version of spigot currently supported. + //jarUrl.set('https://cdn.getbukkit.org/spigot/spigot-1.17.jar') + //jarUrl.set('https://cdn.getbukkit.org/spigot/spigot-1.20.1.jar') //jarUrl.set('https://api.papermc.io/v2/projects/paper/versions/1.13.2/builds/657/downloads/paper-1.13.2-657.jar') - jarUrl.set('https://api.papermc.io/v2/projects/paper/versions/1.20.1/builds/83/downloads/paper-1.20.1-83.jar') - //jarUrl.set('https://api.papermc.io/v2/projects/folia/versions/1.20.1/builds/10/downloads/folia-1.20.1-10.jar') + //jarUrl.set('https://api.papermc.io/v2/projects/paper/versions/1.20.1/builds/83/downloads/paper-1.20.1-83.jar') + jarUrl.set('https://api.papermc.io/v2/projects/folia/versions/1.20.1/builds/10/downloads/folia-1.20.1-10.jar') jvmArgument = ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-DIReallyKnowWhatIAmDoingISwear=true"] } @@ -268,12 +269,17 @@ task curseforge { def versions = gameVersions.findAll { it.gameVersionTypeID == gameVersionTypeID } String[] supportedVersions = [ + "1.20.1", + "1.20", + "1.19.4", + "1.19.3", + "1.19.2", + "1.19.1", + "1.19", + "1.18.2", + "1.18.1", "1.18", "1.17", - "1.16", - "1.15", - "1.14", - "1.13" ] def supportedGameVersions = versions.findAll { supportedVersions.contains(it.name) } diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/Selection.java b/src/main/java/com/sekwah/advancedportals/bukkit/Selection.java index adbbf1de..1ad98a68 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/Selection.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/Selection.java @@ -1,6 +1,9 @@ package com.sekwah.advancedportals.bukkit; import com.sekwah.advancedportals.bukkit.config.ConfigAccessor; +import com.sekwah.advancedportals.bukkit.listeners.Listeners; +import com.sekwah.advancedportals.bukkit.util.FoliaHandler; +import com.sekwah.advancedportals.bukkit.util.ForkDetector; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -133,11 +136,12 @@ public static void show(final Player player, final AdvancedPortalsPlugin plugin, } - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - public void run() { - Selection.hide(player, plugin, pos1, pos2); - } - }, timeout * 20); + Runnable hideRun = () -> Selection.hide(player, plugin, pos1, pos2); + if(ForkDetector.isFolia()) { + FoliaHandler.scheduleEntityTask(plugin, player, hideRun, 10); + } else { + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, hideRun, timeout * 20); + } } diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/listeners/Listeners.java b/src/main/java/com/sekwah/advancedportals/bukkit/listeners/Listeners.java index 83b9a445..7f0cb1c7 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/listeners/Listeners.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/listeners/Listeners.java @@ -59,12 +59,12 @@ public Listeners(AdvancedPortalsPlugin plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); int cleanPeriod = config.getConfig().getInt("CleanUpPeriod", 120); - int period = 60 * cleanPeriod; + int period = 20 * 60 * cleanPeriod; if(ForkDetector.isFolia()) { FoliaHandler.repeatingTask(plugin, new CooldownDataRemovalTask(), period); } else { plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new CooldownDataRemovalTask(), - 20L * period, 20L * period); + period, period); } } @@ -152,11 +152,18 @@ public void checkTriggerLocations(Player player, boolean useDelayed, Location... player.setMetadata(HAS_WARPED, new FixedMetadataValue(plugin, System.currentTimeMillis())); if(ForkDetector.isFolia()) { + FoliaHandler.scheduleEntityTask(plugin, player, new RemoveWarpData(player), 10); + } else { Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new RemoveWarpData(player), 10); } if (portal.getTriggers().contains(Material.LAVA)) { player.setMetadata(LAVA_WARPED, new FixedMetadataValue(plugin, System.currentTimeMillis())); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new RemoveLavaData(player), 10); + if(ForkDetector.isFolia()) { + FoliaHandler.scheduleEntityTask(plugin, player, new RemoveLavaData(player), 10); + } else { + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new RemoveLavaData(player), 10); + } + } if (portal.inPortal.contains(player.getUniqueId())) return; diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/metrics/Metrics.java b/src/main/java/com/sekwah/advancedportals/bukkit/metrics/Metrics.java index 64dc2a9d..dfa7e310 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/metrics/Metrics.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/metrics/Metrics.java @@ -3,6 +3,8 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.sekwah.advancedportals.bukkit.util.FoliaHandler; +import com.sekwah.advancedportals.bukkit.util.ForkDetector; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -173,7 +175,11 @@ public void run() { } // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) - Bukkit.getScheduler().runTask(plugin, () -> submitData()); + if(ForkDetector.isFolia()) { + FoliaHandler.runAsyncTask(plugin, () -> submitData()); + } else { + Bukkit.getScheduler().runTask(plugin, () -> submitData()); + } } }, 1000 * 60 * 5, 1000 * 60 * 30); // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java b/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java index 64352538..2ae23338 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/portals/Portal.java @@ -4,11 +4,14 @@ import com.google.common.io.ByteStreams; import com.sekwah.advancedportals.bukkit.AdvancedPortalsPlugin; import com.sekwah.advancedportals.bukkit.PluginMessages; +import com.sekwah.advancedportals.bukkit.Selection; import com.sekwah.advancedportals.bukkit.api.portaldata.PortalArg; import com.sekwah.advancedportals.bukkit.config.ConfigAccessor; import com.sekwah.advancedportals.bukkit.config.ConfigHelper; import com.sekwah.advancedportals.bukkit.destinations.Destination; import com.sekwah.advancedportals.bukkit.effects.WarpEffects; +import com.sekwah.advancedportals.bukkit.util.FoliaHandler; +import com.sekwah.advancedportals.bukkit.util.ForkDetector; import com.sekwah.advancedportals.bungee.BungeeMessages; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; @@ -541,9 +544,14 @@ public static boolean activate(Player player, AdvancedPortal portal, boolean doK if(portal.hasArg("leavedesti")) { player.setMetadata("leaveDesti", new FixedMetadataValue(plugin, portal.getArg("leavedesti"))); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { + Runnable removeMeta = () -> { player.removeMetadata("leaveDesti", plugin); - }, 20 * 10); + }; + if(ForkDetector.isFolia()) { + FoliaHandler.scheduleEntityTask(plugin, player, removeMeta, 20 * 10); + } else { + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, removeMeta, 20 * 10); + } } if (portal.getDestinations().length != 0) { diff --git a/src/main/java/com/sekwah/advancedportals/bukkit/util/FoliaHandler.java b/src/main/java/com/sekwah/advancedportals/bukkit/util/FoliaHandler.java index d788dacd..d711fb6f 100644 --- a/src/main/java/com/sekwah/advancedportals/bukkit/util/FoliaHandler.java +++ b/src/main/java/com/sekwah/advancedportals/bukkit/util/FoliaHandler.java @@ -1,7 +1,8 @@ package com.sekwah.advancedportals.bukkit.util; import com.sekwah.advancedportals.bukkit.AdvancedPortalsPlugin; -import com.sekwah.advancedportals.bukkit.listeners.Listeners; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; import java.util.concurrent.TimeUnit; @@ -9,9 +10,44 @@ * This is to stop jars such as spigot complaining about folia imports */ public class FoliaHandler { - public static void repeatingTask(AdvancedPortalsPlugin plugin, Runnable runnable, int seconds) { - plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, (task) -> { + public static void repeatingTask(AdvancedPortalsPlugin plugin, Runnable runnable, int ticks) { + plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> { runnable.run(); - }, seconds, seconds, TimeUnit.SECONDS); + }, ticks, ticks); + } + + public static void scheduleTask(AdvancedPortalsPlugin plugin, Runnable runnable, int ticks) { + plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, (task) -> { + runnable.run(); + }, ticks); + } + + public static void scheduleAsyncTask(Plugin plugin, Runnable runnable, int ticks) { + plugin.getServer().getAsyncScheduler().runDelayed(plugin, (task) -> { + runnable.run(); + }, ticks * 1000L / 20L, TimeUnit.MILLISECONDS); + } + + public static void runAsyncTask(Plugin plugin, Runnable runnable) { + plugin.getServer().getAsyncScheduler().runNow(plugin, (task) -> { + runnable.run(); + }); + } + + + /** + * Will run if the entity isn't destroyed, if you want to run something different in that case also supply a retired runnable. + * @param plugin + * @param entity + * @param runnable + * @param ticks + */ + public static void scheduleEntityTask(Plugin plugin, Entity entity, Runnable runnable, int ticks) { + scheduleEntityTask(plugin, entity, runnable, null, ticks); + } + public static void scheduleEntityTask(Plugin plugin, Entity entity, Runnable runnable, Runnable retired, int ticks) { + entity.getScheduler().runDelayed(plugin, (task) -> { + runnable.run(); + }, retired, ticks); } }