Add Paper platform (#541)
* Add paper platform * Fix package name for Paper module * Load adventure-nbt library on paper * Add missing license header --------- Co-authored-by: Jones <admin@jonesdev.xyz>
This commit is contained in:
1 parent
2a98d4bdb0
commit
878789b2c1
9 files changed
+281
-1
No files matched your search
@@ -30,6 +30,8 @@ public enum SonarPlatform {
|
||||
pipeline -> pipeline.context("outbound_config") != null ? "outbound_config" : "encoder"),
|
||||
BUNGEE("BungeeCord", 19109, "inbound-boss",
|
||||
pipeline -> "packet-encoder"),
|
||||
PAPER("Paper", 19110, "packet_handler",
|
||||
pipeline -> pipeline.context("outbound_config") != null ? "outbound_config" : "encoder"),
|
||||
VELOCITY("Velocity", 19107, "handler",
|
||||
pipeline -> "minecraft-encoder");
|
||||
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ allprojects {
|
||||
tasks {
|
||||
// This is a small wrapper tasks to simplify the building process
|
||||
register("build-sonar") {
|
||||
val subprojects = listOf("api", "captcha", "common", "bukkit", "bungeecord", "velocity")
|
||||
val subprojects = listOf("api", "captcha", "common", "bukkit", "bungeecord", "paper", "velocity")
|
||||
val buildTasks = subprojects.flatMap { listOf("$it:clean", "$it:spotlessApply", "$it:shadowJar") }
|
||||
dependsOn(buildTasks)
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ class LibraryLoader {
|
||||
|
||||
// Only load adventure if not on Velocity
|
||||
if (platform != SonarPlatform.VELOCITY) {
|
||||
if (platform != SonarPlatform.PAPER) {
|
||||
libraryManager.loadLibraries(
|
||||
Library.builder()
|
||||
.groupId("net{}kyori")
|
||||
@@ -88,6 +89,17 @@ class LibraryLoader {
|
||||
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
||||
.build()
|
||||
);
|
||||
} else {
|
||||
// On Paper, we only relocate the nbt package since the rest of adventure is bundled with the server.
|
||||
libraryManager.loadLibrary(
|
||||
Library.builder()
|
||||
.groupId("net{}kyori")
|
||||
.artifactId("adventure-nbt")
|
||||
.version("4.21.0")
|
||||
.relocate("net{}kyori{}adventure{}nbt", "xyz{}jonesdev{}sonar{}libs{}kyori{}adventure{}nbt")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ shadow = "com.gradleup.shadow:8.3.8"
|
||||
spotless = "com.diffplug.spotless:7.2.1"
|
||||
pluginyml-bungee = { id = "net.minecrell.plugin-yml.bungee", version.ref = "pluginyml" }
|
||||
pluginyml-bukkit = { id = "net.minecrell.plugin-yml.bukkit", version.ref = "pluginyml" }
|
||||
pluginyml-paper = { id = "net.minecrell.plugin-yml.paper", version.ref = "pluginyml" }
|
||||
|
||||
[libraries]
|
||||
netty = { module = "io.netty:netty-all", version.ref = "netty" }
|
||||
@@ -23,6 +24,7 @@ adventure-platform-bungee = { module = "net.kyori:adventure-platform-bungeecord"
|
||||
libby-core = { module = "com.alessiodp.libby:libby-core", version.ref = "libby" }
|
||||
libby-bungee = { module = "com.alessiodp.libby:libby-bungee", version.ref = "libby" }
|
||||
libby-bukkit = { module = "com.alessiodp.libby:libby-bukkit", version.ref = "libby" }
|
||||
libby-paper = { module = "com.alessiodp.libby:libby-paper", version.ref = "libby" }
|
||||
libby-velocity = { module = "com.alessiodp.libby:libby-velocity", version.ref = "libby" }
|
||||
bstats-bungee = { module = "org.bstats:bstats-bungeecord", version.ref = "bstats" }
|
||||
bstats-bukkit = { module = "org.bstats:bstats-bukkit", version.ref = "bstats" }
|
||||
@@ -35,5 +37,6 @@ ormlite = "com.j256.ormlite:ormlite-jdbc:6.1"
|
||||
lombok = "org.projectlombok:lombok:1.18.42"
|
||||
bungeecord = "net.md-5:bungeecord-proxy:1.21-SNAPSHOT"
|
||||
velocity = "io.papermc.velocity:velocity-proxy:3.4.0-SNAPSHOT"
|
||||
paper = "io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT"
|
||||
# We have to use 1.16.5 for backwards compatibility
|
||||
spigot = "org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT"
|
||||
@@ -0,0 +1,52 @@
|
||||
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.pluginyml.paper) apply true
|
||||
}
|
||||
|
||||
paper {
|
||||
name = rootProject.name
|
||||
main = "xyz.jonesdev.sonar.paper.SonarPaperPlugin"
|
||||
authors = listOf("Jones Development", "Sonar Contributors")
|
||||
website = "https://jonesdev.xyz/discord/"
|
||||
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
|
||||
apiVersion = "1.21" // ignore legacy plugin warning
|
||||
foliaSupported = true
|
||||
|
||||
serverDependencies {
|
||||
listOf("Geyser-Spigot", "floodgate", "Protocolize", "ProtocolSupport",
|
||||
"ViaVersion", "packetevents", "ProtocolLib", "FastLogin").forEach {
|
||||
register(it) {
|
||||
required = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
// Modern Paper requires Java 21
|
||||
java.sourceCompatibility = JavaVersion.VERSION_21
|
||||
java.targetCompatibility = JavaVersion.VERSION_21
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven(url = "https://repo.papermc.io/repository/maven-public/") // Paper
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":api"))
|
||||
implementation(project(":common"))
|
||||
implementation(project(":bukkit"))
|
||||
|
||||
compileOnly(rootProject.libs.paper)
|
||||
|
||||
implementation(rootProject.libs.bstats.bukkit)
|
||||
implementation(rootProject.libs.libby.paper)
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
relocate("net.kyori.adventure.nbt", "xyz.jonesdev.sonar.libs.kyori.adventure.nbt")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Sonar 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jonesdev.sonar.paper;
|
||||
|
||||
import com.alessiodp.libby.PaperLibraryManager;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xyz.jonesdev.sonar.paper.command.PaperSonarCommand;
|
||||
import xyz.jonesdev.sonar.api.SonarPlatform;
|
||||
import xyz.jonesdev.sonar.api.logger.LoggerWrapper;
|
||||
import xyz.jonesdev.sonar.bukkit.SonarBukkit;
|
||||
import xyz.jonesdev.sonar.bukkit.antibot.BukkitInjector;
|
||||
import xyz.jonesdev.sonar.bukkit.listener.BukkitJoinListener;
|
||||
import xyz.jonesdev.sonar.common.boot.SonarBootstrap;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public final class SonarPaper extends SonarBootstrap<SonarPaperPlugin> {
|
||||
private final LoggerWrapper logger = new LoggerWrapper() {
|
||||
|
||||
@Override
|
||||
public void info(final String message, final Object... args) {
|
||||
getPlugin().getLogger().info(buildFullMessage(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(final String message, final Object... args) {
|
||||
getPlugin().getLogger().warning(buildFullMessage(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(final String message, final Object... args) {
|
||||
getPlugin().getLogger().severe(buildFullMessage(message, args));
|
||||
}
|
||||
};
|
||||
private Metrics metrics;
|
||||
|
||||
public SonarPaper(final @NotNull SonarPaperPlugin plugin) {
|
||||
super(plugin, SonarPlatform.PAPER, plugin.getDataFolder(), new PaperLibraryManager(plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Audience audience(@Nullable final UUID uniqueId) {
|
||||
if (uniqueId == null) return null;
|
||||
return Bukkit.getPlayer(uniqueId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Audience sender(@NotNull final Object object) {
|
||||
return (Audience) object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull LoggerWrapper getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
// Initialize bStats.org metrics
|
||||
metrics = new Metrics(getPlugin(), getPlatform().getMetricsId());
|
||||
|
||||
// Add charts for some configuration options
|
||||
metrics.addCustomChart(new SimplePie("verification",
|
||||
() -> getConfig().getVerification().getTiming().getDisplayName()));
|
||||
metrics.addCustomChart(new SimplePie("captcha",
|
||||
() -> getConfig().getVerification().getMap().getTiming().getDisplayName()));
|
||||
metrics.addCustomChart(new SimplePie("language",
|
||||
() -> getConfig().getLanguage().getName()));
|
||||
metrics.addCustomChart(new SimplePie("database_type",
|
||||
() -> getConfig().getDatabase().getType().getDisplayName()));
|
||||
|
||||
// Register Sonar command
|
||||
getPlugin().getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, event ->
|
||||
event.registrar().register("sonar", new PaperSonarCommand()));
|
||||
|
||||
// Try to inject into the server
|
||||
if (BukkitInjector.isLateBindEnabled()) {
|
||||
getPlugin().getServer().getScheduler().runTask(getPlugin(), BukkitInjector::inject);
|
||||
} else {
|
||||
getPlugin().getServer().getPluginManager().registerEvents(new BukkitJoinListener(), getPlugin());
|
||||
}
|
||||
|
||||
// Let the injector know that the plugin has been enabled
|
||||
SonarBukkit.INITIALIZE_LISTENER.complete(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
// Make sure to properly stop the metrics
|
||||
if (metrics != null) {
|
||||
metrics.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Sonar 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jonesdev.sonar.paper;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import xyz.jonesdev.sonar.bukkit.antibot.BukkitInjector;
|
||||
|
||||
public final class SonarPaperPlugin extends JavaPlugin {
|
||||
private SonarPaper bootstrap;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Inject early if late-bind is disabled
|
||||
if (!BukkitInjector.isLateBindEnabled()) {
|
||||
BukkitInjector.inject();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
bootstrap = new SonarPaper(this);
|
||||
bootstrap.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
bootstrap.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Sonar 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jonesdev.sonar.paper.command;
|
||||
|
||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import xyz.jonesdev.sonar.api.command.InvocationSource;
|
||||
import xyz.jonesdev.sonar.api.command.SonarCommand;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class PaperSonarCommand implements BasicCommand, SonarCommand {
|
||||
@Override
|
||||
public void execute(final CommandSourceStack commandSourceStack, final String @NonNull [] args) {
|
||||
final CommandSender sender = commandSourceStack.getSender();
|
||||
final InvocationSource invocationSource = new InvocationSource(
|
||||
sender instanceof Player ? ((Player) sender).getUniqueId() : null,
|
||||
sender,
|
||||
sender::hasPermission
|
||||
);
|
||||
handle(invocationSource, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<String> suggest(final CommandSourceStack commandSourceStack, final String @NonNull [] args) {
|
||||
// Do not allow tab completion if the player does not have the required permission
|
||||
return commandSourceStack.getSender().hasPermission("sonar.command") ?
|
||||
getCachedTabSuggestions(args) : Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ sequenceOf(
|
||||
"common",
|
||||
"bukkit",
|
||||
"bungeecord",
|
||||
"paper",
|
||||
"velocity"
|
||||
).forEach {
|
||||
include(":$it")
|
||||
|
||||
Reference in new issue
Block a user