Skip to content

Commit

Permalink
Folia support
Browse files Browse the repository at this point in the history
  • Loading branch information
lucko committed Feb 9, 2024
1 parent 7fe6531 commit 6d50bcb
Show file tree
Hide file tree
Showing 8 changed files with 567 additions and 9 deletions.
13 changes: 12 additions & 1 deletion spark-bukkit/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
plugins {
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'io.papermc.paperweight.userdev' version '1.5.3'
}

tasks.withType(JavaCompile) {
options.release = 17
}

dependencies {
implementation project(':spark-common')
implementation 'net.kyori:adventure-platform-bukkit:4.3.1'
compileOnly 'com.destroystokyo.paper:paper-api:1.16.4-R0.1-SNAPSHOT'
paperweight.devBundle("dev.folia", "1.20.1-R0.1-SNAPSHOT")

// placeholders
compileOnly 'me.clip:placeholderapi:2.10.3'
Expand All @@ -28,6 +33,12 @@ processResources {
}
}

tasks {
assemble {
dependsOn reobfJar
}
}

shadowJar {
archiveFileName = "spark-${project.pluginVersion}-bukkit.jar"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@

package me.lucko.spark.bukkit;

import com.google.common.collect.ImmutableSet;

import me.lucko.spark.api.Spark;
import me.lucko.spark.bukkit.folia.FoliaScheduler;
import me.lucko.spark.bukkit.folia.FoliaTickStatistics;
import me.lucko.spark.bukkit.folia.FoliaSupport;
import me.lucko.spark.bukkit.folia.FoliaWorldInfoProvider;
import me.lucko.spark.bukkit.placeholder.SparkMVdWPlaceholders;
import me.lucko.spark.bukkit.placeholder.SparkPlaceholderApi;
import me.lucko.spark.common.SparkPlatform;
import me.lucko.spark.common.SparkPlugin;
import me.lucko.spark.common.monitor.ping.PlayerPingProvider;
import me.lucko.spark.common.monitor.tick.TickStatistics;
import me.lucko.spark.common.platform.PlatformInfo;
import me.lucko.spark.common.platform.serverconfig.ServerConfigProvider;
import me.lucko.spark.common.platform.world.WorldInfoProvider;
Expand Down Expand Up @@ -53,6 +60,7 @@
import java.util.stream.Stream;

public class BukkitSparkPlugin extends JavaPlugin implements SparkPlugin {
private BukkitSparkScheduler scheduler;
private BukkitAudiences audienceFactory;
private ThreadDumper gameThreadDumper;

Expand All @@ -62,14 +70,19 @@ public class BukkitSparkPlugin extends JavaPlugin implements SparkPlugin {

@Override
public void onEnable() {
this.scheduler = FoliaSupport.IS_ACTIVE
? new FoliaScheduler(this)
: new BukkitSparkScheduler.Basic(this);
this.audienceFactory = BukkitAudiences.create(this);
this.gameThreadDumper = new ThreadDumper.Specific(Thread.currentThread());
this.gameThreadDumper = FoliaSupport.IS_ACTIVE
? new ThreadDumper.Regex(ImmutableSet.of("Region Scheduler Thread #\\d+"))
: new ThreadDumper.Specific(Thread.currentThread());

this.platform = new SparkPlatform(this);
this.platform.enable();

// override Spigot's TPS command with our own.
if (this.platform.getConfiguration().getBoolean("overrideTpsCommand", true)) {
if (this.platform.getConfiguration().getBoolean("overrideTpsCommand", !FoliaSupport.IS_ACTIVE)) {
this.tpsCommand = (sender, command, label, args) -> {
if (!sender.hasPermission("spark") && !sender.hasPermission("spark.tps") && !sender.hasPermission("bukkit.command.tps")) {
sender.sendMessage(ChatColor.RED + "You do not have permission to use this command.");
Expand Down Expand Up @@ -142,12 +155,12 @@ public Stream<BukkitCommandSender> getCommandSenders() {

@Override
public void executeAsync(Runnable task) {
getServer().getScheduler().runTaskAsynchronously(this, task);
this.scheduler.executeAsync(task);
}

@Override
public void executeSync(Runnable task) {
getServer().getScheduler().runTask(this, task);
this.scheduler.executeSync(task);
}

@Override
Expand All @@ -162,7 +175,9 @@ public ThreadDumper getDefaultThreadDumper() {

@Override
public TickHook createTickHook() {
if (classExists("com.destroystokyo.paper.event.server.ServerTickStartEvent")) {
if (FoliaSupport.IS_ACTIVE) {
return null;
} else if (classExists("com.destroystokyo.paper.event.server.ServerTickStartEvent")) {
getLogger().info("Using Paper ServerTickStartEvent for tick monitoring");
return new PaperTickHook(this);
} else {
Expand All @@ -173,10 +188,23 @@ public TickHook createTickHook() {

@Override
public TickReporter createTickReporter() {
if (classExists("com.destroystokyo.paper.event.server.ServerTickStartEvent")) {
if (FoliaSupport.IS_ACTIVE) {
return null;
} else if (classExists("com.destroystokyo.paper.event.server.ServerTickStartEvent")) {
return new PaperTickReporter(this);
} else {
return null;
}
}

@Override
public TickStatistics createTickStatistics() {
if (FoliaSupport.IS_ACTIVE) {
getLogger().info("Using Paper 'threaded regions' for tick statistics");
return new FoliaTickStatistics(getServer());
} else {
return null;
}
return null;
}

@Override
Expand Down Expand Up @@ -210,7 +238,9 @@ public ServerConfigProvider createServerConfigProvider() {

@Override
public WorldInfoProvider createWorldInfoProvider() {
return new BukkitWorldInfoProvider(getServer());
return FoliaSupport.IS_ACTIVE
? new FoliaWorldInfoProvider(this)
: new BukkitWorldInfoProvider(getServer());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* This file is part of spark.
*
* Copyright (c) lucko (Luck) <[email protected]>
* Copyright (c) contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package me.lucko.spark.bukkit;

import org.bukkit.scheduler.BukkitScheduler;

/**
* Interface for the server scheduler on Bukkit servers.
*/
public interface BukkitSparkScheduler {

/**
* Executes the given {@link Runnable} asynchronously using the plugins scheduler.
*
* @param task the task
*/
void executeAsync(Runnable task);

/**
* Executes the given {@link Runnable} on the server/client main thread.
*
* @param task the task
*/
void executeSync(Runnable task);

/**
* Uses the {@link BukkitScheduler} for async and sync operations.
*/
@SuppressWarnings("deprecation")
final class Basic implements BukkitSparkScheduler {
private final BukkitSparkPlugin plugin;

public Basic(BukkitSparkPlugin plugin) {
this.plugin = plugin;
}

@Override
public void executeAsync(Runnable task) {
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, task);
}

@Override
public void executeSync(Runnable task) {
this.plugin.getServer().getScheduler().runTask(this.plugin, task);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of spark.
*
* Copyright (c) lucko (Luck) <[email protected]>
* Copyright (c) contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package me.lucko.spark.bukkit.folia;

import me.lucko.spark.bukkit.BukkitSparkPlugin;
import me.lucko.spark.bukkit.BukkitSparkScheduler;

import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;

/**
* Uses the {@link AsyncScheduler} for async operations,
* and the {@link GlobalRegionScheduler} for sync operations.
*/
public final class FoliaScheduler implements BukkitSparkScheduler {
private final BukkitSparkPlugin plugin;

public FoliaScheduler(BukkitSparkPlugin plugin) {
this.plugin = plugin;
}

@Override
public void executeAsync(Runnable task) {
this.plugin.getServer().getAsyncScheduler().runNow(this.plugin, t -> task.run());
}

@Override
public void executeSync(Runnable task) {
this.plugin.getServer().getGlobalRegionScheduler().execute(this.plugin, task);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* This file is part of spark.
*
* Copyright (c) lucko (Luck) <[email protected]>
* Copyright (c) contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package me.lucko.spark.bukkit.folia;

/**
* Compatibility util for Paper's threaded regions "Folia" project.
*/
public enum FoliaSupport {
;

public static final boolean IS_ACTIVE;

static {
boolean active = false;
try {
Class.forName("io.papermc.paper.threadedregions.scheduler.RegionScheduler");
active = true;
} catch (ClassNotFoundException e) {
// ignore
}
IS_ACTIVE = active;
}

}
Loading

0 comments on commit 6d50bcb

Please sign in to comment.