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 61d2f71..6afc9a8 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 d10fd55..b21b5fa 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 adbbf1d..1ad98a6 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 class Selection { } - 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 83b9a44..7f0cb1c 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 class Listeners implements Listener { 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 class Listeners implements Listener { 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 64dc2a9..dfa7e31 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 @@ package com.sekwah.advancedportals.bukkit.metrics; 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 class Metrics { } // 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 6435253..2ae2333 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.ByteArrayDataOutput; 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 class Portal { 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 d788dac..d711fb6 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 @@ import java.util.concurrent.TimeUnit; * 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); } }