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
+301
-21
No files matched your search
@@ -30,6 +30,8 @@ public enum SonarPlatform {
|
|||||||
pipeline -> pipeline.context("outbound_config") != null ? "outbound_config" : "encoder"),
|
pipeline -> pipeline.context("outbound_config") != null ? "outbound_config" : "encoder"),
|
||||||
BUNGEE("BungeeCord", 19109, "inbound-boss",
|
BUNGEE("BungeeCord", 19109, "inbound-boss",
|
||||||
pipeline -> "packet-encoder"),
|
pipeline -> "packet-encoder"),
|
||||||
|
PAPER("Paper", 19110, "packet_handler",
|
||||||
|
pipeline -> pipeline.context("outbound_config") != null ? "outbound_config" : "encoder"),
|
||||||
VELOCITY("Velocity", 19107, "handler",
|
VELOCITY("Velocity", 19107, "handler",
|
||||||
pipeline -> "minecraft-encoder");
|
pipeline -> "minecraft-encoder");
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ allprojects {
|
|||||||
tasks {
|
tasks {
|
||||||
// This is a small wrapper tasks to simplify the building process
|
// This is a small wrapper tasks to simplify the building process
|
||||||
register("build-sonar") {
|
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") }
|
val buildTasks = subprojects.flatMap { listOf("$it:clean", "$it:spotlessApply", "$it:shadowJar") }
|
||||||
dependsOn(buildTasks)
|
dependsOn(buildTasks)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,26 +68,38 @@ class LibraryLoader {
|
|||||||
|
|
||||||
// Only load adventure if not on Velocity
|
// Only load adventure if not on Velocity
|
||||||
if (platform != SonarPlatform.VELOCITY) {
|
if (platform != SonarPlatform.VELOCITY) {
|
||||||
libraryManager.loadLibraries(
|
if (platform != SonarPlatform.PAPER) {
|
||||||
Library.builder()
|
libraryManager.loadLibraries(
|
||||||
.groupId("net{}kyori")
|
Library.builder()
|
||||||
.artifactId("adventure-text-minimessage")
|
.groupId("net{}kyori")
|
||||||
.version("4.21.0")
|
.artifactId("adventure-text-minimessage")
|
||||||
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
.version("4.21.0")
|
||||||
.build(),
|
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
||||||
Library.builder()
|
.build(),
|
||||||
.groupId("net{}kyori")
|
Library.builder()
|
||||||
.artifactId("adventure-text-serializer-gson")
|
.groupId("net{}kyori")
|
||||||
.version("4.21.0")
|
.artifactId("adventure-text-serializer-gson")
|
||||||
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
.version("4.21.0")
|
||||||
.build(),
|
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
||||||
Library.builder()
|
.build(),
|
||||||
.groupId("net{}kyori")
|
Library.builder()
|
||||||
.artifactId("adventure-nbt")
|
.groupId("net{}kyori")
|
||||||
.version("4.21.0")
|
.artifactId("adventure-nbt")
|
||||||
.relocate("net{}kyori", "xyz{}jonesdev{}sonar{}libs{}kyori")
|
.version("4.21.0")
|
||||||
.build()
|
.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"
|
spotless = "com.diffplug.spotless:7.2.1"
|
||||||
pluginyml-bungee = { id = "net.minecrell.plugin-yml.bungee", version.ref = "pluginyml" }
|
pluginyml-bungee = { id = "net.minecrell.plugin-yml.bungee", version.ref = "pluginyml" }
|
||||||
pluginyml-bukkit = { id = "net.minecrell.plugin-yml.bukkit", 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]
|
[libraries]
|
||||||
netty = { module = "io.netty:netty-all", version.ref = "netty" }
|
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-core = { module = "com.alessiodp.libby:libby-core", version.ref = "libby" }
|
||||||
libby-bungee = { module = "com.alessiodp.libby:libby-bungee", 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-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" }
|
libby-velocity = { module = "com.alessiodp.libby:libby-velocity", version.ref = "libby" }
|
||||||
bstats-bungee = { module = "org.bstats:bstats-bungeecord", version.ref = "bstats" }
|
bstats-bungee = { module = "org.bstats:bstats-bungeecord", version.ref = "bstats" }
|
||||||
bstats-bukkit = { module = "org.bstats:bstats-bukkit", 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"
|
lombok = "org.projectlombok:lombok:1.18.42"
|
||||||
bungeecord = "net.md-5:bungeecord-proxy:1.21-SNAPSHOT"
|
bungeecord = "net.md-5:bungeecord-proxy:1.21-SNAPSHOT"
|
||||||
velocity = "io.papermc.velocity:velocity-proxy:3.4.0-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
|
# We have to use 1.16.5 for backwards compatibility
|
||||||
spigot = "org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT"
|
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",
|
"common",
|
||||||
"bukkit",
|
"bukkit",
|
||||||
"bungeecord",
|
"bungeecord",
|
||||||
|
"paper",
|
||||||
"velocity"
|
"velocity"
|
||||||
).forEach {
|
).forEach {
|
||||||
include(":$it")
|
include(":$it")
|
||||||
|
|||||||
Reference in new issue
Block a user