mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +00:00
Refactor command system, fix bugs (#573)
This commit is contained in:
@@ -6,7 +6,7 @@ Subject: [PATCH] Renewable Elytra
|
||||
This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition)
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java
|
||||
index 483b0499f1f70b3aa8862e6cd8e512748492bee0..896c6fe4ee76708f09022934056cd9de74c5e851 100644
|
||||
index 483b0499f1f70b3aa8862e6cd8e512748492bee0..5467a1b28525386dfae2a04d8c69d23f163c74f5 100644
|
||||
--- a/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -231,6 +231,20 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
@@ -20,7 +20,7 @@ index 483b0499f1f70b3aa8862e6cd8e512748492bee0..896c6fe4ee76708f09022934056cd9de
|
||||
+ if (org.leavesmc.leaves.LeavesConfig.modify.renewableElytra > 0.0D) {
|
||||
+ if (source.getEntity() instanceof Shulker && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.modify.renewableElytra) {
|
||||
+ net.minecraft.world.item.ItemStack item = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ELYTRA);
|
||||
+ item.setDamageValue(432);
|
||||
+ item.setDamageValue(431);
|
||||
+ this.spawnAtLocation(level, item);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Creative fly no clip
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..3eb9a9f6d7f8d28d527941177a5faf2c97628594 100644
|
||||
index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf6b8b480f 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -277,8 +277,8 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -37,7 +37,7 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..3eb9a9f6d7f8d28d527941177a5faf2c
|
||||
AABB aabb;
|
||||
if (this.isPassenger() && !this.getVehicle().isRemoved()) {
|
||||
aabb = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0);
|
||||
@@ -1931,6 +1931,21 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -1931,6 +1931,26 @@ public abstract class Player extends LivingEntity {
|
||||
return this.gameMode() == GameType.SPECTATOR;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,11 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..3eb9a9f6d7f8d28d527941177a5faf2c
|
||||
+ return world.isUnobstructed(state, pos, context);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCollidable(boolean ignoreClimbing) {
|
||||
+ return !isCreativeFlyOrSpectator() && super.isCollidable(ignoreClimbing);
|
||||
+ }
|
||||
+ // Leaves end - creative no clip
|
||||
+
|
||||
@Override
|
||||
|
||||
@@ -4,90 +4,94 @@ Date: Mon, 3 Feb 2025 19:16:16 +0800
|
||||
Subject: [PATCH] No block update command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index b8a9b2f5671537cf0a805dc2c98945094bd7b8b1..a2199f7aac4f44a70087dd90fe9330fcb8970772 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1789,6 +1789,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 5e54d6de0430cd137fbe13ca8f17dc487ce52ff3..a68ca4ccec97b9fc6f9a6ae698722842cb6bf42d 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -381,7 +381,7 @@ public class ServerPlayerGameMode {
|
||||
org.bukkit.block.BlockState state = bblock.getState();
|
||||
this.level.captureDrops = new java.util.ArrayList<>();
|
||||
// CraftBukkit end
|
||||
- BlockState blockState1 = block.playerWillDestroy(this.level, pos, blockState, this.player);
|
||||
+ BlockState blockState1 = org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate() ? blockState : block.playerWillDestroy(this.level, pos, blockState, this.player); // Leaves - no block update
|
||||
boolean flag = this.level.removeBlock(pos, false);
|
||||
if (flag) {
|
||||
block.destroy(this.level, pos, blockState1);
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 7c13e7b7a547150642c4a4bddf5e8dee1d580984..ac4996dda7bcf5f20391f45e3f703b21557a1669 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1089,6 +1089,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
|
||||
@Override
|
||||
public void updateNeighborsAt(BlockPos pos, Block block, @Nullable Orientation orientation) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
if (captureBlockStates) { return; } // Paper - Cancel all physics during placement
|
||||
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, block, null, orientation);
|
||||
}
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index 649d17dcd7856e3b1344192d8ea4b2e9f73fc03b..93b7c607e0f527a910fc15c88c9a0a9ede26f23d 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -482,7 +482,7 @@ public final class ItemStack implements DataComponentHolder {
|
||||
net.minecraft.world.level.block.state.BlockState block = serverLevel.getBlockState(newPos);
|
||||
public boolean setBlock(BlockPos pos, BlockState state, int flags, int recursionLeft) {
|
||||
+ // Leaves start - no block update
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) {
|
||||
+ flags = flags & ~1 | net.minecraft.world.level.block.Block.UPDATE_SKIP_ON_PLACE;
|
||||
+ }
|
||||
+ // Leaves end - no block update
|
||||
// CraftBukkit start - tree generation
|
||||
if (this.captureTreeGeneration) {
|
||||
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
@@ -1190,6 +1195,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
BlockState state = newState;
|
||||
BlockState blockState = oldState;
|
||||
BlockState blockState1 = currentState;
|
||||
+ // Leaves start - no block update
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) {
|
||||
+ flags = flags & ~1 | net.minecraft.world.level.block.Block.UPDATE_SKIP_ON_PLACE;
|
||||
+ }
|
||||
+ // Leaves end - no block update
|
||||
if (blockState1 == state) {
|
||||
if (blockState != blockState1) {
|
||||
this.setBlocksDirty(pos, blockState, blockState1);
|
||||
@@ -1208,7 +1218,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
|
||||
if (!(block.getBlock() instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Containers get placed automatically
|
||||
- block.onPlace(serverLevel, newPos, oldBlock, true, context);
|
||||
+ if (!org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) block.onPlace(serverLevel, newPos, oldBlock, true, context); // Leaves - no block update
|
||||
}
|
||||
|
||||
serverLevel.notifyAndUpdatePhysics(newPos, null, oldBlock, block, serverLevel.getBlockState(newPos), updateFlags, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // send null chunk as chunk.k() returns false by this point
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 845319dd3e355f739cce70b7df3172dd146601b1..7fca1659bd85b1a737355fb9a8377dff64a7fe17 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -413,7 +413,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
return null;
|
||||
} else {
|
||||
if (!this.level.isClientSide && (flags & 512) == 0 && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled.
|
||||
- state.onPlace(this.level, pos, blockState, flag1);
|
||||
+ if (!org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) state.onPlace(this.level, pos, blockState, flag1); // Leaves - no block update
|
||||
}
|
||||
|
||||
if (state.hasBlockEntity()) {
|
||||
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
|
||||
index ace1099a12c762b2e73b71dd3551cf351fedf067..0ccc884066b0a217c7b833c33d3fe96dd7ad0a0b 100644
|
||||
--- a/net/minecraft/world/level/material/FlowingFluid.java
|
||||
+++ b/net/minecraft/world/level/material/FlowingFluid.java
|
||||
@@ -476,6 +476,7 @@ public abstract class FlowingFluid extends Fluid {
|
||||
|
||||
@Override
|
||||
public void tick(ServerLevel level, BlockPos pos, BlockState blockState, FluidState fluidState) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
if (!fluidState.isSource()) {
|
||||
FluidState newLiquid = this.getNewLiquid(level, pos, level.getBlockState(pos));
|
||||
int spreadDelay = this.getSpreadDelay(level, pos, fluidState, newLiquid);
|
||||
diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
index 028eae2f9a459b60e92f3344091083aa93b54485..63684402f7c89c7c5d71902db4bfb23132b1d28d 100644
|
||||
--- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
+++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
||||
@@ -47,6 +47,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
|
||||
if ((flags & 16) == 0 && recursionLeft > 0) {
|
||||
int i = flags & -34;
|
||||
-
|
||||
+ // Leaves start - no block update
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) {
|
||||
+ this.updatePOIOnBlockStateChange(pos, blockState, blockState1);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - no block update
|
||||
// CraftBukkit start
|
||||
blockState.updateIndirectNeighbourShapes(this, pos, i, recursionLeft - 1); // Don't call an event for the old block to limit event spam
|
||||
boolean cancelledUpdates = false; // Paper - Fix block place logic
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
index 16aa9f5996dc6eda95541fddb01e00e41305357a..31ab92e0769aa4ce09da5073ad9b734eeebac9c5 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
@@ -105,6 +105,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
}
|
||||
|
||||
private void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates updates) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
boolean flag = this.count > 0;
|
||||
boolean flag1 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates;
|
||||
this.count++;
|
||||
diff --git a/net/minecraft/world/level/redstone/InstantNeighborUpdater.java b/net/minecraft/world/level/redstone/InstantNeighborUpdater.java
|
||||
index d0da64e325f83ab073221a3fa7284e42b6a88534..32e10dccde3e80969641ba1fb67479b5a0bada06 100644
|
||||
--- a/net/minecraft/world/level/redstone/InstantNeighborUpdater.java
|
||||
+++ b/net/minecraft/world/level/redstone/InstantNeighborUpdater.java
|
||||
@@ -16,17 +16,20 @@ public class InstantNeighborUpdater implements NeighborUpdater {
|
||||
private void checkIfExtend(Level level, BlockPos pos, BlockState state) {
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
Direction direction = state.getValue(FACING);
|
||||
boolean neighborSignal = this.getNeighborSignal(level, pos, direction);
|
||||
if (neighborSignal && !state.getValue(EXTENDED)) {
|
||||
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
index 263bf2b795057c2d5218bf9cfb684e526601aa77..da1e77ccd8805ac0cb0729720b4a1742da67d35c 100644
|
||||
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
+++ b/net/minecraft/world/level/redstone/NeighborUpdater.java
|
||||
@@ -34,6 +34,11 @@ public interface NeighborUpdater {
|
||||
static void executeShapeUpdate(
|
||||
LevelAccessor level, Direction direction, BlockPos pos, BlockPos neighborPos, BlockState neighborState, int flags, int recursionLeft
|
||||
) {
|
||||
+ // Leaves start - no block update
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) {
|
||||
+ flags = flags & ~1 | net.minecraft.world.level.block.Block.UPDATE_SKIP_ON_PLACE;
|
||||
+ }
|
||||
+ // Leaves end - no block update
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
if ((flags & 128) == 0 || !blockState.is(Blocks.REDSTONE_WIRE)) {
|
||||
BlockState blockState1 = blockState.updateShape(level, level, pos, direction, neighborPos, neighborState, level.getRandom());
|
||||
@@ -48,6 +53,7 @@ public interface NeighborUpdater {
|
||||
|
||||
@Override
|
||||
public void shapeUpdate(Direction direction, BlockState state, BlockPos pos, BlockPos neighborPos, int flags, int recursionLevel) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
NeighborUpdater.executeShapeUpdate(this.level, direction, pos, neighborPos, state, flags, recursionLevel - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockPos pos, Block neighborBlock, @Nullable Orientation orientation) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
BlockState blockState = this.level.getBlockState(pos);
|
||||
this.neighborChanged(blockState, pos, neighborBlock, orientation, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
|
||||
+ if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
NeighborUpdater.executeUpdate(this.level, state, pos, neighborBlock, orientation, movedByPiston);
|
||||
}
|
||||
}
|
||||
static void executeUpdate(Level level, BlockState state, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston, BlockPos sourcePos) {
|
||||
// Paper end - Add source block to BlockPhysicsEvent
|
||||
+ if (org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update
|
||||
try {
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.block.BlockPhysicsEvent event = new org.bukkit.event.block.BlockPhysicsEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), org.bukkit.craftbukkit.block.CraftBlock.at(level, sourcePos)); // Paper - Add source block to BlockPhysicsEvent
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Bow infinity fix
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index a00e1ccb915e9e33b0c56b228cb0447d8af1e195..7d606ed45d88bc269943c013b4793583bacb1c83 100644
|
||||
index ee8c0d0edbb296106a128c48f4186ba3a5bf9df8..0f1a398c588b7e0832612a50734b7db8b3a48ccc 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -2165,7 +2165,7 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -2170,7 +2170,7 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
if (anyEventCancelled.booleanValue() && !this.abilities.instabuild && this instanceof final ServerPlayer player) this.resyncUsingItem(player); // Paper - resync if no item matched the Predicate
|
||||
|
||||
@@ -120,10 +120,10 @@ index 814bb2981ab32b216b7953e9b14fe09e96cc7c89..45f884bf598b38ec45baf423b84f5293
|
||||
.filter(player -> !playerList.isOp(player.getGameProfile()))
|
||||
.map(player -> player.getGameProfile().getName()),
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 5fd09fe2c544d197035f4500a0672f73b1da2501..27729923db521bc5b875badb1ee3fe75d5c16fdd 100644
|
||||
index 68490d8dc26c2d5f4999361fd7ad72a83581f48f..122e5e46a2c1e4be5c9d04501bfe064f239ec230 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2646,7 +2646,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2645,7 +2645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
// Leaves start - skip
|
||||
@@ -132,7 +132,7 @@ index 5fd09fe2c544d197035f4500a0672f73b1da2501..27729923db521bc5b875badb1ee3fe75
|
||||
ServerLevel.this.realPlayers.add(serverPlayer);
|
||||
}
|
||||
// Leaves end - skip
|
||||
@@ -2721,7 +2721,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2720,7 +2720,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
// Leaves start - skip
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Servux Protocol
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 9b1a65036392a965dc0ce93247dfc0cf53630034..c4113e01a8624397e78a18834bdcd857bf953bbe 100644
|
||||
index 122e5e46a2c1e4be5c9d04501bfe064f239ec230..cda2a31196b43abe2e32a3d755b42f043c97f5de 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2207,6 +2207,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2206,6 +2206,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
this.lastSpawnChunkRadius = i;
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Placing locked hopper no longer send NC updates
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 7c13e7b7a547150642c4a4bddf5e8dee1d580984..148d92e12c238b81087f68756da7d17da435d3ea 100644
|
||||
index ac4996dda7bcf5f20391f45e3f703b21557a1669..31f52bef093849dc15add696bb7bcfb5f326589a 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1200,7 +1200,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
@@ -1210,7 +1210,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
|
||||
}
|
||||
|
||||
if ((flags & 1) != 0) {
|
||||
|
||||
@@ -5,36 +5,14 @@ Subject: [PATCH] Spawn invulnerable time
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index d4984c919a88fa930dfec823cd9b471fa47f3565..6f845730bb0a9dcd1b26e68171e80edc669b6430 100644
|
||||
index d4984c919a88fa930dfec823cd9b471fa47f3565..8a622da26cff56f404b7d8b6131c27c65a31cdfe 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -221,6 +221,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private int lastSentFood = -99999999;
|
||||
private boolean lastFoodSaturationZero = true;
|
||||
public int lastSentExp = -99999999;
|
||||
+ private int spawnInvulnerableTime = 60; // Leaves - spawn invulnerable time
|
||||
private ChatVisiblity chatVisibility = ChatVisiblity.FULL;
|
||||
public ParticleStatus particleStatus = ParticleStatus.ALL;
|
||||
private boolean canChatColor = true;
|
||||
@@ -751,6 +752,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.resetOperationCountPerTick(); // Leaves - player operation limiter
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
+ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.spawnInvulnerableTime && this.invulnerableTime > 0) --this.spawnInvulnerableTime; // Leaves - spawn invulnerable time
|
||||
if (this.invulnerableTime > 0) {
|
||||
this.invulnerableTime--;
|
||||
}
|
||||
@@ -1185,6 +1187,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
if (this.isInvulnerableTo(level, damageSource)) {
|
||||
return false;
|
||||
} else {
|
||||
+ // Leaves start - spawn invulnerable time
|
||||
+ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.spawnInvulnerableTime) {
|
||||
+ if (this.spawnInvulnerableTime > 0 && !damageSource.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - spawn invulnerable time
|
||||
Entity entity = damageSource.getEntity();
|
||||
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
|
||||
!(entity instanceof Player player && !this.canHarmPlayer(player))
|
||||
@@ -474,6 +474,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.adventure$displayName = org.leavesmc.leaves.LeavesConfig.fix.vanillaDisplayName ? io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getDisplayName()) : net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper // Leaves - Vanilla display name
|
||||
this.bukkitPickUpLoot = true;
|
||||
this.maxHealthCache = this.getMaxHealth();
|
||||
+ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.spawnInvulnerableTime) this.invulnerableTime = 60; // Leaves - spawn invulnerable time
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,19 +18,18 @@ index 62e2d5704c348955bc8284dc2d54c933b7bcdd06..7ef20f0138fad39a1d23edd7b26ddc88
|
||||
public void executeAsync(final Runnable runnable) {
|
||||
MCUtil.scheduleAsyncTask(this.catching(runnable, "asynchronous"));
|
||||
diff --git a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java
|
||||
index 5c52b1563d20d7e977a5bb958c18b19dec5c365a..e227cb58989c32a2e1dff1b731efe771db33b26e 100644
|
||||
index 5c52b1563d20d7e977a5bb958c18b19dec5c365a..65664441c5692620a8b22513ded497b7951a3245 100644
|
||||
--- a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java
|
||||
@@ -106,6 +106,14 @@ public class BukkitCommandNode extends LiteralCommandNode<CommandSourceStack> {
|
||||
@@ -106,6 +106,13 @@ public class BukkitCommandNode extends LiteralCommandNode<CommandSourceStack> {
|
||||
List<String> results = null;
|
||||
Location pos = context.getSource().getLocation();
|
||||
try {
|
||||
+ // Leaves start - custom suggestion
|
||||
+ if (this.command instanceof org.leavesmc.leaves.command.LeavesSuggestionCommand suggestionCommand) {
|
||||
+ CompletableFuture<Suggestions> suggestions = suggestionCommand.tabSuggestion(sender, this.literal, args, pos.clone(), builder);
|
||||
+ if (suggestions != null) {
|
||||
+ return suggestions;
|
||||
+ }
|
||||
+ org.leavesmc.leaves.command.LeavesSuggestionBuilder suggestionBuilder = new org.leavesmc.leaves.command.LeavesSuggestionBuilder(builder.createOffset(builder.getInput().lastIndexOf(' ') + 1));
|
||||
+ suggestionCommand.suggest(sender, this.literal, args, pos.clone(), suggestionBuilder);
|
||||
+ return suggestionBuilder.build();
|
||||
+ }
|
||||
+ // Leaves end - custom suggestion
|
||||
results = this.command.tabComplete(sender, this.literal, args, pos.clone());
|
||||
|
||||
@@ -81,7 +81,7 @@ public final class LeavesConfig {
|
||||
|
||||
GlobalConfigManager.init();
|
||||
|
||||
registerCommand("leaves", new LeavesCommand("leaves"));
|
||||
registerCommand("leaves", new LeavesCommand());
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
@@ -138,7 +138,7 @@ public final class LeavesConfig {
|
||||
@Override
|
||||
public void verify(Boolean old, Boolean value) throws IllegalArgumentException {
|
||||
if (value) {
|
||||
registerCommand("bot", new org.leavesmc.leaves.bot.BotCommand("bot"));
|
||||
registerCommand("bot", new org.leavesmc.leaves.bot.BotCommand());
|
||||
org.leavesmc.leaves.bot.agent.Actions.registerAll();
|
||||
} else {
|
||||
unregisterCommand("bot");
|
||||
@@ -523,20 +523,9 @@ public final class LeavesConfig {
|
||||
}
|
||||
}
|
||||
|
||||
@GlobalConfig(value = "no-block-update-command", validator = NoBlockUpdateValidator.class)
|
||||
@GlobalConfig(value = "no-block-update-command")
|
||||
public boolean noBlockUpdateCommand = false;
|
||||
|
||||
private static class NoBlockUpdateValidator extends BooleanConfigValidator {
|
||||
@Override
|
||||
public void verify(Boolean old, Boolean value) throws IllegalArgumentException {
|
||||
if (value) {
|
||||
registerCommand("blockupdate", new org.leavesmc.leaves.command.NoBlockUpdateCommand("blockupdate"));
|
||||
} else {
|
||||
unregisterCommand("blockupdate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GlobalConfig("no-tnt-place-update")
|
||||
public boolean noTNTPlaceUpdate = false;
|
||||
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
package org.leavesmc.leaves.bot;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
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.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.subcommands.BotActionCommand;
|
||||
import org.leavesmc.leaves.bot.subcommands.BotConfigCommand;
|
||||
@@ -23,37 +9,15 @@ import org.leavesmc.leaves.bot.subcommands.BotListCommand;
|
||||
import org.leavesmc.leaves.bot.subcommands.BotLoadCommand;
|
||||
import org.leavesmc.leaves.bot.subcommands.BotRemoveCommand;
|
||||
import org.leavesmc.leaves.bot.subcommands.BotSaveCommand;
|
||||
import org.leavesmc.leaves.command.LeavesCommandUtil;
|
||||
import org.leavesmc.leaves.command.LeavesRootCommand;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionCommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
//TODO rewrite
|
||||
public class BotCommand extends Command implements LeavesSuggestionCommand {
|
||||
|
||||
public BotCommand(String name) {
|
||||
super(name);
|
||||
this.description = "FakePlayer Command";
|
||||
this.usageMessage = "/bot [" + String.join(" | ", usableSubcommands()) + "]";
|
||||
this.setPermission("bukkit.command.bot");
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
if (pluginManager.getPermission("bukkit.command.bot") == null) {
|
||||
pluginManager.addPermission(new Permission("bukkit.command.bot", PermissionDefault.OP));
|
||||
}
|
||||
}
|
||||
public class BotCommand extends LeavesRootCommand {
|
||||
|
||||
// subcommand label -> subcommand
|
||||
private static final Map<String, LeavesSubcommand> SUBCOMMANDS = Util.make(() -> {
|
||||
@@ -71,75 +35,12 @@ public class BotCommand extends Command implements LeavesSuggestionCommand {
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
});
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String alias, final String[] args, final @Nullable Location location) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, usableSubcommands(), "bukkit.command.bot.", "bukkit.command.bot");
|
||||
}
|
||||
|
||||
final @Nullable Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
var list = subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length), location);
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, list, "bukkit.command.bot.", "bukkit.command.bot");
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
public BotCommand() {
|
||||
super("bot", "FakePlayer Command", "bukkit.command.bot", SUBCOMMANDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CompletableFuture<Suggestions> tabSuggestion(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, @NotNull SuggestionsBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length > 1) {
|
||||
final @Nullable Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
return subCommand.second().tabSuggestion(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length), location, builder);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(final @NotNull CommandSender sender, final @NotNull String commandLabel, final String @NotNull [] args) {
|
||||
if (!testPermission(sender) || !LeavesConfig.modify.fakeplayer.enable) return true;
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return false;
|
||||
}
|
||||
final Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
|
||||
if (subCommand == null) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<String, LeavesSubcommand> resolveCommand(String label) {
|
||||
label = label.toLowerCase(Locale.ENGLISH);
|
||||
LeavesSubcommand subCommand = SUBCOMMANDS.get(label);
|
||||
|
||||
if (subCommand != null) {
|
||||
return Pair.of(label, subCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<String> usableSubcommands() {
|
||||
List<String> subcommands = new ArrayList<>();
|
||||
for (var entry : SUBCOMMANDS.entrySet()) {
|
||||
if (entry.getValue().tabCompletes()) {
|
||||
subcommands.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return subcommands;
|
||||
}
|
||||
|
||||
public Component unknownMessage() {
|
||||
return text("Usage: /bot [" + String.join(" | ", usableSubcommands()) + "]", NamedTextColor.RED);
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.fakeplayer.enable;
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class ServerBotGameMode extends ServerPlayerGameMode {
|
||||
return false;
|
||||
} else {
|
||||
this.level.captureDrops = null;
|
||||
BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player);
|
||||
BlockState iblockdata1 = org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate() ? iblockdata : block.playerWillDestroy(this.level, pos, iblockdata, this.player); // Leaves - no block update
|
||||
boolean flag = this.level.removeBlock(pos, false);
|
||||
|
||||
if (flag) {
|
||||
|
||||
@@ -3,7 +3,23 @@ package org.leavesmc.leaves.bot.agent;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.bot.agent.actions.*;
|
||||
import org.leavesmc.leaves.bot.agent.actions.AttackAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.BreakBlockAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.DropAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.FishAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.JumpAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.LookAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.RotateAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.RotationAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.ShootAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.SneakAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.SwimAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemOffHandAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemOnAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemOnOffhandAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemToAction;
|
||||
import org.leavesmc.leaves.bot.agent.actions.UseItemToOffhandAction;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -4,7 +4,11 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.configs.*;
|
||||
import org.leavesmc.leaves.bot.agent.configs.AlwaysSendDataConfig;
|
||||
import org.leavesmc.leaves.bot.agent.configs.SimulationDistanceConfig;
|
||||
import org.leavesmc.leaves.bot.agent.configs.SkipSleepConfig;
|
||||
import org.leavesmc.leaves.bot.agent.configs.SpawnPhantomConfig;
|
||||
import org.leavesmc.leaves.bot.agent.configs.TickTypeConfig;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package org.leavesmc.leaves.bot.subcommands;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
@@ -15,94 +14,49 @@ import org.leavesmc.leaves.bot.agent.AbstractBotAction;
|
||||
import org.leavesmc.leaves.bot.agent.Actions;
|
||||
import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotActionCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canUseAction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 2) {
|
||||
sender.sendMessage(text("Use /bot action <name> <action> to make fakeplayer do action", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
ServerBot bot = BotList.INSTANCE.getBotByName(args[0]);
|
||||
if (bot == null) {
|
||||
sender.sendMessage(text("This fakeplayer is not in server", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[1].equals("list")) {
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s action list:");
|
||||
for (int i = 0; i < bot.getBotActions().size(); i++) {
|
||||
sender.sendMessage(i + " " + bot.getBotActions().get(i).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args[1].equals("stop")) {
|
||||
if (args.length < 3) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
return false;
|
||||
}
|
||||
|
||||
String index = args[2];
|
||||
if (index.equals("all")) {
|
||||
Set<AbstractBotAction<?>> forRemoval = new HashSet<>();
|
||||
switch (args[1].toLowerCase()) {
|
||||
case "list" -> {
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s action list:");
|
||||
for (int i = 0; i < bot.getBotActions().size(); i++) {
|
||||
AbstractBotAction<?> action = bot.getBotActions().get(i);
|
||||
BotActionStopEvent event = new BotActionStopEvent(
|
||||
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
|
||||
);
|
||||
event.callEvent();
|
||||
if (!event.isCancelled()) {
|
||||
forRemoval.add(action);
|
||||
}
|
||||
}
|
||||
bot.getBotActions().removeAll(forRemoval);
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s action list cleared.");
|
||||
} else {
|
||||
try {
|
||||
int i = Integer.parseInt(index);
|
||||
if (i < 0 || i >= bot.getBotActions().size()) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
return false;
|
||||
}
|
||||
|
||||
AbstractBotAction<?> action = bot.getBotActions().get(i);
|
||||
BotActionStopEvent event = new BotActionStopEvent(
|
||||
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
|
||||
);
|
||||
event.callEvent();
|
||||
if (!event.isCancelled()) {
|
||||
bot.getBotActions().remove(i);
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s " + action.getName() + " stopped.");
|
||||
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
sender.sendMessage(i + " " + bot.getBotActions().get(i).getName());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case "start" -> executeStart(bot, sender, args);
|
||||
case "stop" -> executeStop(bot, sender, args);
|
||||
}
|
||||
}
|
||||
|
||||
AbstractBotAction<?> action = Actions.getForName(args[1]);
|
||||
private void executeStart(ServerBot bot, CommandSender sender, String[] args) {
|
||||
AbstractBotAction<?> action = Actions.getForName(args[2]);
|
||||
if (action == null) {
|
||||
sender.sendMessage(text("Invalid action", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
CraftPlayer player;
|
||||
@@ -112,11 +66,7 @@ public class BotActionCommand implements LeavesSubcommand {
|
||||
player = bot.getBukkitEntity();
|
||||
}
|
||||
|
||||
String[] realArgs = new String[args.length - 2];
|
||||
if (realArgs.length != 0) {
|
||||
System.arraycopy(args, 2, realArgs, 0, realArgs.length);
|
||||
}
|
||||
|
||||
String[] realArgs = Arrays.copyOfRange(args, 3, args.length);
|
||||
AbstractBotAction<?> newAction;
|
||||
try {
|
||||
if (action instanceof CraftCustomBotAction customBotAction) {
|
||||
@@ -127,76 +77,96 @@ public class BotActionCommand implements LeavesSubcommand {
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
sender.sendMessage(text("Action create error, please check your arguments, " + e.getMessage(), NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newAction == null) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bot.addBotAction(newAction, sender)) {
|
||||
sender.sendMessage("Action " + action.getName() + " has been issued to " + bot.getName().getString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void executeStop(ServerBot bot, CommandSender sender, String[] args) {
|
||||
if (args.length < 3) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
|
||||
String index = args[2];
|
||||
if (index.equals("all")) {
|
||||
Set<AbstractBotAction<?>> forRemoval = new HashSet<>();
|
||||
for (int i = 0; i < bot.getBotActions().size(); i++) {
|
||||
AbstractBotAction<?> action = bot.getBotActions().get(i);
|
||||
BotActionStopEvent event = new BotActionStopEvent(
|
||||
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
|
||||
);
|
||||
event.callEvent();
|
||||
if (!event.isCancelled()) {
|
||||
forRemoval.add(action);
|
||||
}
|
||||
}
|
||||
bot.getBotActions().removeAll(forRemoval);
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s action list cleared.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int i = Integer.parseInt(index);
|
||||
if (i < 0 || i >= bot.getBotActions().size()) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractBotAction<?> action = bot.getBotActions().get(i);
|
||||
BotActionStopEvent event = new BotActionStopEvent(
|
||||
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
|
||||
);
|
||||
event.callEvent();
|
||||
if (!event.isCancelled()) {
|
||||
bot.getBotActions().remove(i);
|
||||
sender.sendMessage(bot.getScoreboardName() + "'s " + action.getName() + " stopped.");
|
||||
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(text("Invalid index", NamedTextColor.RED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canUseAction) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String subCommand, String @NotNull [] args, Location location, @NotNull LeavesSuggestionBuilder builder) {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
ServerBot serverBot = null;
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(botList.bots.stream().map(e -> e.getName().getString()).toList());
|
||||
} else {
|
||||
ServerBot bot = botList.getBotByName(args[0]);
|
||||
if (bot == null) {
|
||||
return Collections.singletonList("<" + args[0] + " not found>");
|
||||
}
|
||||
if (args.length > 1 && (serverBot = botList.getBotByName(args[0])) == null) {
|
||||
builder.suggest("<" + args[0] + " not found>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 2) {
|
||||
list.add("list");
|
||||
list.add("stop");
|
||||
list.addAll(Actions.getNames());
|
||||
}
|
||||
|
||||
if (args.length >= 3) {
|
||||
if (args[1].equals("stop")) {
|
||||
list.add("all");
|
||||
for (int i = 0; i < bot.getBotActions().size(); i++) {
|
||||
list.add(String.valueOf(i));
|
||||
switch (args.length) {
|
||||
case 0, 1 -> botList.bots.forEach(bot -> builder.suggest(bot.getName().getString()));
|
||||
case 2 -> builder.suggest("start").suggest("stop").suggest("list");
|
||||
case 3 -> {
|
||||
switch (args[1].toLowerCase()) {
|
||||
case "start" -> Actions.getNames().forEach(builder::suggest);
|
||||
case "stop" -> {
|
||||
builder.suggest("all");
|
||||
int[] index = new int[]{0};
|
||||
serverBot.getBotActions().forEach(a -> builder.suggest(String.valueOf(index[0]++)));
|
||||
}
|
||||
} else {
|
||||
return Collections.singletonList("<" + args[1] + " not found>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> tabSuggestion(CommandSender sender, String subCommand, String[] args, Location location, SuggestionsBuilder builder) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canUseAction) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args.length >= 3) {
|
||||
if (args[1].equals("stop")) {
|
||||
return null;
|
||||
}
|
||||
AbstractBotAction<?> action = Actions.getForName(args[1]);
|
||||
if (action != null) {
|
||||
Pair<List<String>, String> results = action.getArgument().suggestion(args.length - 3, sender, args[args.length - 1]);
|
||||
|
||||
case 4, 5, 6, 7 -> {
|
||||
AbstractBotAction<?> action = Actions.getForName(args[2]);
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
Pair<List<String>, String> results = action.getArgument().suggestion(args.length - 4, sender, args[args.length - 2]);
|
||||
if (results == null || results.getLeft() == null) {
|
||||
return builder.buildFuture();
|
||||
return;
|
||||
}
|
||||
|
||||
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
|
||||
for (String s : results.getLeft()) {
|
||||
if (results.getRight() != null) {
|
||||
builder.suggest(s, Component.literal(results.getRight()));
|
||||
@@ -204,16 +174,12 @@ public class BotActionCommand implements LeavesSubcommand {
|
||||
builder.suggest(s);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.fakeplayer.canUseAction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package org.leavesmc.leaves.bot.subcommands;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
@@ -15,52 +15,46 @@ import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
|
||||
import org.leavesmc.leaves.bot.agent.Configs;
|
||||
import org.leavesmc.leaves.command.CommandArgumentResult;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.event.bot.BotConfigModifyEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotConfigCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canModifyConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 2) {
|
||||
sender.sendMessage(text("Use /bot config <name> <config> to modify fakeplayer's config", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
ServerBot bot = BotList.INSTANCE.getBotByName(args[0]);
|
||||
if (bot == null) {
|
||||
sender.sendMessage(text("This fakeplayer is not in server", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Configs.getConfigNames().contains(args[1])) {
|
||||
sender.sendMessage(text("This config is not accept", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractBotConfig<?> config = bot.getConfig(Objects.requireNonNull(Configs.getConfig(args[1])));
|
||||
if (args.length < 3) {
|
||||
config.getMessage().forEach(sender::sendMessage);
|
||||
} else {
|
||||
String[] realArgs = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, realArgs, 0, realArgs.length);
|
||||
String[] realArgs = Arrays.copyOfRange(args, 2, args.length);
|
||||
|
||||
BotConfigModifyEvent event = new BotConfigModifyEvent(bot.getBukkitEntity(), config.getName(), realArgs, sender);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
CommandArgumentResult result = config.getArgument().parse(0, realArgs);
|
||||
|
||||
@@ -71,60 +65,33 @@ public class BotConfigCommand implements LeavesSubcommand {
|
||||
sender.sendMessage(text(e.getMessage(), NamedTextColor.RED));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canModifyConfig) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
@Override
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
ServerBot serverBot = null;
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(botList.bots.stream().map(e -> e.getName().getString()).toList());
|
||||
} else {
|
||||
ServerBot bot = botList.getBotByName(args[0]);
|
||||
if (bot == null) {
|
||||
return Collections.singletonList("<" + args[0] + " not found>");
|
||||
} else {
|
||||
if (args.length == 2) {
|
||||
list.addAll(Configs.getConfigNames());
|
||||
}
|
||||
|
||||
if (args.length >= 3) {
|
||||
return Collections.singletonList("<" + args[1] + " not found>");
|
||||
}
|
||||
}
|
||||
if (args.length > 1 && (serverBot = botList.getBotByName(args[0])) == null) {
|
||||
builder.suggest("<" + args[0] + " not found>");
|
||||
return;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> tabSuggestion(CommandSender sender, String subCommand, String[] args, Location location, SuggestionsBuilder builder) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canModifyConfig) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args.length >= 3) {
|
||||
ServerBot bot = BotList.INSTANCE.getBotByName(args[0]);
|
||||
if (bot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Configs<?> config = Configs.getConfig(args[1]);
|
||||
if (config != null) {
|
||||
AbstractBotConfig<?> botConfig = bot.getConfig(config);
|
||||
switch (args.length) {
|
||||
case 0, 1 -> botList.bots.forEach(bot -> builder.suggest(bot.getName().getString()));
|
||||
case 2 -> Configs.getConfigNames().forEach(builder::suggest);
|
||||
case 3, 4 -> {
|
||||
Configs<?> config = Configs.getConfig(args[1]);
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
AbstractBotConfig<?> botConfig = serverBot.getConfig(config);
|
||||
Pair<List<String>, String> results = botConfig.getArgument().suggestion(args.length - 3, sender, args[args.length - 1]);
|
||||
|
||||
if (results == null || results.getLeft() == null) {
|
||||
return builder.buildFuture();
|
||||
return;
|
||||
}
|
||||
|
||||
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
|
||||
for (String s : results.getLeft()) {
|
||||
if (results.getRight() != null) {
|
||||
builder.suggest(s, Component.literal(results.getRight()));
|
||||
@@ -132,16 +99,12 @@ public class BotConfigCommand implements LeavesSubcommand {
|
||||
builder.suggest(s);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.fakeplayer.canModifyConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,26 +8,25 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.LeavesLogger;
|
||||
import org.leavesmc.leaves.bot.BotCreateState;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.BotUtil;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.event.bot.BotCreateEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotCreateCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(text("Use /bot create <name> [skin_name] to create a fakeplayer", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
String botName = args[0];
|
||||
@@ -59,26 +58,19 @@ public class BotCreateCommand implements LeavesSubcommand {
|
||||
|
||||
builder.spawnWithSkin(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
List<String> list = new ArrayList<>();
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
list.add("<BotName>");
|
||||
builder.suggest("<BotName>");
|
||||
}
|
||||
if (args.length == 2) {
|
||||
list.add("[SkinName]");
|
||||
builder.suggest("[SkinName]");
|
||||
}
|
||||
if (sender instanceof ConsoleCommandSender) {
|
||||
if (args.length == 3) {
|
||||
for (var world : sender.getServer().getWorlds()) {
|
||||
list.add(world.getName());
|
||||
}
|
||||
}
|
||||
if (sender instanceof ConsoleCommandSender && args.length == 3) {
|
||||
Bukkit.getWorlds().forEach(world -> builder.suggest(world.getName()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean canCreate(CommandSender sender, @NotNull String name) {
|
||||
|
||||
@@ -5,12 +5,13 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.entity.Bot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,8 +23,17 @@ import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotListCommand implements LeavesSubcommand {
|
||||
|
||||
@NotNull
|
||||
private static String formatPlayerNameList(@NotNull List<String> list) {
|
||||
if (list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
String string = list.toString();
|
||||
return string.substring(1, string.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
if (args.length < 2) {
|
||||
Map<World, List<String>> botMap = new HashMap<>();
|
||||
@@ -45,7 +55,7 @@ public class BotListCommand implements LeavesSubcommand {
|
||||
|
||||
if (world == null) {
|
||||
sender.sendMessage(text("Unknown world", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> snowBotList = new ArrayList<>();
|
||||
@@ -58,26 +68,10 @@ public class BotListCommand implements LeavesSubcommand {
|
||||
|
||||
sender.sendMessage(world.getName() + "(" + botList.bots.size() + "): " + formatPlayerNameList(snowBotList));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(Bukkit.getWorlds().stream().map(WorldInfo::getName).toList());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String formatPlayerNameList(@NotNull List<String> list) {
|
||||
if (list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
String string = list.toString();
|
||||
return string.substring(1, string.length() - 1);
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
Bukkit.getWorlds().forEach(world -> builder.suggest(world.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,61 +3,46 @@ package org.leavesmc.leaves.bot.subcommands;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotLoadCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(text("Use /bot load <name> to save a fakeplayer", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
String realName = args[0];
|
||||
BotList botList = BotList.INSTANCE;
|
||||
if (!botList.getSavedBotList().contains(realName)) {
|
||||
sender.sendMessage(text("This fakeplayer is not saved", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (botList.loadNewBot(realName) == null) {
|
||||
sender.sendMessage(text("Can't load bot, please check", NamedTextColor.RED));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(botList.getSavedBotList().keySet());
|
||||
botList.getSavedBotList().keySet().forEach(builder::suggest);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.fakeplayer.canManualSaveAndLoad;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,15 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
|
||||
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotRemoveCommand implements LeavesSubcommand {
|
||||
@@ -21,10 +21,10 @@ public class BotRemoveCommand implements LeavesSubcommand {
|
||||
private final Component errorMessage = text("Usage: /bot remove <name> [hour] [minute] [second]", NamedTextColor.RED);
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1 || args.length > 4) {
|
||||
sender.sendMessage(errorMessage);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
BotList botList = BotList.INSTANCE;
|
||||
@@ -32,18 +32,18 @@ public class BotRemoveCommand implements LeavesSubcommand {
|
||||
|
||||
if (bot == null) {
|
||||
sender.sendMessage(text("This fakeplayer is not in server", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 2 && args[1].equals("cancel")) {
|
||||
if (bot.removeTaskId == -1) {
|
||||
sender.sendMessage(text("This fakeplayer is not scheduled to be removed", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().cancelTask(bot.removeTaskId);
|
||||
bot.removeTaskId = -1;
|
||||
sender.sendMessage(text("Remove cancel"));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
@@ -74,7 +74,7 @@ public class BotRemoveCommand implements LeavesSubcommand {
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage(errorMessage);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isReschedule = bot.removeTaskId != -1;
|
||||
@@ -88,36 +88,30 @@ public class BotRemoveCommand implements LeavesSubcommand {
|
||||
}, time).getTaskId();
|
||||
|
||||
sender.sendMessage("This fakeplayer will be removed in " + h + "h " + m + "m " + s + "s" + (isReschedule ? " (rescheduled)" : ""));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
botList.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
List<String> list = new ArrayList<>();
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(botList.bots.stream().map(e -> e.getName().getString()).toList());
|
||||
botList.bots.forEach(bot -> builder.suggest(bot.getName().getString()));
|
||||
}
|
||||
|
||||
if (args.length == 2) {
|
||||
list.add("cancel");
|
||||
list.add("[hour]");
|
||||
builder.suggest("cancel");
|
||||
builder.suggest("[hour]");
|
||||
}
|
||||
|
||||
if (args.length > 2 && !args[1].equals("cancel")) {
|
||||
switch (args.length) {
|
||||
case 3 -> list.add("[minute]");
|
||||
case 4 -> list.add("[second]");
|
||||
case 3 -> builder.suggest("[minute]");
|
||||
case 4 -> builder.suggest("[second]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,29 +3,24 @@ package org.leavesmc.leaves.bot.subcommands;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class BotSaveCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(text("Use /bot save <name> to save a fakeplayer", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
BotList botList = BotList.INSTANCE;
|
||||
@@ -33,34 +28,24 @@ public class BotSaveCommand implements LeavesSubcommand {
|
||||
|
||||
if (bot == null) {
|
||||
sender.sendMessage(text("This fakeplayer is not in server", NamedTextColor.RED));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (botList.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, true)) {
|
||||
sender.sendMessage(bot.getScoreboardName() + " saved to " + bot.createState.realName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
|
||||
if (args.length <= 1) {
|
||||
list.addAll(botList.bots.stream().map(e -> e.getName().getString()).toList());
|
||||
botList.bots.forEach(bot -> builder.suggest(bot.getName().getString()));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.fakeplayer.canManualSaveAndLoad;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.command.subcommands.BlockUpdateCommand;
|
||||
import org.leavesmc.leaves.command.subcommands.ConfigCommand;
|
||||
import org.leavesmc.leaves.command.subcommands.CounterCommand;
|
||||
import org.leavesmc.leaves.command.subcommands.PeacefulModeSwitchCommand;
|
||||
@@ -21,22 +9,12 @@ import org.leavesmc.leaves.command.subcommands.ReloadCommand;
|
||||
import org.leavesmc.leaves.command.subcommands.ReportCommand;
|
||||
import org.leavesmc.leaves.command.subcommands.UpdateCommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
|
||||
public final class LeavesCommand extends Command implements LeavesSuggestionCommand {
|
||||
public final class LeavesCommand extends LeavesRootCommand {
|
||||
|
||||
public static final String BASE_PERM = "bukkit.command.leaves.";
|
||||
|
||||
@@ -49,111 +27,14 @@ public final class LeavesCommand extends Command implements LeavesSuggestionComm
|
||||
commands.put(Set.of("counter"), new CounterCommand());
|
||||
commands.put(Set.of("reload"), new ReloadCommand());
|
||||
commands.put(Set.of("report"), new ReportCommand());
|
||||
commands.put(Set.of("blockupdate"), new BlockUpdateCommand());
|
||||
|
||||
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));
|
||||
});
|
||||
|
||||
public LeavesCommand(final String name) {
|
||||
super(name);
|
||||
this.description = "Leaves related commands";
|
||||
this.usageMessage = "/leaves [" + String.join(" | ", SUBCOMMANDS.keySet()) + "]";
|
||||
final List<String> permissions = new ArrayList<>();
|
||||
permissions.add("bukkit.command.leaves");
|
||||
permissions.addAll(SUBCOMMANDS.keySet().stream().map(s -> BASE_PERM + s).toList());
|
||||
this.setPermission(String.join(";", permissions));
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
for (final String perm : permissions) {
|
||||
if (pluginManager.getPermission(perm) == null) {
|
||||
pluginManager.addPermission(new Permission(perm, PermissionDefault.OP));
|
||||
}
|
||||
}
|
||||
public LeavesCommand() {
|
||||
super("leaves", "Leaves related commands", "bukkit.command.leaves", SUBCOMMANDS);
|
||||
}
|
||||
|
||||
private static boolean testPermission(final CommandSender sender, final String permission) {
|
||||
if (sender.hasPermission(BASE_PERM + permission) || sender.hasPermission("bukkit.command.leaves")) {
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(Bukkit.permissionMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String alias, final String[] args, final @Nullable Location location) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, usableSubcommands());
|
||||
}
|
||||
|
||||
final @Nullable Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length), location);
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> tabSuggestion(final @NotNull CommandSender sender, final @NotNull String alias, final @NotNull String @NotNull [] args, final @Nullable Location location, final @NotNull SuggestionsBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length > 1) {
|
||||
final @Nullable Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
return subCommand.second().tabSuggestion(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length), location, builder);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(final @NotNull CommandSender sender, final @NotNull String commandLabel, final String @NotNull [] args) {
|
||||
if (!testPermission(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return false;
|
||||
}
|
||||
final Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
|
||||
if (subCommand == null) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!testPermission(sender, subCommand.first())) {
|
||||
return true;
|
||||
}
|
||||
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||
}
|
||||
|
||||
private Collection<String> usableSubcommands() {
|
||||
List<String> subcommands = new ArrayList<>();
|
||||
for (var entry : SUBCOMMANDS.entrySet()) {
|
||||
if (entry.getValue().tabCompletes()) {
|
||||
subcommands.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return subcommands;
|
||||
}
|
||||
|
||||
public Component unknownMessage() {
|
||||
return text("Usage: /leaves [" + String.join(" | ", usableSubcommands()) + "]", RED);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<String, LeavesSubcommand> resolveCommand(String label) {
|
||||
label = label.toLowerCase(Locale.ENGLISH);
|
||||
LeavesSubcommand subCommand = SUBCOMMANDS.get(label);
|
||||
|
||||
if (subCommand != null) {
|
||||
return Pair.of(label, subCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -107,14 +107,6 @@ public class LeavesCommandUtil {
|
||||
return results;
|
||||
}
|
||||
|
||||
private record Candidate(String item, int score) {
|
||||
private static Candidate of(String item, int score) {
|
||||
return new Candidate(item, score);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from org/bukkit/command/defaults/HelpCommand.java
|
||||
|
||||
/**
|
||||
* Computes the Dameraur-Levenshtein Distance between two strings. Adapted
|
||||
* from the algorithm at <a href="http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance">Wikipedia: Damerau–Levenshtein distance</a>
|
||||
@@ -178,4 +170,12 @@ public class LeavesCommandUtil {
|
||||
|
||||
return H[s1Len + 1][s2Len + 1];
|
||||
}
|
||||
|
||||
// Copy from org/bukkit/command/defaults/HelpCommand.java
|
||||
|
||||
private record Candidate(String item, int score) {
|
||||
private static Candidate of(String item, int score) {
|
||||
return new Candidate(item, score);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
|
||||
public abstract class LeavesRootCommand extends Command implements LeavesSuggestionCommand {
|
||||
|
||||
protected final String basePermission;
|
||||
protected final Map<String, LeavesSubcommand> subcommands;
|
||||
|
||||
protected LeavesRootCommand(
|
||||
@NotNull String name,
|
||||
@NotNull String description,
|
||||
@NotNull String basePermission,
|
||||
@NotNull Map<String, LeavesSubcommand> subCommands
|
||||
) {
|
||||
super(name, description, String.format("/%s [%s]", name, String.join(" | ", subCommands.keySet())), Collections.emptyList());
|
||||
this.basePermission = basePermission;
|
||||
this.subcommands = subCommands;
|
||||
|
||||
final List<String> permissions = new ArrayList<>();
|
||||
permissions.add(basePermission);
|
||||
permissions.addAll(subCommands.keySet().stream().map(s -> basePermission + "." + s).toList());
|
||||
this.setPermission(String.join(";", permissions));
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
for (final String perm : permissions) {
|
||||
if (pluginManager.getPermission(perm) == null) {
|
||||
pluginManager.addPermission(new Permission(perm, PermissionDefault.OP));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean testPermission(final CommandSender sender, final String permission) {
|
||||
if (sender.hasPermission(basePermission) || sender.hasPermission(basePermission + "." + permission)) {
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(Bukkit.permissionMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||
if (!testPermission(sender) || !isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return true;
|
||||
}
|
||||
final Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
|
||||
if (subCommand == null) {
|
||||
sender.sendMessage(unknownMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!testPermission(sender, subCommand.first())) {
|
||||
return true;
|
||||
}
|
||||
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggest(final @NotNull CommandSender sender, final @NotNull String alias, final @NotNull String @NotNull [] args, final @Nullable Location location, @NotNull LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
if (!testPermission(sender) || !isEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (args.length <= 1) {
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, usableSubcommands(), basePermission + ".", basePermission).forEach(builder::suggest);
|
||||
return;
|
||||
}
|
||||
final @Nullable Pair<String, LeavesSubcommand> subCommand = resolveCommand(args[0]);
|
||||
if (subCommand != null) {
|
||||
subCommand.second().suggest(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length), location, builder);
|
||||
}
|
||||
}
|
||||
|
||||
public Component unknownMessage() {
|
||||
return text(String.format("Usage: /%s [%s]", this.getName(), String.join(" | ", usableSubcommands())), RED);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Pair<String, LeavesSubcommand> resolveCommand(String label) {
|
||||
label = label.toLowerCase(Locale.ENGLISH);
|
||||
LeavesSubcommand subCommand = subcommands.get(label);
|
||||
|
||||
if (subCommand != null && subCommand.isEnabled()) {
|
||||
return Pair.of(label, subCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<String> usableSubcommands() {
|
||||
List<String> subcommandList = new ArrayList<>();
|
||||
for (var entry : subcommands.entrySet()) {
|
||||
if (entry.getValue().isEnabled()) {
|
||||
subcommandList.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return subcommandList;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,7 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface LeavesSubcommand {
|
||||
boolean execute(CommandSender sender, String subCommand, String[] args);
|
||||
|
||||
default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args, Location location) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
default CompletableFuture<Suggestions> tabSuggestion(final CommandSender sender, final String subCommand, final String[] args, final Location location, final SuggestionsBuilder builder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default boolean tabCompletes() {
|
||||
return true;
|
||||
}
|
||||
public interface LeavesSubcommand extends LeavesSuggestionCommand {
|
||||
void execute(CommandSender sender, String subCommand, String[] args);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class LeavesSuggestionBuilder {
|
||||
|
||||
private SuggestionsBuilder vanillaBuilder;
|
||||
|
||||
public LeavesSuggestionBuilder(SuggestionsBuilder builder) {
|
||||
this.vanillaBuilder = builder;
|
||||
}
|
||||
|
||||
public CompletableFuture<Suggestions> build() {
|
||||
return vanillaBuilder.buildFuture();
|
||||
}
|
||||
|
||||
public LeavesSuggestionBuilder suggest(String text) {
|
||||
vanillaBuilder.suggest(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LeavesSuggestionBuilder suggest(String text, Message tooltip) {
|
||||
vanillaBuilder.suggest(text, tooltip);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LeavesSuggestionBuilder suggest(int value) {
|
||||
vanillaBuilder.suggest(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LeavesSuggestionBuilder suggest(int value, Message tooltip) {
|
||||
vanillaBuilder.suggest(value, tooltip);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LeavesSuggestionBuilder createOffset(int start) {
|
||||
vanillaBuilder = vanillaBuilder.createOffset(start);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getInput() {
|
||||
return vanillaBuilder.getInput();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface LeavesSuggestionCommand {
|
||||
@Nullable
|
||||
CompletableFuture<Suggestions> tabSuggestion(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, @NotNull SuggestionsBuilder builder) throws IllegalArgumentException;
|
||||
default void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
}
|
||||
|
||||
default boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package org.leavesmc.leaves.command;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
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.NotNull;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO merge to /leaves blockupdate
|
||||
public class NoBlockUpdateCommand extends Command {
|
||||
|
||||
private static boolean noBlockUpdate = false;
|
||||
|
||||
public NoBlockUpdateCommand(@NotNull String name) {
|
||||
super(name);
|
||||
this.description = "No Block Update Command";
|
||||
this.usageMessage = "/blockupdate";
|
||||
this.setPermission("bukkit.command.blockupdate");
|
||||
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
if (pluginManager.getPermission("bukkit.command.blockupdate") == null) {
|
||||
pluginManager.addPermission(new Permission("bukkit.command.blockupdate", PermissionDefault.OP));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, String @NotNull [] args) throws IllegalArgumentException {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, String @NotNull [] args) {
|
||||
if (!testPermission(sender)) return true;
|
||||
noBlockUpdate = !noBlockUpdate;
|
||||
Bukkit.broadcast(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Block update status: ", NamedTextColor.GRAY),
|
||||
Component.text(!noBlockUpdate, noBlockUpdate ? NamedTextColor.AQUA : NamedTextColor.GRAY)
|
||||
), "bukkit.command.blockupdate");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isNoBlockUpdate() {
|
||||
return LeavesConfig.modify.noBlockUpdateCommand && noBlockUpdate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.leavesmc.leaves.command.subcommands;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
|
||||
public class BlockUpdateCommand implements LeavesSubcommand {
|
||||
|
||||
private static boolean noBlockUpdate = false;
|
||||
|
||||
public static boolean isNoBlockUpdate() {
|
||||
return LeavesConfig.modify.noBlockUpdateCommand && noBlockUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull CommandSender sender, @NotNull String commandLabel, String @NotNull [] args) {
|
||||
noBlockUpdate = !noBlockUpdate;
|
||||
Bukkit.broadcast(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Block update status: ", NamedTextColor.GRAY),
|
||||
Component.text(!noBlockUpdate, noBlockUpdate ? NamedTextColor.AQUA : NamedTextColor.GRAY)
|
||||
), "bukkit.command.leaves.blockupdate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.noBlockUpdateCommand;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.leavesmc.leaves.command.subcommands;
|
||||
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
@@ -11,20 +9,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.command.LeavesCommandUtil;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.config.GlobalConfigManager;
|
||||
import org.leavesmc.leaves.config.VerifiedConfig;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ConfigCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(Component.text("Leaves Config", NamedTextColor.GRAY));
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
VerifiedConfig verifiedConfig = GlobalConfigManager.getVerifiedConfig(args[0]);
|
||||
@@ -34,7 +29,7 @@ public class ConfigCommand implements LeavesSubcommand {
|
||||
Component.text(args[0], NamedTextColor.RED),
|
||||
Component.text(" is Not Found.", NamedTextColor.GRAY)
|
||||
));
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
@@ -62,33 +57,24 @@ public class ConfigCommand implements LeavesSubcommand {
|
||||
Component.text(verifiedConfig.getString(), NamedTextColor.AQUA)
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String subCommand, String @NotNull [] args, @Nullable Location location, @NotNull LeavesSuggestionBuilder builder) {
|
||||
if (args.length <= 1) {
|
||||
String arg = args[0];
|
||||
int dotIndex = arg.lastIndexOf(".");
|
||||
builder.createOffset(builder.getInput().lastIndexOf(' ') + dotIndex + 2);
|
||||
LeavesCommandUtil.getListClosestMatchingLast(sender, arg.substring(dotIndex + 1), GlobalConfigManager.getVerifiedConfigSubPaths(arg), "bukkit.command.leaves.config")
|
||||
.forEach(builder::suggest);
|
||||
}
|
||||
if (args.length == 2) {
|
||||
VerifiedConfig verifiedConfig = GlobalConfigManager.getVerifiedConfig(args[0]);
|
||||
if (verifiedConfig != null) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, verifiedConfig.validator().valueSuggest());
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, verifiedConfig.validator().valueSuggest()).forEach(builder::suggest);
|
||||
} else {
|
||||
return Collections.singletonList("<ERROR CONFIG>");
|
||||
builder.suggest("<ERROR CONFIG>");
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> tabSuggestion(CommandSender sender, String subCommand, String @NotNull [] args, @Nullable Location location, @NotNull SuggestionsBuilder builder) {
|
||||
if (args.length == 1) {
|
||||
String arg = args[0];
|
||||
int dotIndex = arg.lastIndexOf(".");
|
||||
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + dotIndex + 2);
|
||||
LeavesCommandUtil.getListClosestMatchingLast(sender, arg.substring(dotIndex + 1), GlobalConfigManager.getVerifiedConfigSubPaths(arg), "bukkit.command.leaves.config")
|
||||
.forEach(builder::suggest);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,30 +9,26 @@ import net.minecraft.world.item.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.command.LeavesCommandUtil;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.util.HopperCounter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CounterCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (!LeavesConfig.modify.hopperCounter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Hopper Counter: ", NamedTextColor.GRAY),
|
||||
Component.text(HopperCounter.isEnabled(), HopperCounter.isEnabled() ? NamedTextColor.AQUA : NamedTextColor.GRAY)
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!HopperCounter.isEnabled()) {
|
||||
@@ -42,7 +38,6 @@ public class CounterCommand implements LeavesSubcommand {
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Hopper Counter is not enabled", NamedTextColor.RED));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DyeColor color = DyeColor.byName(args[0], null);
|
||||
@@ -50,20 +45,19 @@ public class CounterCommand implements LeavesSubcommand {
|
||||
HopperCounter counter = HopperCounter.getCounter(color);
|
||||
if (args.length < 2) {
|
||||
displayCounter(sender, counter, false);
|
||||
} else {
|
||||
switch (args[1]) {
|
||||
case "reset" -> {
|
||||
counter.reset(MinecraftServer.getServer());
|
||||
sender.sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Restarted "),
|
||||
Component.text(color.getName(), TextColor.color(color.getTextColor())),
|
||||
Component.text(" counter")
|
||||
));
|
||||
}
|
||||
case "realtime" -> displayCounter(sender, counter, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (args[1]) {
|
||||
case "reset" -> {
|
||||
counter.reset(MinecraftServer.getServer());
|
||||
sender.sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Restarted "),
|
||||
Component.text(color.getName(), TextColor.color(color.getTextColor())),
|
||||
Component.text(" counter")
|
||||
));
|
||||
}
|
||||
case "realtime" -> displayCounter(sender, counter, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args[0]) {
|
||||
@@ -77,8 +71,6 @@ public class CounterCommand implements LeavesSubcommand {
|
||||
sender.sendMessage(Component.text("Hopper Counter now is disabled", NamedTextColor.GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void displayCounter(CommandSender sender, @NotNull HopperCounter counter, boolean realTime) {
|
||||
@@ -88,35 +80,27 @@ public class CounterCommand implements LeavesSubcommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (!LeavesConfig.modify.hopperCounter) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
switch (args.length) {
|
||||
case 1 -> {
|
||||
if (!HopperCounter.isEnabled()) {
|
||||
return Collections.singletonList("enable");
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>(Arrays.stream(DyeColor.values()).map(DyeColor::getName).toList());
|
||||
list.add("reset");
|
||||
list.add("disable");
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, list);
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
if (!HopperCounter.isEnabled()) {
|
||||
builder.suggest("enable");
|
||||
return;
|
||||
}
|
||||
|
||||
case 2 -> {
|
||||
if (DyeColor.byName(args[0], null) != null) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, "reset", "realtime");
|
||||
}
|
||||
List<String> list = new ArrayList<>(Arrays.stream(DyeColor.values()).map(DyeColor::getName).toList());
|
||||
list.add("reset");
|
||||
list.add("disable");
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, list).forEach(builder::suggest);
|
||||
}
|
||||
if (args.length == 2) {
|
||||
if (DyeColor.byName(args[0], null) != null) {
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, "reset", "realtime").forEach(builder::suggest);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
public boolean isEnabled() {
|
||||
return LeavesConfig.modify.hopperCounter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,31 +12,30 @@ import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.command.LeavesCommandUtil;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
|
||||
public class PeacefulModeSwitchCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
World world;
|
||||
if (args.length == 0) {
|
||||
if (sender instanceof Player player) {
|
||||
world = player.getWorld();
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Must specify a world! ex: '/leaves peaceful world'", NamedTextColor.RED));
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
final String input = args[0];
|
||||
final World inputWorld = Bukkit.getWorld(input);
|
||||
if (inputWorld == null) {
|
||||
sender.sendMessage(Component.text("'" + input + "' is not a valid world!", NamedTextColor.RED));
|
||||
return true;
|
||||
return;
|
||||
} else {
|
||||
world = inputWorld;
|
||||
}
|
||||
@@ -69,20 +68,13 @@ public class PeacefulModeSwitchCommand implements LeavesSubcommand {
|
||||
Component.text("/", color),
|
||||
Component.text(limit, color)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args, Location location) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, this.suggestPeacefulModeSwitch(args));
|
||||
}
|
||||
|
||||
private List<String> suggestPeacefulModeSwitch(final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return new ArrayList<>(Bukkit.getWorlds().stream().map(World::getName).toList());
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, Bukkit.getWorlds().stream().map(World::getName).toList()).forEach(builder::suggest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,8 @@ import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
|
||||
|
||||
public class ReloadCommand implements LeavesSubcommand {
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
LeavesConfig.reload();
|
||||
sender.sendMessage(text("Leaves config reload complete.", GREEN));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,17 +19,19 @@ import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.command.LeavesCommandUtil;
|
||||
import org.leavesmc.leaves.command.LeavesSubcommand;
|
||||
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
|
||||
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
|
||||
import org.leavesmc.leaves.plugin.provider.configuration.LeavesPluginMeta;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
|
||||
@@ -41,48 +43,6 @@ public class ReportCommand implements LeavesSubcommand {
|
||||
private static final String NOT_VANILLA_URL = "https://github.com/LeavesMC/Leaves/issues/new?template=2-not-vanilla.yml&leaves-version=${version}";
|
||||
private static final String COMMAND_PERM = "bukkit.command.leaves.report";
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(text("Please select a report template: \"bug-report\" or \"not-vanilla\"", RED));
|
||||
return true;
|
||||
}
|
||||
if (args[0].equals("bug-report")) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MinecraftInternalPlugin.INSTANCE, () -> {
|
||||
sendOnSuccess(sender, BUG_REPORT_URL, Component.text("Successfully generated report url for \"bug-report\"", AQUA));
|
||||
});
|
||||
return true;
|
||||
} else if (args[0].equals("not-vanilla")) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MinecraftInternalPlugin.INSTANCE, () -> {
|
||||
sendOnSuccess(sender, NOT_VANILLA_URL, Component.text("Successfully generated report url for \"not-vanilla\"", AQUA));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage(text("The template" + args[0] + " does not exist! Please select a correct template: \"bug-report\" or \"not-vanilla\"", RED));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String subCommand, String[] args, Location location) {
|
||||
if (args.length <= 1) {
|
||||
return LeavesCommandUtil.getListMatchingLast(sender, args, List.of("bug-report", "not-vanilla"), COMMAND_PERM + ".", COMMAND_PERM);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void sendOnSuccess(CommandSender sender, String template, Component component) {
|
||||
String finalUrl = template
|
||||
.replace("${version}", URLEncoder.encode(Bukkit.getVersionMessage(), StandardCharsets.UTF_8))
|
||||
.replace("${plugins}", URLEncoder.encode(generatePluginMessage(), StandardCharsets.UTF_8))
|
||||
.replace("${datapacks}", URLEncoder.encode(generateDataPackMessage(), StandardCharsets.UTF_8));
|
||||
if (sender instanceof ConsoleCommandSender) {
|
||||
sender.sendMessage(component.append(text(", please copy it as you are running this command in console")));
|
||||
sender.sendMessage(text(finalUrl, AQUA).decorate(TextDecoration.UNDERLINED));
|
||||
} else {
|
||||
sender.sendMessage(component.append(text(", click this message to open")).decorate(TextDecoration.UNDERLINED).hoverEvent(Component.text("Click to open the report url", NamedTextColor.WHITE)).clickEvent(ClickEvent.openUrl(finalUrl)));
|
||||
}
|
||||
}
|
||||
|
||||
private static String generatePluginMessage() {
|
||||
final StringBuilder pluginList = new StringBuilder();
|
||||
|
||||
@@ -166,4 +126,40 @@ public class ReportCommand implements LeavesSubcommand {
|
||||
}
|
||||
return dataPackList.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(text("Please select a report template: \"bug-report\" or \"not-vanilla\"", RED));
|
||||
return;
|
||||
}
|
||||
if (args[0].equals("bug-report")) {
|
||||
CompletableFuture.runAsync(() -> sendOnSuccess(sender, BUG_REPORT_URL, Component.text("Successfully generated report url for \"bug-report\"", AQUA)));
|
||||
return;
|
||||
} else if (args[0].equals("not-vanilla")) {
|
||||
CompletableFuture.runAsync(() -> sendOnSuccess(sender, NOT_VANILLA_URL, Component.text("Successfully generated report url for \"not-vanilla\"", AQUA)));
|
||||
return;
|
||||
}
|
||||
sender.sendMessage(text("The template" + args[0] + " does not exist! Please select a correct template: \"bug-report\" or \"not-vanilla\"", RED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggest(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location, LeavesSuggestionBuilder builder) throws IllegalArgumentException {
|
||||
if (args.length <= 1) {
|
||||
LeavesCommandUtil.getListMatchingLast(sender, args, List.of("bug-report", "not-vanilla"), COMMAND_PERM + ".", COMMAND_PERM).forEach(builder::suggest);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOnSuccess(CommandSender sender, String template, Component component) {
|
||||
String finalUrl = template
|
||||
.replace("${version}", URLEncoder.encode(Bukkit.getVersionMessage(), StandardCharsets.UTF_8))
|
||||
.replace("${plugins}", URLEncoder.encode(generatePluginMessage(), StandardCharsets.UTF_8))
|
||||
.replace("${datapacks}", URLEncoder.encode(generateDataPackMessage(), StandardCharsets.UTF_8));
|
||||
if (sender instanceof ConsoleCommandSender) {
|
||||
sender.sendMessage(component.append(text(", please copy it as you are running this command in console")));
|
||||
sender.sendMessage(text(finalUrl, AQUA).decorate(TextDecoration.UNDERLINED));
|
||||
} else {
|
||||
sender.sendMessage(component.append(text(", click this message to open")).decorate(TextDecoration.UNDERLINED).hoverEvent(Component.text("Click to open the report url", NamedTextColor.WHITE)).clickEvent(ClickEvent.openUrl(finalUrl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,8 @@ import org.leavesmc.leaves.util.LeavesUpdateHelper;
|
||||
public class UpdateCommand implements LeavesSubcommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||
public void execute(CommandSender sender, String subCommand, String[] args) {
|
||||
sender.sendMessage(Component.text("Trying to update Leaves, see the console for more info.", NamedTextColor.GRAY));
|
||||
LeavesUpdateHelper.tryUpdateLeaves();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tabCompletes() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user