Skip to content

Commit 3683622

Browse files
v0.3.0 - Add task consumers & Better platform detection
1 parent fdab289 commit 3683622

19 files changed

Lines changed: 1002 additions & 159 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ buildscript {
77
allprojects {
88
apply plugin: 'java'
99

10-
version = '0.2.6'
10+
version = '0.3.0'
1111

1212
repositories {
1313

common/src/main/java/com/tcoded/folialib/FoliaLib.java

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package com.tcoded.folialib;
22

33
import com.tcoded.folialib.enums.ImplementationType;
4-
import com.tcoded.folialib.impl.*;
4+
import com.tcoded.folialib.impl.ServerImplementation;
55
import org.bukkit.plugin.java.JavaPlugin;
66

77
import java.lang.reflect.InvocationTargetException;
8-
import java.util.List;
98
import java.util.logging.Logger;
109

1110
public class FoliaLib {
@@ -20,39 +19,18 @@ public FoliaLib(JavaPlugin plugin) {
2019

2120
// Find the implementation type based on the class names
2221
ImplementationType foundType = ImplementationType.UNKNOWN;
23-
typeLoop:
22+
2423
for (ImplementationType type : ImplementationType.values()) {
25-
String[] classNames = type.getClassNames();
26-
27-
// Check if any of the class names are present
28-
for (String className : classNames) {
29-
try {
30-
// Try to load the class
31-
Class.forName(className);
32-
33-
// Found the server type, remember that and break the loop
34-
foundType = type;
35-
break typeLoop;
36-
} catch (ClassNotFoundException ignored) {}
37-
}
24+
// Implementation is not suited for this server
25+
if (!type.selfCheck()) continue;
26+
// Found implementation match
27+
foundType = type;
28+
break;
3829
}
3930

4031
// Apply the implementation based on the type
4132
this.implementationType = foundType;
42-
switch (foundType) {
43-
case FOLIA:
44-
this.implementation = this.createServerImpl("FoliaImplementation");
45-
break;
46-
case PAPER:
47-
this.implementation = this.createServerImpl("PaperImplementation");
48-
break;
49-
case SPIGOT:
50-
this.implementation = this.createServerImpl("SpigotImplementation");
51-
break;
52-
default:
53-
this.implementation = this.createServerImpl("UnsupportedImplementation");
54-
break;
55-
}
33+
this.implementation = this.createServerImpl(this.implementationType.getImplementationClassName());
5634

5735
// Check for valid implementation
5836
if (this.implementation == null) {
@@ -76,7 +54,7 @@ public FoliaLib(JavaPlugin plugin) {
7654
}
7755

7856
private ServerImplementation createServerImpl(String implName) {
79-
String basePackage = "com.tcoded.folialib.impl.";
57+
String basePackage = this.getClass().getPackage().getName() + ".impl.";
8058

8159
try {
8260
return (ServerImplementation) Class.forName(basePackage + implName)
Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,97 @@
11
package com.tcoded.folialib.enums;
22

3+
import com.tcoded.folialib.impl.ServerImplementation;
4+
import com.tcoded.folialib.util.ImplementationTestsUtil;
5+
6+
import java.util.function.Consumer;
7+
import java.util.function.Supplier;
8+
9+
/**
10+
* This enum is used to determine the server implementation type.
11+
* <p>
12+
* The enum is ordered by PRIORITY. The first implementation that passes all tests will be used.
13+
* <p>
14+
* A server is considered 'legacy' if it does not support task consumers. This feature was added in 1.13.2.
15+
* This means that event 1.13.1 servers are considered legacy servers as they do not support highly important
16+
* features that developers may want to use. Refer to {@link ServerImplementation#runLater(Consumer, long)}
17+
* for more information on the behavior of task consumer-enabled methods on servers which do not support this feature.
18+
*/
19+
@SuppressWarnings("SpellCheckingInspection")
320
public enum ImplementationType {
421

5-
// Ordered by priority
6-
@SuppressWarnings("SpellCheckingInspection")
7-
FOLIA ("io.papermc.paper.threadedregions.RegionizedServer"),
8-
@SuppressWarnings("SpellCheckingInspection")
9-
PAPER ("com.destroystokyo.paper.PaperConfig", "io.papermc.paper.configuration.Configuration"),
10-
@SuppressWarnings("SpellCheckingInspection")
11-
SPIGOT ("org.spigotmc.SpigotConfig"),
12-
UNKNOWN;
22+
FOLIA (
23+
"FoliaImplementation",
24+
new Supplier[0],
25+
"io.papermc.paper.threadedregions.RegionizedServer"
26+
),
27+
PAPER (
28+
"PaperImplementation",
29+
new Supplier[] {ImplementationTestsUtil::isTaskConsumersSupported},
30+
"com.destroystokyo.paper.PaperConfig", "io.papermc.paper.configuration.Configuration"
31+
),
32+
LEGACY_PAPER (
33+
"LegacyPaperImplementation",
34+
new Supplier[0],
35+
"com.destroystokyo.paper.PaperConfig", "io.papermc.paper.configuration.Configuration"
36+
),
37+
SPIGOT (
38+
"SpigotImplementation",
39+
new Supplier[] {ImplementationTestsUtil::isTaskConsumersSupported},
40+
"org.spigotmc.SpigotConfig"
41+
),
42+
LEGACY_SPIGOT (
43+
"LegacySpigotImplementation",
44+
new Supplier[0],
45+
"org.spigotmc.SpigotConfig"
46+
),
47+
UNKNOWN (
48+
"UnsupportedImplementation",
49+
new Supplier[0]
50+
);
1351

52+
private final String implementationClassName;
53+
private final Supplier<Boolean>[] tests;
1454
private final String[] classNames;
1555

16-
ImplementationType(String... classNames) {
56+
ImplementationType(String implementationClassName, Supplier<Boolean>[] tests, String... classNames) {
57+
this.implementationClassName = implementationClassName;
58+
this.tests = tests;
1759
this.classNames = classNames;
1860
}
1961

62+
public String getImplementationClassName() {
63+
return implementationClassName;
64+
}
65+
66+
public Supplier<Boolean>[] getTests() {
67+
return tests;
68+
}
69+
2070
public String[] getClassNames() {
2171
return classNames;
2272
}
73+
74+
public boolean selfCheck() {
75+
// Run self-tests
76+
for (Supplier<Boolean> test : this.getTests()) {
77+
if (!test.get()) return false;
78+
}
79+
80+
// Self-test for class names
81+
String[] classNames = this.getClassNames();
82+
83+
// Check if any of the class names are present
84+
for (String className : classNames) {
85+
try {
86+
// Try to load the class
87+
Class.forName(className);
88+
89+
// Found the server type, remember that and break the loop
90+
return true;
91+
} catch (ClassNotFoundException ignored) {}
92+
}
93+
94+
return false;
95+
}
2396
}
97+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.tcoded.folialib.util;
2+
3+
import org.bukkit.plugin.Plugin;
4+
import org.bukkit.scheduler.BukkitScheduler;
5+
import org.bukkit.scheduler.BukkitTask;
6+
7+
import java.util.function.Consumer;
8+
9+
public class ImplementationTestsUtil {
10+
11+
private static final boolean IS_CANCELLED_SUPPORTED;
12+
private static final boolean IS_TASK_CONSUMERS_SUPPORTED;
13+
14+
15+
static {
16+
boolean isCancelledSupported = false;
17+
try {
18+
Class<BukkitTask> bukkitTaskClass = BukkitTask.class;
19+
// noinspection JavaReflectionMemberAccess
20+
bukkitTaskClass.getDeclaredMethod("isCancelled");
21+
isCancelledSupported = true;
22+
} catch (NoSuchMethodException e) {
23+
// ignore
24+
}
25+
// Set class-wide
26+
IS_CANCELLED_SUPPORTED = isCancelledSupported;
27+
28+
boolean taskConsumersSupported = false;
29+
try {
30+
Class<BukkitScheduler> bukkitSchedulerClass = BukkitScheduler.class;
31+
// noinspection JavaReflectionMemberAccess
32+
bukkitSchedulerClass.getDeclaredMethod("runTask", Plugin.class, Consumer.class);
33+
taskConsumersSupported = true;
34+
} catch (NoSuchMethodException e) {
35+
// ignore
36+
}
37+
// Set class-wide
38+
IS_TASK_CONSUMERS_SUPPORTED = taskConsumersSupported;
39+
}
40+
41+
public static boolean isCancelledSupported() {
42+
return IS_CANCELLED_SUPPORTED;
43+
}
44+
45+
public static boolean isTaskConsumersSupported() {
46+
return IS_TASK_CONSUMERS_SUPPORTED;
47+
}
48+
49+
}

common/src/main/java/com/tcoded/folialib/util/TimeConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static long toTicks(long time, TimeUnit unit) {
88
return unit.toMillis(time) / 50;
99
}
1010

11-
public static long toMillis(long delay) {
12-
return delay * 50L;
11+
public static long toMillis(long ticks) {
12+
return ticks * 50L;
1313
}
1414
}

0 commit comments

Comments
 (0)