Skip to content

Commit fd1b05d

Browse files
committed
Add Folia support via reflections to support older versions.
1 parent e6ac39a commit fd1b05d

10 files changed

Lines changed: 316 additions & 31 deletions

File tree

src/main/java/eu/decentsoftware/holograms/api/DecentHolograms.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import eu.decentsoftware.holograms.api.nms.NMS;
99
import eu.decentsoftware.holograms.api.nms.PacketListener;
1010
import eu.decentsoftware.holograms.api.listeners.PlayerListener;
11+
import eu.decentsoftware.holograms.api.utils.scheduler.SchedulerAdapter;
12+
import eu.decentsoftware.holograms.api.utils.scheduler.adapters.BukkitSchedulerAdapter;
13+
import eu.decentsoftware.holograms.api.utils.scheduler.adapters.FoliaSchedulerAdapter;
1114
import eu.decentsoftware.holograms.api.utils.BungeeUtils;
1215
import eu.decentsoftware.holograms.api.utils.Common;
1316
import eu.decentsoftware.holograms.api.utils.DExecutor;
@@ -43,6 +46,7 @@
4346
public final class DecentHolograms {
4447

4548
private final JavaPlugin plugin;
49+
private final SchedulerAdapter scheduler;
4650
private HologramManager hologramManager;
4751
private CommandManager commandManager;
4852
private FeatureManager featureManager;
@@ -57,6 +61,7 @@ public final class DecentHolograms {
5761

5862
DecentHolograms(@NonNull JavaPlugin plugin) {
5963
this.plugin = plugin;
64+
this.scheduler = FoliaSchedulerAdapter.isSupported() ? new FoliaSchedulerAdapter(plugin) : new BukkitSchedulerAdapter(plugin);
6065
}
6166

6267
/*

src/main/java/eu/decentsoftware/holograms/api/actions/ActionType.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public boolean execute(Player player, String... args) {
6666
Validate.notNull(player);
6767

6868
String string = String.join(" ", args);
69-
Bukkit.getScheduler().runTask(DECENT_HOLOGRAMS.getPlugin(), () -> {
69+
DECENT_HOLOGRAMS.getScheduler().executeAtEntity(player, () -> {
7070
//
7171
player.chat(PAPI.setPlaceholders(player, string.replace("{player}", player.getName())));
7272
});
@@ -80,7 +80,7 @@ public boolean execute(Player player, String... args) {
8080
Validate.notNull(player);
8181

8282
String string = String.join(" ", args);
83-
Bukkit.getScheduler().runTask(DECENT_HOLOGRAMS.getPlugin(), () -> {
83+
DECENT_HOLOGRAMS.getScheduler().executeAtEntity(player, () -> {
8484
//
8585
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), PAPI.setPlaceholders(player, string.replace("{player}", player.getName())));
8686
});
@@ -113,7 +113,7 @@ public boolean execute(Player player, String... args) {
113113
if (location == null) {
114114
return false;
115115
}
116-
Bukkit.getScheduler().runTask(DECENT_HOLOGRAMS.getPlugin(), () -> player.teleport(location));
116+
DECENT_HOLOGRAMS.getScheduler().executeAtEntity(player, () -> player.teleport(location));
117117
return true;
118118
}
119119
};

src/main/java/eu/decentsoftware/holograms/api/holograms/Hologram.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ public boolean show(@NonNull Player player, int pageIndex) {
639639
} else {
640640
// We need to run the task later on older versions as, if we don't, it causes issues with some holograms *randomly* becoming invisible.
641641
// I *think* this is from despawning and spawning the entities (with the same ID) in the same tick.
642-
S.sync(() -> showPageTo(player, page, pageIndex), 0L);
642+
S.sync(player, () -> showPageTo(player, page, pageIndex), 0L);
643643
}
644644
return true;
645645
}

src/main/java/eu/decentsoftware/holograms/api/utils/UpdateChecker.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package eu.decentsoftware.holograms.api.utils;
22

3+
import eu.decentsoftware.holograms.api.DecentHologramsAPI;
34
import org.apache.commons.lang.Validate;
4-
import org.bukkit.Bukkit;
55
import org.bukkit.plugin.java.JavaPlugin;
66

77
import java.io.IOException;
@@ -23,7 +23,7 @@ public UpdateChecker(JavaPlugin plugin, int resourceId) {
2323
}
2424

2525
public void getVersion(Consumer<String> consumer) {
26-
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
26+
DecentHologramsAPI.get().getScheduler().runAsync(() -> {
2727
try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + resourceId).openStream();
2828
Scanner scanner = new Scanner(inputStream)) {
2929
if (scanner.hasNext() && consumer != null) {

src/main/java/eu/decentsoftware/holograms/api/utils/scheduler/S.java

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,39 @@
33
import eu.decentsoftware.holograms.api.DecentHolograms;
44
import eu.decentsoftware.holograms.api.DecentHologramsAPI;
55
import eu.decentsoftware.holograms.api.utils.DExecutor;
6-
import org.bukkit.Bukkit;
6+
import org.bukkit.entity.Entity;
77
import org.bukkit.plugin.IllegalPluginAccessException;
88
import org.bukkit.scheduler.BukkitTask;
99

10+
import java.util.concurrent.TimeUnit;
11+
1012
public class S {
1113

1214
private static final DecentHolograms DECENT_HOLOGRAMS = DecentHologramsAPI.get();
1315

14-
public static void stopTask(int id) {
15-
Bukkit.getScheduler().cancelTask(id);
16-
}
17-
18-
public static void sync(Runnable runnable) {
19-
Bukkit.getScheduler().runTask(DECENT_HOLOGRAMS.getPlugin(), runnable);
20-
}
21-
22-
public static BukkitTask sync(Runnable runnable, long delay) {
23-
return Bukkit.getScheduler().runTaskLater(DECENT_HOLOGRAMS.getPlugin(), runnable, delay);
16+
public static void sync(Entity entity, Runnable runnable, long delay) {
17+
DECENT_HOLOGRAMS.getScheduler().runAtEntityDelayed(entity, runnable, delay);
2418
}
2519

26-
public static BukkitTask syncTask(Runnable runnable, long interval) {
27-
return Bukkit.getScheduler().runTaskTimer(DECENT_HOLOGRAMS.getPlugin(), runnable, 0, interval);
28-
}
2920

3021
public static void async(Runnable runnable) {
3122
try {
32-
Bukkit.getScheduler().runTaskAsynchronously(DECENT_HOLOGRAMS.getPlugin(), runnable);
23+
DECENT_HOLOGRAMS.getScheduler().runAsync(runnable);
3324
} catch (IllegalPluginAccessException e) {
3425
DExecutor.execute(runnable);
3526
}
3627
}
3728

3829
public static void async(Runnable runnable, long delay) {
3930
try {
40-
Bukkit.getScheduler().runTaskLaterAsynchronously(DECENT_HOLOGRAMS.getPlugin(), runnable, delay);
31+
DECENT_HOLOGRAMS.getScheduler().runAsyncDelayed(runnable, delay * 50, TimeUnit.MILLISECONDS);
4132
} catch (IllegalPluginAccessException e) {
4233
DExecutor.execute(runnable);
4334
}
4435
}
4536

46-
public static BukkitTask asyncTask(Runnable runnable, long interval) {
47-
return Bukkit.getScheduler().runTaskTimerAsynchronously(DECENT_HOLOGRAMS.getPlugin(), runnable, 0, interval);
48-
}
49-
5037
public static BukkitTask asyncTask(Runnable runnable, long interval, long delay) {
51-
return Bukkit.getScheduler().runTaskTimerAsynchronously(DECENT_HOLOGRAMS.getPlugin(), runnable, delay, interval);
38+
return DECENT_HOLOGRAMS.getScheduler().runAsyncRate(runnable, 0, interval * 50, TimeUnit.MILLISECONDS);
5239
}
5340

5441
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package eu.decentsoftware.holograms.api.utils.scheduler;
2+
3+
import org.bukkit.entity.Entity;
4+
import org.bukkit.scheduler.BukkitTask;
5+
6+
import java.util.concurrent.TimeUnit;
7+
8+
public interface SchedulerAdapter {
9+
10+
/**
11+
* Schedules the specified task to be executed asynchronously immediately.
12+
*
13+
* @param runnable The task to execute.
14+
*/
15+
void runAsync(Runnable runnable);
16+
17+
/**
18+
* Schedules the specified task to be executed asynchronously after the time delay has passed.
19+
*
20+
* @param runnable The task to execute.
21+
* @param delay The time delay to pass before the task should be executed.
22+
* @param unit The time unit for the initial delay and period.
23+
*/
24+
void runAsyncDelayed(Runnable runnable, long delay, TimeUnit unit);
25+
26+
/**
27+
* Schedules the specified task to be executed asynchronously after the delay has passed,
28+
* and then periodically executed with the specified period.
29+
*
30+
* @param runnable The task to execute.
31+
* @param delay The time delay to pass before the task should be executed.
32+
* @param period The time between task executions after the first execution of the task.
33+
* @param unit The time unit for the initial delay and period.
34+
* @return The BukkitTask that represents the scheduled task.
35+
*/
36+
BukkitTask runAsyncRate(Runnable runnable, long delay, long period, TimeUnit unit);
37+
38+
/**
39+
* Schedules a task. If the task failed to schedule because the scheduler is retired (entity removed),
40+
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
41+
* or the retired callback will be invoked if the scheduler is retired.
42+
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
43+
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
44+
*
45+
* <p>
46+
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
47+
* </p>
48+
*
49+
* @param entity The entity relative to which the scheduler is obtained.
50+
* @param runnable The task to execute.
51+
*/
52+
void executeAtEntity(Entity entity, Runnable runnable);
53+
54+
/**
55+
* Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity removed),
56+
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
57+
* or the retired callback will be invoked if the scheduler is retired.
58+
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
59+
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
60+
*
61+
* <p>
62+
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
63+
* </p>
64+
*
65+
* @param entity The entity relative to which the scheduler is obtained.
66+
* @param runnable The task to execute.
67+
* @param delay The time delay to pass before the task should be executed, in ticks.
68+
*/
69+
void runAtEntityDelayed(Entity entity, Runnable runnable, long delay);
70+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package eu.decentsoftware.holograms.api.utils.scheduler.adapters;
2+
3+
import eu.decentsoftware.holograms.api.utils.scheduler.SchedulerAdapter;
4+
import lombok.NonNull;
5+
import lombok.RequiredArgsConstructor;
6+
import org.bukkit.Bukkit;
7+
import org.bukkit.entity.Entity;
8+
import org.bukkit.plugin.Plugin;
9+
import org.bukkit.scheduler.BukkitTask;
10+
11+
import java.util.concurrent.TimeUnit;
12+
13+
@RequiredArgsConstructor
14+
public class BukkitSchedulerAdapter implements SchedulerAdapter {
15+
16+
private @NonNull Plugin plugin;
17+
18+
@Override
19+
public void runAsync(Runnable runnable) {
20+
Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable);
21+
}
22+
23+
@Override
24+
public void runAsyncDelayed(Runnable runnable, long delay, TimeUnit unit) {
25+
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, unit.toMillis(delay) / 50);
26+
}
27+
28+
@Override
29+
public BukkitTask runAsyncRate(Runnable runnable, long delay, long period, TimeUnit unit) {
30+
return Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, unit.toMillis(delay) / 50, unit.toMillis(period) / 50);
31+
}
32+
33+
@Override
34+
public void executeAtEntity(Entity entity, Runnable runnable) {
35+
Bukkit.getScheduler().runTask(plugin, runnable);
36+
}
37+
38+
@Override
39+
public void runAtEntityDelayed(Entity entity, Runnable runnable, long delay) {
40+
Bukkit.getScheduler().runTaskLater(plugin, runnable, delay);
41+
}
42+
}

0 commit comments

Comments
 (0)