9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

update upstream and add commands

This commit is contained in:
NONPLAYT
2025-01-12 20:47:03 +03:00
parent 1b38b9d986
commit df2b2cc1db
19 changed files with 403 additions and 62 deletions

View File

@@ -56,7 +56,29 @@
implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency
// Paper start
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
@@ -219,14 +_,14 @@
@@ -207,26 +_,35 @@
// Paper end - spark
}
+// DivineMC start - hide irrelevant compilation warnings
+tasks.withType<JavaCompile> {
+ val compilerArgs = options.compilerArgs
+ compilerArgs.add("-Xlint:-module")
+ compilerArgs.add("-Xlint:-removal")
+ compilerArgs.add("-Xlint:-dep-ann")
+}
+// DivineMC end - hide irrelevant compilation warnings
+
tasks.jar {
manifest {
val git = Git(rootProject.layout.projectDirectory.path)
val mcVersion = rootProject.providers.gradleProperty("mcVersion").get()
val build = System.getenv("BUILD_NUMBER") ?: null
- val buildTime = if (build != null) Instant.now() else Instant.EPOCH
+ val buildTime = Instant.now() // DivineMC - Build time to current, we dont have a build server rn
val gitHash = git.exec(providers, "rev-parse", "--short=7", "HEAD").get().trim()
val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash"
val date = git.exec(providers, "show", "-s", "--format=%ci", gitHash).get().trim() // Paper
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim() // Paper
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] DivineMC Configuration
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 90cdcb8934e28dcc51272c9b40a6d89ac5dec75e..884f86f3a8f8bcc5242a9c9f44cc09506312b8c0 100644
index b545362d99d39e1fbecf2e38ba4406e7936b9d6e..18b8405ac4de2b96ae8164fd580f9bd164b8db81 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -300,6 +300,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile boolean abnormalExit; // Paper - Improved watchdog support
public volatile Thread shutdownThread; // Paper - Improved watchdog support
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
@@ -16,7 +16,7 @@ index 90cdcb8934e28dcc51272c9b40a6d89ac5dec75e..884f86f3a8f8bcc5242a9c9f44cc0950
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public boolean lagging = false; // Purpur - Lagging threshold
@@ -472,6 +473,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -473,6 +474,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
// CraftBukkit end
this.paperConfigurations = services.paperConfigurations(); // Paper - add paper configuration files
@@ -74,7 +74,7 @@ index ee760cc9d6756c40f13fe6459725dcfc200b9630..f407553fa89e85412193f617d01f2e36
}
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 3d91240015ad8f464283da03bd45beba90cf2b89..4aef0ac69817b85c5f8db94424dbc60f969153bf 100644
index f6f90b69a0fe21ab9689b74b22cec272c63425fd..2d38e8a31ae290b41b05e152481199a5ed9a49d2 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -221,6 +221,10 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -89,7 +89,7 @@ index 3d91240015ad8f464283da03bd45beba90cf2b89..4aef0ac69817b85c5f8db94424dbc60f
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
if (this.convertOldUsers()) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 5e730cdde960603d5fa0fa7d1b70ec56c4fa8145..b6d339bc7f8f14d762c1083a9818bde6b9bcf9a1 100644
index b29a421c67ce9889af32e5c049c9bc6a6d640df0..6be5095aa7d57f0c4034f9375453a882d3736fd4 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -591,7 +591,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe

View File

@@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 Jan 2025 16:55:31 +0300
Subject: [PATCH] temporary fix for purpur build failure
diff --git a/net/minecraft/world/level/block/EndGatewayBlock.java b/net/minecraft/world/level/block/EndGatewayBlock.java
index 017bc4fda1a43e74acf77860916309ca7a4b0b10..54abeb142e119edd1c1d1c263821b95b1f05c388 100644
--- a/net/minecraft/world/level/block/EndGatewayBlock.java
+++ b/net/minecraft/world/level/block/EndGatewayBlock.java
@@ -100,7 +100,7 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal {
// Paper end - call EntityPortalEnterEvent
// Purpur start - Add EntityTeleportHinderedEvent
if (level.purpurConfig.imposeTeleportRestrictionsOnGateways && (entity.isVehicle() || entity.isPassenger())) {
- if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY).callEvent()) {
return;
}
}
diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java
index a229bf06e34305db5b8aa81bc26b47bfb7d79c5c..7e60bcadd2d343e00fc554dba0b85c9191f7efb6 100644
--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -60,7 +60,7 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
if (entity.canUsePortal(false)) {
// Purpur start - Add EntityTeleportHinderedEvent
if (level.purpurConfig.imposeTeleportRestrictionsOnEndPortals && (entity.isVehicle() || entity.isPassenger())) {
- if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) {
+ if (!new org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent(entity.getBukkitEntity(), entity.isPassenger() ? org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_PASSENGER : org.purpurmc.purpur.event.entity.EntityTeleportHinderedEvent.Reason.IS_VEHICLE, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL).callEvent()) {
return;
}
}

View File

@@ -1,5 +1,13 @@
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -231,6 +_,7 @@
org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread
thread.start(); // Paper - Enhance console tab completions for brigadier commands; start console thread after MinecraftServer.console & PaperConfig are initialized
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
+ space.bxteam.divinemc.command.DivineCommands.registerCommands(this); // DivineMC - register commands
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
// Purpur start - Purpur config files
@@ -301,7 +_,7 @@
String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord";
String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/";

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2239,6 +_,7 @@
@@ -2240,6 +_,7 @@
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId()));
if (gameMode == GameType.SPECTATOR) {
this.removeEntitiesOnShoulder();

View File

@@ -8,7 +8,7 @@
public boolean onGround;
public boolean horizontalCollision;
public boolean verticalCollision;
@@ -1095,6 +_,12 @@
@@ -1113,6 +_,12 @@
// Paper end - detailed watchdog information
public void move(MoverType type, Vec3 movement) {
@@ -21,7 +21,7 @@
final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
// Paper start - detailed watchdog information
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main");
@@ -4214,6 +_,7 @@
@@ -4232,6 +_,7 @@
}
public final void setBoundingBox(AABB bb) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -1358,7 +_,7 @@
@@ -1377,7 +_,7 @@
player.setRealHealth(health);
}
@@ -9,7 +9,7 @@
return;
}
// CraftBukkit end
@@ -2637,6 +_,7 @@
@@ -2656,6 +_,7 @@
}
protected void updateSwingTime() {
@@ -17,7 +17,7 @@
int currentSwingDuration = this.getCurrentSwingDuration();
if (this.swinging) {
this.swingTime++;
@@ -3120,7 +_,13 @@
@@ -3139,7 +_,13 @@
}
protected float getFlyingSpeed() {
@@ -32,7 +32,7 @@
}
public float getSpeed() {
@@ -3561,6 +_,7 @@
@@ -3606,6 +_,7 @@
protected void updateFallFlying() {
this.checkSlowFallDistance();
if (!this.level().isClientSide) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -1864,6 +_,11 @@
@@ -1872,6 +_,11 @@
}
public void causeFoodExhaustion(float exhaustion, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason reason) {

View File

@@ -0,0 +1,10 @@
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
@@ -5,6 +_,7 @@
public final class CraftDefaultPermissions {
private static final String ROOT = "minecraft";
+ public static final String DIVINEMC_ROOT = "divinemc"; // DivineMC - permission root for commands
private CraftDefaultPermissions() {}

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Optimize default values for configs
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index 3b0875ed8ef29a5cede89e22e86bf90ab99d7f13..c5f0b3a31dfa851363df5f96d193c313474b192b 100644
index 31f41990623120f8de9f7c842bd8ad4f5affe59f..8f9a73f524ffaa439f0cb59eeb3de3c2ff9fac3d 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -201,7 +201,7 @@ public class PurpurConfig {
@@ -217,7 +217,7 @@ public class PurpurConfig {
laggingThreshold = getDouble("settings.lagging-threshold", laggingThreshold);
}

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Add missing purpur config options
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
index c5f0b3a31dfa851363df5f96d193c313474b192b..0eb993f2c6b8b7b59ae6995cefb0a921fd3a480a 100644
index 8f9a73f524ffaa439f0cb59eeb3de3c2ff9fac3d..3ba75f262e7477fc4d1a544599646e1d33fe31aa 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -235,6 +235,7 @@ public class PurpurConfig {
@@ -273,6 +273,7 @@ public class PurpurConfig {
}
public static int barrelRows = 3;
@@ -16,7 +16,7 @@ index c5f0b3a31dfa851363df5f96d193c313474b192b..0eb993f2c6b8b7b59ae6995cefb0a921
public static boolean enderChestSixRows = false;
public static boolean enderChestPermissionRows = false;
public static boolean cryingObsidianValidForPortalFrame = false;
@@ -265,6 +266,7 @@ public class PurpurConfig {
@@ -306,6 +307,7 @@ public class PurpurConfig {
case 1 -> 9;
default -> 27;
});
@@ -25,10 +25,10 @@ index c5f0b3a31dfa851363df5f96d193c313474b192b..0eb993f2c6b8b7b59ae6995cefb0a921
org.bukkit.event.inventory.InventoryType.ENDER_CHEST.setDefaultSize(enderChestSixRows ? 54 : 27);
enderChestPermissionRows = getBoolean("settings.blocks.ender_chest.use-permissions-for-rows", enderChestPermissionRows);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c225edee9e 100644
index 278e43c190613a0181211c160e063a514afae1ae..8203ff823587b6a282506620d0b1f6b389f0d22c 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -575,12 +575,20 @@ public class PurpurWorldConfig {
@@ -979,12 +979,20 @@ public class PurpurWorldConfig {
public boolean allayControllable = true;
public double allayMaxHealth = 20.0D;
public double allayScale = 1.0D;
@@ -49,7 +49,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
}
public boolean armadilloRidable = false;
@@ -716,6 +724,10 @@ public class PurpurWorldConfig {
@@ -1124,6 +1132,10 @@ public class PurpurWorldConfig {
public double camelMovementSpeedMin = 0.09D;
public double camelMovementSpeedMax = 0.09D;
public int camelBreedingTicks = 6000;
@@ -60,7 +60,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
private void camelSettings() {
camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater);
camelMaxHealthMin = getDouble("mobs.camel.attributes.max_health.min", camelMaxHealthMin);
@@ -725,6 +737,10 @@ public class PurpurWorldConfig {
@@ -1133,6 +1145,10 @@ public class PurpurWorldConfig {
camelMovementSpeedMin = getDouble("mobs.camel.attributes.movement_speed.min", camelMovementSpeedMin);
camelMovementSpeedMax = getDouble("mobs.camel.attributes.movement_speed.max", camelMovementSpeedMax);
camelBreedingTicks = getInt("mobs.camel.breeding-delay-ticks", camelBreedingTicks);
@@ -71,7 +71,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
}
public boolean catRidable = false;
@@ -1127,12 +1143,22 @@ public class PurpurWorldConfig {
@@ -1539,12 +1555,22 @@ public class PurpurWorldConfig {
public boolean frogControllable = true;
public float frogRidableJumpHeight = 0.65F;
public int frogBreedingTicks = 6000;
@@ -94,7 +94,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
}
public boolean ghastRidable = false;
@@ -1991,6 +2017,10 @@ public class PurpurWorldConfig {
@@ -2439,6 +2465,10 @@ public class PurpurWorldConfig {
public double snifferMaxHealth = 14.0D;
public double snifferScale = 1.0D;
public int snifferBreedingTicks = 6000;
@@ -105,7 +105,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
private void snifferSettings() {
snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable);
snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater);
@@ -1998,6 +2028,10 @@ public class PurpurWorldConfig {
@@ -2446,6 +2476,10 @@ public class PurpurWorldConfig {
snifferMaxHealth = getDouble("mobs.sniffer.attributes.max_health", snifferMaxHealth);
snifferScale = Mth.clamp(getDouble("mobs.sniffer.attributes.scale", snifferScale), 0.0625D, 16.0D);
snifferBreedingTicks = getInt("mobs.sniffer.breeding-delay-ticks", snifferBreedingTicks);
@@ -116,7 +116,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
}
public boolean squidRidable = false;
@@ -2091,10 +2125,20 @@ public class PurpurWorldConfig {
@@ -2539,10 +2573,20 @@ public class PurpurWorldConfig {
public boolean tadpoleRidable = false;
public boolean tadpoleRidableInWater = true;
public boolean tadpoleControllable = true;
@@ -137,7 +137,7 @@ index f52cbfa21b9df10f30216138585218074a495f8a..0be19a242561e58792c2614f2a9c12c2
}
public boolean traderLlamaRidable = false;
@@ -2278,10 +2322,20 @@ public class PurpurWorldConfig {
@@ -2730,10 +2774,20 @@ public class PurpurWorldConfig {
public boolean wardenRidable = false;
public boolean wardenRidableInWater = true;
public boolean wardenControllable = true;

View File

@@ -0,0 +1,160 @@
package space.bxteam.divinemc.command;
import io.papermc.paper.command.CommandUtil;
import it.unimi.dsi.fastutil.Pair;
import net.minecraft.Util;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.Nullable;
import space.bxteam.divinemc.command.subcommands.*;
import java.util.*;
import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.newline;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
public final class DivineCommand extends Command {
public static final String COMMAND_LABEL = "divinemc";
public static final String BASE_PERM = DivineCommands.COMMAND_BASE_PERM + "." + COMMAND_LABEL;
private static final Permission basePermission = new Permission(BASE_PERM, PermissionDefault.TRUE);
private static final DivineSubCommand RELOAD_SUBCOMMAND = new ReloadCommand();
private static final DivineSubCommand VERSION_SUBCOMMAND = new VersionCommand();
private static final Map<String, DivineSubCommand> SUBCOMMANDS = Util.make(() -> {
final Map<Set<String>, DivineSubCommand> commands = new HashMap<>();
commands.put(Set.of(ReloadCommand.LITERAL_ARGUMENT), RELOAD_SUBCOMMAND);
commands.put(Set.of(VersionCommand.LITERAL_ARGUMENT), VERSION_SUBCOMMAND);
return commands.entrySet().stream()
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
});
// alias -> subcommand label
private static final Map<String, String> ALIASES = Util.make(() -> {
final Map<String, Set<String>> aliases = new HashMap<>();
aliases.put(VersionCommand.LITERAL_ARGUMENT, Set.of("ver"));
return aliases.entrySet().stream()
.flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
});
private String createUsageMessage(Collection<String> arguments) {
return "/" + COMMAND_LABEL + " [" + String.join(" | ", arguments) + "]";
}
public DivineCommand() {
super(COMMAND_LABEL);
this.description = "DivineMC related commands";
this.usageMessage = this.createUsageMessage(SUBCOMMANDS.keySet());
final List<Permission> permissions = SUBCOMMANDS.values().stream().map(DivineSubCommand::getPermission).filter(Objects::nonNull).toList();
this.setPermission(BASE_PERM);
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
pluginManager.addPermission(basePermission);
for (final Permission permission : permissions) {
pluginManager.addPermission(permission);
}
}
@Override
public List<String> tabComplete(
final CommandSender sender,
final String alias,
final String[] args,
final @Nullable Location location
) throws IllegalArgumentException {
if (args.length <= 1) {
List<String> subCommandArguments = new ArrayList<>(SUBCOMMANDS.size());
for (Map.Entry<String, DivineSubCommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
if (subCommandEntry.getValue().testPermission(sender)) {
subCommandArguments.add(subCommandEntry.getKey());
}
}
return CommandUtil.getListMatchingLast(sender, args, subCommandArguments);
}
final @Nullable Pair<String, DivineSubCommand> subCommand = resolveCommand(args[0]);
if (subCommand != null && subCommand.second().testPermission(sender)) {
return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length));
}
return Collections.emptyList();
}
private boolean testHasOnePermission(CommandSender sender) {
for (Map.Entry<String, DivineSubCommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
if (subCommandEntry.getValue().testPermission(sender)) {
return true;
}
}
return false;
}
@Override
public boolean execute(
final CommandSender sender,
final String commandLabel,
final String[] args
) {
// Check if the sender has the base permission and at least one specific permission
if (!sender.hasPermission(basePermission) || !this.testHasOnePermission(sender)) {
sender.sendMessage(Bukkit.permissionMessage());
return true;
}
// Determine the usage message with the subcommands they can perform
List<String> subCommandArguments = new ArrayList<>(SUBCOMMANDS.size());
for (Map.Entry<String, DivineSubCommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
if (subCommandEntry.getValue().testPermission(sender)) {
subCommandArguments.add(subCommandEntry.getKey());
}
}
String specificUsageMessage = this.createUsageMessage(subCommandArguments);
// If they did not give a subcommand
if (args.length == 0) {
sender.sendMessage(newline().append(text("Command usage: " + specificUsageMessage, GRAY)));
return false;
}
// If they do not have permission for the subcommand they gave, or the argument is not a valid subcommand
final @Nullable Pair<String, DivineSubCommand> subCommand = resolveCommand(args[0]);
if (subCommand == null || !subCommand.second().testPermission(sender)) {
sender.sendMessage(text("Usage: " + specificUsageMessage, RED));
return false;
}
// Execute the subcommand
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
}
private static @Nullable Pair<String, DivineSubCommand> resolveCommand(String label) {
label = label.toLowerCase(Locale.ENGLISH);
@Nullable DivineSubCommand subCommand = SUBCOMMANDS.get(label);
if (subCommand == null) {
final @Nullable String command = ALIASES.get(label);
if (command != null) {
label = command;
subCommand = SUBCOMMANDS.get(command);
}
}
if (subCommand != null) {
return Pair.of(label, subCommand);
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
package space.bxteam.divinemc.command;
import net.minecraft.server.MinecraftServer;
import org.bukkit.command.Command;
import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import java.util.HashMap;
import java.util.Map;
@DefaultQualifier(NonNull.class)
public final class DivineCommands {
public static final String COMMAND_BASE_PERM = CraftDefaultPermissions.DIVINEMC_ROOT + ".command";
private DivineCommands() {}
private static final Map<String, Command> COMMANDS = new HashMap<>();
static {
COMMANDS.put(DivineCommand.COMMAND_LABEL, new DivineCommand());
}
public static void registerCommands(final MinecraftServer server) {
COMMANDS.forEach((s, command) -> {
server.server.getCommandMap().register(s, "DivineMC", command);
});
}
}

View File

@@ -0,0 +1,23 @@
package space.bxteam.divinemc.command;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
@DefaultQualifier(NonNull.class)
public interface DivineSubCommand {
boolean execute(CommandSender sender, String subCommand, String[] args);
default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
return Collections.emptyList();
}
boolean testPermission(CommandSender sender);
@Nullable Permission getPermission();
}

View File

@@ -0,0 +1,28 @@
package space.bxteam.divinemc.command;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.jetbrains.annotations.Nullable;
public abstract class DivineSubCommandPermission implements DivineSubCommand {
public final Permission permission;
protected DivineSubCommandPermission(Permission permission) {
this.permission = permission;
}
protected DivineSubCommandPermission(String permission, PermissionDefault permissionDefault) {
this(new Permission(permission, permissionDefault));
}
@Override
public boolean testPermission(CommandSender sender) {
return sender.hasPermission(this.permission);
}
@Override
public @Nullable Permission getPermission() {
return this.permission;
}
}

View File

@@ -0,0 +1,39 @@
package space.bxteam.divinemc.command.subcommands;
import net.minecraft.server.MinecraftServer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.permissions.PermissionDefault;
import space.bxteam.divinemc.command.DivineCommand;
import space.bxteam.divinemc.command.DivineSubCommandPermission;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
public final class ReloadCommand extends DivineSubCommandPermission {
public final static String LITERAL_ARGUMENT = "reload";
public static final String PERM = DivineCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
public ReloadCommand() {
super(PERM, PermissionDefault.OP);
}
@Override
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
this.doReload(sender);
return true;
}
private void doReload(final CommandSender sender) {
Command.broadcastCommandMessage(sender, text("Please note that this command is not supported and may cause issues.", RED));
Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED));
MinecraftServer server = ((CraftServer) sender.getServer()).getServer();
server.divineConfigurations.reloadConfigs(server);
server.server.reloadCount++;
Command.broadcastCommandMessage(sender, text("DivineMC config reload complete.", GREEN));
}
}

View File

@@ -0,0 +1,35 @@
package space.bxteam.divinemc.command.subcommands;
import net.minecraft.server.MinecraftServer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.PermissionDefault;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.jetbrains.annotations.Nullable;
import space.bxteam.divinemc.command.DivineCommand;
import space.bxteam.divinemc.command.DivineSubCommandPermission;
@DefaultQualifier(NonNull.class)
public final class VersionCommand extends DivineSubCommandPermission {
public final static String LITERAL_ARGUMENT = "version";
public static final String PERM = DivineCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
public VersionCommand() {
super(PERM, PermissionDefault.TRUE);
}
@Override
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
if (ver != null) {
ver.execute(sender, DivineCommand.COMMAND_LABEL, new String[0]);
}
return true;
}
@Override
public boolean testPermission(CommandSender sender) {
return super.testPermission(sender) && sender.hasPermission("bukkit.command.version");
}
}

View File

@@ -2,7 +2,7 @@ group = space.bxteam.divinemc
mcVersion = 1.21.4
version = 1.21.4-R0.1-SNAPSHOT
purpurRef = 4b00f67e399eb4decafe5e4fcf559bc04ee1d8f4
purpurRef = a4e8b4d70b42fbecd7dc4ea82cad847f6fd65282
org.gradle.configuration-cache=true
org.gradle.caching = true

View File

@@ -12,9 +12,29 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}
if (!file(".git").exists()) {
val errorText = """
=====================[ ERROR ]=====================
The DivineMC project directory is not a properly cloned Git repository.
In order to build DivineMC from source you must clone
the DivineMC repository using Git, not download a code
zip from GitHub.
Built Gale jars are available for download at
https://github.com/DivineMC/DivineMC/actions
See https://github.com/PaperMC/Paper/blob/main/CONTRIBUTING.md
for further information on building and modifying Paper forks.
===================================================
""".trimIndent()
error(errorText)
}
rootProject.name = "DivineMC"
for (name in listOf("divinemc-api", "divinemc-server", "divinemc-api-generator")) {
for (name in listOf("divinemc-api", "divinemc-server")) {
val projName = name.lowercase(Locale.ENGLISH)
include(projName)
findProject(":$projName")!!.projectDir = file(name)