Make beta implementation use Project Poseidon from Maven, default to 1 tick refresh rate to avoid lag, fix tenkumaLib ConfigurationProvider usage in Main, switch from reflection to hybrid abstraction/reflection.
This commit is contained in:
parent
d624a46703
commit
029b37db7e
9 changed files with 100 additions and 242 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -12,3 +12,4 @@ out/
|
||||||
build
|
build
|
||||||
|
|
||||||
run/
|
run/
|
||||||
|
runBeta/
|
||||||
10
.idea/jarRepositories.xml
generated
10
.idea/jarRepositories.xml
generated
|
|
@ -21,5 +21,15 @@
|
||||||
<option name="name" value="maven" />
|
<option name="name" value="maven" />
|
||||||
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
|
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven2" />
|
||||||
|
<option name="name" value="maven2" />
|
||||||
|
<option name="url" value="https://repository.johnymuffin.com/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="maven2" />
|
||||||
|
<option name="name" value="maven2" />
|
||||||
|
<option name="url" value="https://repository.johnymuffin.com/repository/maven-releases/" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -9,6 +9,7 @@ version = System.getenv("TKEEPER_VERSION_NAME") ?: "unknown"
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
|
maven("https://repository.johnymuffin.com/repository/maven-releases/")
|
||||||
flatDir {
|
flatDir {
|
||||||
dirs("libs")
|
dirs("libs")
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +67,7 @@ mcVersions.forEach { ver ->
|
||||||
dependencies {
|
dependencies {
|
||||||
add("compileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
add("compileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||||
add("modernCompileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
add("modernCompileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||||
add("legacyCompileOnly", files("libs/tenkumaLib/libs/craftbukkit-1060.jar"))
|
add("legacyImplementation", "com.legacyminecraft.poseidon:poseidon-craftbukkit:1.1.12-260503-0121-a9af58a")
|
||||||
|
|
||||||
compileOnly(project(":tenkumaLib"))
|
compileOnly(project(":tenkumaLib"))
|
||||||
|
|
||||||
|
|
@ -76,7 +77,6 @@ dependencies {
|
||||||
testImplementation("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
testImplementation("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||||
testImplementation("com.github.seeseemelk:MockBukkit-v1.21:3.102.0")
|
testImplementation("com.github.seeseemelk:MockBukkit-v1.21:3.102.0")
|
||||||
|
|
||||||
// Allow tests to see the versioned implementations
|
|
||||||
mcVersions.forEach { ver ->
|
mcVersions.forEach { ver ->
|
||||||
testImplementation(sourceSets[ver].output)
|
testImplementation(sourceSets[ver].output)
|
||||||
}
|
}
|
||||||
|
|
@ -111,26 +111,26 @@ tasks.register("buildAll") {
|
||||||
dependsOn(tasks.withType<Jar>())
|
dependsOn(tasks.withType<Jar>())
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Jar>("bundleAll") {
|
//tasks.register<Jar>("bundleAll") {
|
||||||
dependsOn(configurations.runtimeClasspath)
|
// dependsOn(configurations.runtimeClasspath)
|
||||||
|
//
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
// duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
//
|
||||||
from(sourceSets["main"].output)
|
// from(sourceSets["main"].output)
|
||||||
|
//
|
||||||
mcVersions.forEach { ver ->
|
// mcVersions.forEach { ver ->
|
||||||
from(sourceSets[ver].output)
|
// from(sourceSets[ver].output)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
from({
|
// from({
|
||||||
configurations.runtimeClasspath.get()
|
// configurations.runtimeClasspath.get()
|
||||||
.filter { it.name.endsWith("jar") }
|
// .filter { it.name.endsWith("jar") }
|
||||||
.map { zipTree(it) }
|
// .map { zipTree(it) }
|
||||||
})
|
// })
|
||||||
|
//
|
||||||
archiveClassifier.set("all-implementations")
|
// archiveClassifier.set("all-implementations")
|
||||||
archiveVersion.set(project.version.toString())
|
// archiveVersion.set(project.version.toString())
|
||||||
}
|
//}
|
||||||
|
|
||||||
/* ----------------------------------------- */
|
/* ----------------------------------------- */
|
||||||
/* JAVA SETTINGS */
|
/* JAVA SETTINGS */
|
||||||
|
|
@ -151,14 +151,34 @@ tasks.withType<JavaCompile> {
|
||||||
tasks.runServer {
|
tasks.runServer {
|
||||||
minecraftVersion("1.21")
|
minecraftVersion("1.21")
|
||||||
|
|
||||||
val bundleAll = tasks.named<Jar>("bundleAll")
|
val modern = tasks.named<Jar>("jarModern")
|
||||||
val tLibBundleAll = project(":tenkumaLib").tasks.named<Jar>("bundleAll")
|
val tLibBundleAll = project(":tenkumaLib").tasks.named<Jar>("bundleAll")
|
||||||
|
|
||||||
dependsOn(bundleAll)
|
dependsOn(modern)
|
||||||
dependsOn(tLibBundleAll)
|
dependsOn(tLibBundleAll)
|
||||||
|
|
||||||
pluginJars(
|
pluginJars(
|
||||||
bundleAll.flatMap { it.archiveFile },
|
modern.flatMap { it.archiveFile },
|
||||||
tLibBundleAll.flatMap { it.archiveFile }
|
tLibBundleAll.flatMap { it.archiveFile }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.register<Copy>("copyLegacyPlugin") {
|
||||||
|
from(project(":tenkumaLib").tasks.named<Jar>("bundleAll"))
|
||||||
|
from(tasks.named<Jar>("jarLegacy"))
|
||||||
|
into("runBeta/plugins")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<JavaExec>("runBetaServer") {
|
||||||
|
group = "verification"
|
||||||
|
description = "Runs the beta server with legacy TimeKeeper."
|
||||||
|
|
||||||
|
dependsOn("copyLegacyPlugin")
|
||||||
|
|
||||||
|
jvmArgs = listOf("-Djline.terminal=jline.UnsupportedTerminal", "-Dfile.encoding=UTF-8", "-Djava.awt.headless=true")
|
||||||
|
classpath = files("runBeta/poseidon-craftbukkit.jar")
|
||||||
|
mainClass.set("org.bukkit.craftbukkit.Main")
|
||||||
|
workingDir = file("runBeta")
|
||||||
|
|
||||||
|
standardInput = file("/dev/null").inputStream()
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import org.bukkit.event.player.PlayerBedEnterEvent;
|
||||||
|
|
||||||
public class Events {
|
public class Events {
|
||||||
public static void onBedEnter(PlayerBedEnterEvent event) {
|
public static void onBedEnter(PlayerBedEnterEvent event) {
|
||||||
boolean isCancelled = Main.getInstance().getConfig().getBoolean("preventSleep", true);
|
boolean isCancelled = Main.getInstance().getConfigProvider().getBoolean("preventSleep", true);
|
||||||
event.setCancelled(isCancelled);
|
event.setCancelled(isCancelled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/main/java/org/adrianvictor/realtime/GlimmerFactory.java
Normal file
19
src/main/java/org/adrianvictor/realtime/GlimmerFactory.java
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.adrianvictor.realtime;
|
||||||
|
|
||||||
|
import org.adrianvictor.realtime.reflection.Glimmer;
|
||||||
|
|
||||||
|
public class GlimmerFactory {
|
||||||
|
public static Glimmer create() {
|
||||||
|
try {
|
||||||
|
return (Glimmer) Class.forName("org.adrianvictor.realtime.impl.modern.Glimmer")
|
||||||
|
.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
return (Glimmer) Class.forName("org.adrianvictor.realtime.impl.legacy.Glimmer")
|
||||||
|
.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException("Failed to instantiate Glimmer implementation", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
package org.adrianvictor.realtime;
|
package org.adrianvictor.realtime;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.adrianvictor.lib.configuration.exception.InvalidConfigurationException;
|
import org.adrianvictor.lib.configuration.exception.InvalidConfigurationException;
|
||||||
import org.adrianvictor.lib.configuration.provider.ConfigurationProvider;
|
import org.adrianvictor.lib.configuration.provider.ConfigurationProvider;
|
||||||
import org.adrianvictor.lib.file.provider.FileProvider;
|
import org.adrianvictor.lib.file.provider.FileProvider;
|
||||||
import org.adrianvictor.realtime.reflection.VersionMatcher;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
public class Main extends JavaPlugin {
|
public class Main extends JavaPlugin {
|
||||||
ConfigurationProvider config;
|
ConfigurationProvider config;
|
||||||
static JavaPlugin plugin;
|
static Main plugin;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
|
@ -22,19 +23,22 @@ public class Main extends JavaPlugin {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin = this;
|
plugin = this;
|
||||||
config = ConfigurationProvider.get();
|
config = ConfigurationProvider.get();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config.load(new File(getDataFolder(), "config.yml"));
|
File configFile = new File(getDataFolder(), "config.yml");
|
||||||
|
String configString = Files.readString(Path.of(configFile.getPath()));
|
||||||
|
config.load(configString);
|
||||||
} catch (IOException | InvalidConfigurationException e) {
|
} catch (IOException | InvalidConfigurationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
new VersionMatcher().loadGlim().onStart();
|
GlimmerFactory.create().onStart();
|
||||||
|
|
||||||
int ticksBetweenUpdate = config.getInt("ticksBetweenUpdate", 20);
|
int ticksBetweenUpdate = config.getInt("ticksBetweenUpdate", 20);
|
||||||
List<String> worlds = config.getStringList("worlds", null);
|
List<String> worlds = config.getStringList("worlds", List.of("world"));
|
||||||
ZoneId zone = ZoneId.of(config.getString("timezone", ZoneId.systemDefault().toString()));
|
ZoneId zone = ZoneId.of(config.getString("timezone", ZoneId.systemDefault().toString()));
|
||||||
|
|
||||||
Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(
|
Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(
|
||||||
|
|
@ -45,7 +49,7 @@ public class Main extends JavaPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JavaPlugin getInstance() {
|
public static Main getInstance() {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.adrianvictor.realtime;
|
package org.adrianvictor.realtime;
|
||||||
|
|
||||||
|
import org.adrianvictor.lib.logging.provider.LoggerProvider;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
|
@ -21,18 +22,23 @@ public class Runnable implements java.lang.Runnable {
|
||||||
for (String worldName : worlds) {
|
for (String worldName : worlds) {
|
||||||
World world = Bukkit.getServer().getWorld(worldName);
|
World world = Bukkit.getServer().getWorld(worldName);
|
||||||
if (world == null) {
|
if (world == null) {
|
||||||
// log.severe("World " + worldName + " specified in the config was not found, removing it.");
|
LoggerProvider.get().info("World " + worldName + " specified in the config was not found, removing it.");
|
||||||
worlds.remove(worldName);
|
worlds.remove(worldName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ZonedDateTime time = ZonedDateTime.now(zone);
|
ZonedDateTime time = ZonedDateTime.now(zone);
|
||||||
int hour = time.getHour();
|
int hour = time.getHour();
|
||||||
int minute = time.getMinute();
|
int minute = time.getMinute();
|
||||||
long minecraftTime = (hour * 1000 + minute * 100 / 6 - 6000) % 24000;
|
|
||||||
if (minecraftTime < 0) {
|
// Minecraft time: 0 is 6:00 AM. 18000 is Midnight (0:00).
|
||||||
minecraftTime = minecraftTime * 2;
|
// (hour * 1000) + (minute * 1000 / 60) gives time in ticks from 0:00.
|
||||||
}
|
// Subtract 6000 to align 6:00 AM with 0 ticks.
|
||||||
world.setTime(minecraftTime);
|
long ticksSinceMidnight = (hour * 1000L) + (minute * 1000L / 60L);
|
||||||
|
long minecraftTime = (ticksSinceMidnight - 6000L + 24000L) % 24000L;
|
||||||
|
|
||||||
|
long currentFullTime = world.getFullTime();
|
||||||
|
long day = currentFullTime / 24000L;
|
||||||
|
world.setFullTime(day * 24000L + minecraftTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
||||||
package org.adrianvictor.realtime.reflection;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class VersionMatcher {
|
|
||||||
|
|
||||||
public VersionMatcher() {}
|
|
||||||
|
|
||||||
private record Entry(String pattern, String classSuffix) {}
|
|
||||||
|
|
||||||
public String getVersion(String type, String serverVersion) {
|
|
||||||
if (type == null || serverVersion == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, List<Entry>> map = populateMap();
|
|
||||||
List<Entry> entries = map.get(type.toLowerCase());
|
|
||||||
if (entries == null || entries.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entry e : entries) {
|
|
||||||
if (safeMatches(e.pattern, serverVersion)) {
|
|
||||||
return e.pattern + "|" + e.classSuffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entry> sorted = new ArrayList<>(entries);
|
|
||||||
Collections.sort(sorted, (a, b) -> compareVersions(a.pattern, b.pattern));
|
|
||||||
|
|
||||||
Entry oldest = sorted.get(0);
|
|
||||||
Entry newest = sorted.get(sorted.size() - 1);
|
|
||||||
|
|
||||||
int cmpOldest = compareVersions(serverVersion, oldest.pattern);
|
|
||||||
int cmpNewest = compareVersions(serverVersion, newest.pattern);
|
|
||||||
|
|
||||||
if (cmpOldest < 0) {
|
|
||||||
return oldest.pattern + "|" + oldest.classSuffix;
|
|
||||||
} else if (cmpNewest > 0) {
|
|
||||||
return newest.pattern + "|" + newest.classSuffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
// should not happen because we already tried all patterns
|
|
||||||
return newest.pattern + "|" + newest.classSuffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, List<Entry>> populateMap() {
|
|
||||||
Map<String, List<Entry>> map = new HashMap<>();
|
|
||||||
|
|
||||||
// RELEASE patterns, newest first (order does not matter for matching)
|
|
||||||
map.put("release", List.of(
|
|
||||||
new Entry("^1\\.21\\..*$", "r1_21")
|
|
||||||
));
|
|
||||||
|
|
||||||
// BETA patterns
|
|
||||||
map.put("beta", List.of(
|
|
||||||
new Entry("^1\\.7\\.3$", "b1_7_3")
|
|
||||||
));
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int compareVersions(String v1, String v2) {
|
|
||||||
String clean1 = v1.replaceAll("[^0-9.]", "");
|
|
||||||
String clean2 = v2.replaceAll("[^0-9.]", "");
|
|
||||||
|
|
||||||
String[] a1 = clean1.split("\\.");
|
|
||||||
String[] a2 = clean2.split("\\.");
|
|
||||||
|
|
||||||
int len = Math.max(a1.length, a2.length);
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
int n1 = i < a1.length ? parseInt(a1[i]) : 0;
|
|
||||||
int n2 = i < a2.length ? parseInt(a2[i]) : 0;
|
|
||||||
if (n1 != n2) {
|
|
||||||
return n1 - n2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int parseInt(String s) {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(s);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Glimmer loadGlim() {
|
|
||||||
String rawVersion = null;
|
|
||||||
try {
|
|
||||||
if (Bukkit.getServer() != null) {
|
|
||||||
rawVersion = Bukkit.getMinecraftVersion();
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodError ignored) {}
|
|
||||||
|
|
||||||
if (rawVersion == null || rawVersion.isEmpty()) {
|
|
||||||
try {
|
|
||||||
if (Bukkit.getServer() != null) {
|
|
||||||
String v = Bukkit.getVersion(); // e.g. "git-Bukkit-0.0.0-1060-... (MC: 1.7.3)"
|
|
||||||
int start = v.lastIndexOf("MC: ");
|
|
||||||
if (start != -1) {
|
|
||||||
rawVersion = v.substring(start + 4, v.length() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
|
|
||||||
if (rawVersion == null || rawVersion.isEmpty()) {
|
|
||||||
rawVersion = "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String matchInfo = getVersion("release", rawVersion);
|
|
||||||
if (matchInfo.isEmpty()) {
|
|
||||||
matchInfo = getVersion("beta", rawVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchInfo.isEmpty()) {
|
|
||||||
// Fallback to b1.7.3 if everything fails, or throw error?
|
|
||||||
Glimmer fallback = tryInstantiate("org.adrianvictor.realtime.impl.b1_7_3");
|
|
||||||
if (fallback != null) return fallback;
|
|
||||||
throw new IllegalStateException("No suitable implementation found for version " + rawVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] partsInfo = matchInfo.split("\\|");
|
|
||||||
String classSuffix = partsInfo[1];
|
|
||||||
|
|
||||||
Glimmer glimmer = tryInstantiate("org.adrianvictor.realtime.impl." + classSuffix);
|
|
||||||
if (glimmer != null) return glimmer;
|
|
||||||
|
|
||||||
// Backward search for older implementations
|
|
||||||
String[] versionParts = rawVersion.split("\\.");
|
|
||||||
int major = parseInt(versionParts[0]);
|
|
||||||
int minor = versionParts.length > 1 ? parseInt(versionParts[1]) : 0;
|
|
||||||
int patch = versionParts.length > 2 ? parseInt(versionParts[2]) : 0;
|
|
||||||
|
|
||||||
while (major >= 0) {
|
|
||||||
while (minor >= 0) {
|
|
||||||
while (patch >= 0) {
|
|
||||||
String className = String.format("org.adrianvictor.realtime.impl.r%d_%d_%d", major, minor, patch);
|
|
||||||
glimmer = tryInstantiate(className);
|
|
||||||
if (glimmer != null) return glimmer;
|
|
||||||
|
|
||||||
className = String.format("org.adrianvictor.realtime.impl.r%d_%d", major, minor);
|
|
||||||
glimmer = tryInstantiate(className);
|
|
||||||
if (glimmer != null) return glimmer;
|
|
||||||
|
|
||||||
patch--;
|
|
||||||
}
|
|
||||||
minor--;
|
|
||||||
patch = 20; // Search up to .20 patch of previous minor
|
|
||||||
}
|
|
||||||
major--;
|
|
||||||
minor = 30; // Search up to .30 minor of previous major
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNewEventSystem()) {
|
|
||||||
Glimmer modern = tryInstantiate("org.adrianvictor.realtime.impl.modern.Glimmer");
|
|
||||||
if (modern != null) return modern;
|
|
||||||
} else {
|
|
||||||
Glimmer legacy = tryInstantiate("org.adrianvictor.realtime.impl.legacy.Glimmer");
|
|
||||||
if (legacy != null) return legacy;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("No suitable implementation found for version " + rawVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isNewEventSystem() {
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.event.EventHandler");
|
|
||||||
return true;
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Glimmer tryInstantiate(String className) {
|
|
||||||
try {
|
|
||||||
Class<?> clazz = Class.forName(className, true, getClass().getClassLoader());
|
|
||||||
if (!Glimmer.class.isAssignableFrom(clazz)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (Glimmer) clazz.getDeclaredConstructor().newInstance();
|
|
||||||
} catch (ReflectiveOperationException ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean safeMatches(String expression, String against) {
|
|
||||||
String cleanPattern = expression.trim();
|
|
||||||
Pattern pattern = Pattern.compile(cleanPattern, Pattern.CASE_INSENSITIVE);
|
|
||||||
return pattern.matcher(against).matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
ticksBetweenUpdate: 0 # 20 ticks is 1 second
|
ticksBetweenUpdate: 1 # 20 ticks is 1 second, 0 lags the server
|
||||||
timezone: "America/Sao_Paulo" # comment this line to use system's default timezone
|
timezone: "America/Sao_Paulo" # comment this line to use system's default timezone
|
||||||
preventSleep: true # Players will sleep and time will sync afterwards, so it's better to disable unless you have a reason to
|
preventSleep: true # Players will sleep and time will sync afterwards, so it's better to disable unless you have a reason to
|
||||||
worlds:
|
worlds:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue