-
-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add commands to investigate waystones of any player as OP (#758)
* Add commands to investigate waystones of any player as OP - `/waystones [count|owned|activated] <player>` to count/list the target's waystones in chat - `/waystones gui <player>` open a Waystone selection menu listing the target's waystones A waystone is considered `owned` if the target Player UUID matches the waystone's `getOwnerUuid()`. Commands that list both owned and activated waystones of a given target player will list their owned waystones first. Within these categories, waystones are sorted by distance from the OP. * fix review comments + use Dimension in comparator
- Loading branch information
Showing
11 changed files
with
291 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
shared/src/main/java/net/blay09/mods/waystones/client/gui/screen/AdminSelectionScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package net.blay09.mods.waystones.client.gui.screen; | ||
|
||
import net.blay09.mods.waystones.menu.WaystoneSelectionMenu; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.world.entity.player.Inventory; | ||
|
||
public class AdminSelectionScreen extends WaystoneSelectionScreenBase { | ||
|
||
public AdminSelectionScreen(WaystoneSelectionMenu container, Inventory playerInventory, Component title) { | ||
super(container, playerInventory, title); | ||
} | ||
|
||
@Override | ||
protected boolean allowSorting() { | ||
return false; | ||
} | ||
|
||
@Override | ||
protected boolean allowDeletion() { | ||
return false; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
shared/src/main/java/net/blay09/mods/waystones/command/CountWaystonesCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package net.blay09.mods.waystones.command; | ||
|
||
import com.mojang.brigadier.Command; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import net.blay09.mods.waystones.api.IWaystone; | ||
import net.blay09.mods.waystones.core.PlayerWaystoneManager; | ||
import net.minecraft.commands.CommandSourceStack; | ||
import net.minecraft.commands.arguments.selector.EntitySelector; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.server.level.ServerPlayer; | ||
|
||
import java.util.List; | ||
|
||
public class CountWaystonesCommand implements Command<CommandSourceStack> { | ||
@Override | ||
public int run(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { | ||
ServerPlayer player = ctx.getArgument("player", EntitySelector.class).findSinglePlayer(ctx.getSource()); | ||
List<IWaystone> waystones = PlayerWaystoneManager.getWaystones(player); | ||
int total = waystones.size(); | ||
long owned = waystones.stream().filter(w -> w.isOwner(player)).count(); | ||
ctx.getSource().sendSuccess(() -> Component.literal("Player " + player.getScoreboardName() + " has " + total + " waystones activated and owns " + owned + " of these"), false); | ||
return waystones.size(); | ||
} | ||
} |
129 changes: 129 additions & 0 deletions
129
shared/src/main/java/net/blay09/mods/waystones/command/ListWaystonesCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package net.blay09.mods.waystones.command; | ||
|
||
import com.mojang.brigadier.Command; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import net.blay09.mods.waystones.api.IWaystone; | ||
import net.blay09.mods.waystones.core.PlayerWaystoneManager; | ||
import net.minecraft.ChatFormatting; | ||
import net.minecraft.commands.CommandSourceStack; | ||
import net.minecraft.commands.arguments.selector.EntitySelector; | ||
import net.minecraft.network.chat.ClickEvent; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.network.chat.MutableComponent; | ||
import net.minecraft.network.chat.Style; | ||
import net.minecraft.resources.ResourceKey; | ||
import net.minecraft.server.level.ServerLevel; | ||
import net.minecraft.server.level.ServerPlayer; | ||
import net.minecraft.world.entity.player.Player; | ||
import net.minecraft.world.level.Level; | ||
|
||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
public class ListWaystonesCommand implements Command<CommandSourceStack> { | ||
|
||
private final boolean listNotOwned; | ||
public ListWaystonesCommand(boolean listNotOwned) { | ||
this.listNotOwned = listNotOwned; | ||
} | ||
|
||
|
||
@Override | ||
public int run(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { | ||
ServerPlayer player = ctx.getArgument("player", EntitySelector.class).findSinglePlayer(ctx.getSource()); | ||
ServerPlayer op = ctx.getSource().getPlayerOrException(); | ||
|
||
Map<WaystoneOwnership, List<IWaystone>> all = ownedOrActivatedByDistance(player, op); | ||
List<IWaystone> owned = all.get(WaystoneOwnership.OWNED); | ||
List<IWaystone> others = all.get(WaystoneOwnership.ACTIVATED); | ||
|
||
String headerPart; | ||
String footerPart; | ||
if (this.listNotOwned) { | ||
headerPart = " (including not owned):"; | ||
footerPart = "total, " + owned.size() + " owned"; | ||
} else { | ||
others = Collections.emptyList(); | ||
headerPart = ":"; | ||
footerPart = "owned"; | ||
} | ||
|
||
ctx.getSource().sendSystemMessage(Component.literal("----")); | ||
ctx.getSource().sendSystemMessage(Component.literal("Player ").append(player.getScoreboardName()) | ||
.append(" waystones (x y z) coordinates").append(headerPart)); | ||
sendWaystoneList(ctx.getSource(), op, owned, true); | ||
if (this.listNotOwned) { | ||
sendWaystoneList(ctx.getSource(), op, others, false); | ||
} | ||
|
||
int total = (owned.size() + others.size()); | ||
ctx.getSource().sendSuccess(() -> Component.literal(total + " waystones " + footerPart), false); | ||
ctx.getSource().sendSystemMessage(Component.literal("----")); | ||
|
||
return total; | ||
} | ||
|
||
public static Map<WaystoneOwnership, List<IWaystone>> ownedOrActivatedByDistance(Player target, Player commandOp) { | ||
Comparator<IWaystone> distanceComparator = createDistanceComparator(commandOp); | ||
|
||
EnumMap<WaystoneOwnership, List<IWaystone>> ownedAndActivated = PlayerWaystoneManager.getWaystones(target) | ||
.stream() | ||
//we only mark as owned the waystones that are truly bound to the target player's uuid | ||
.collect(Collectors.groupingBy( | ||
w -> target.getGameProfile().getId().equals(w.getOwnerUid()) ? WaystoneOwnership.OWNED : WaystoneOwnership.ACTIVATED, | ||
() -> new EnumMap<>(WaystoneOwnership.class), | ||
Collectors.toList()) | ||
); | ||
|
||
List<IWaystone> owned = ownedAndActivated.computeIfAbsent(WaystoneOwnership.OWNED, k -> Collections.emptyList()); | ||
List<IWaystone> activated = ownedAndActivated.computeIfAbsent(WaystoneOwnership.ACTIVATED, k -> Collections.emptyList()); | ||
owned.sort(distanceComparator); | ||
activated.sort(distanceComparator); | ||
return ownedAndActivated; | ||
} | ||
|
||
public static Comparator<IWaystone> createDistanceComparator(final Player player) { | ||
return Comparator.comparingDouble(w -> { | ||
ResourceKey<Level> targetDimension = w.getDimension(); | ||
if (targetDimension == null) return Double.MAX_VALUE; | ||
if (!targetDimension.equals(player.level().dimension())) return Double.MAX_VALUE - 1; | ||
|
||
return player.position().distanceTo(w.getPos().getCenter()); | ||
}); | ||
} | ||
|
||
private void sendWaystoneList(CommandSourceStack source, ServerPlayer op, List<IWaystone> waystones, boolean owned) { | ||
final String ownedHeader; | ||
if (!owned) ownedHeader = "activated"; | ||
else if (this.listNotOwned) ownedHeader = " owned"; | ||
else ownedHeader = " "; | ||
waystones.forEach(w -> { | ||
MutableComponent c = Component.literal(" - ") | ||
.append(ownedHeader); | ||
|
||
MutableComponent coordinates = Component.literal(w.getPos().toShortString()).withStyle(ChatFormatting.YELLOW); | ||
MutableComponent distance; | ||
|
||
if (w.getDimension() != op.level().dimension()) { | ||
distance = Component.literal(w.getDimension().location().getPath()) | ||
.withStyle(ChatFormatting.ITALIC, ChatFormatting.YELLOW); | ||
c.append(" in ").append(distance).append(" at (").append(coordinates); | ||
} else { | ||
distance = Component.literal(String.valueOf((int) op.position().distanceTo(w.getPos().getCenter()))) | ||
.withStyle(ChatFormatting.BOLD); | ||
c.append(" at ").append(distance).append(" blocks away (").append(coordinates); | ||
} | ||
|
||
String suggestedCommand = "/execute in " + w.getDimension().location() + " run teleport " + | ||
w.getPos().toShortString().replaceAll(",", ""); | ||
c.append("): \"") | ||
.append(Component.literal(w.getName()) | ||
.withStyle(ChatFormatting.GREEN, ChatFormatting.UNDERLINE) | ||
.withStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggestedCommand)))) | ||
.append("\""); | ||
|
||
source.sendSystemMessage(c); | ||
}); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
shared/src/main/java/net/blay09/mods/waystones/command/ModCommands.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package net.blay09.mods.waystones.command; | ||
|
||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; | ||
import net.blay09.mods.balm.api.command.BalmCommands; | ||
import net.minecraft.commands.CommandSourceStack; | ||
import net.minecraft.commands.arguments.EntityArgument; | ||
|
||
import static net.minecraft.commands.Commands.argument; | ||
|
||
public class ModCommands { | ||
public static void initialize(BalmCommands commands) { | ||
commands.register(dispatcher -> dispatcher.register(LiteralArgumentBuilder.<CommandSourceStack>literal("waystones") | ||
.requires(source -> source.isPlayer() && source.hasPermission(2)) | ||
.then(LiteralArgumentBuilder.<CommandSourceStack>literal("count") | ||
.then(argument("player", EntityArgument.player()).executes(new CountWaystonesCommand()))) | ||
.then(LiteralArgumentBuilder.<CommandSourceStack>literal("owned") | ||
.then(argument("player", EntityArgument.player()).executes(new ListWaystonesCommand(false)))) | ||
.then(LiteralArgumentBuilder.<CommandSourceStack>literal("activated") | ||
.then(argument("player", EntityArgument.player()).executes(new ListWaystonesCommand(true)))) | ||
.then(LiteralArgumentBuilder.<CommandSourceStack>literal("gui") | ||
.then(argument("player", EntityArgument.player()).executes(new OpenPlayerWaystonesGuiCommand()))) | ||
)); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
shared/src/main/java/net/blay09/mods/waystones/command/OpenPlayerWaystonesGuiCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package net.blay09.mods.waystones.command; | ||
|
||
import com.mojang.brigadier.Command; | ||
import com.mojang.brigadier.context.CommandContext; | ||
import com.mojang.brigadier.exceptions.CommandSyntaxException; | ||
import net.blay09.mods.balm.api.Balm; | ||
import net.blay09.mods.balm.api.menu.BalmMenuProvider; | ||
import net.blay09.mods.waystones.api.IWaystone; | ||
import net.blay09.mods.waystones.core.Waystone; | ||
import net.blay09.mods.waystones.menu.WaystoneSelectionMenu; | ||
import net.minecraft.commands.CommandSourceStack; | ||
import net.minecraft.commands.arguments.selector.EntitySelector; | ||
import net.minecraft.network.FriendlyByteBuf; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.server.level.ServerPlayer; | ||
import net.minecraft.world.entity.player.Inventory; | ||
import net.minecraft.world.entity.player.Player; | ||
import net.minecraft.world.inventory.AbstractContainerMenu; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class OpenPlayerWaystonesGuiCommand implements Command<CommandSourceStack> { | ||
@Override | ||
public int run(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { | ||
ServerPlayer target = ctx.getArgument("player", EntitySelector.class).findSinglePlayer(ctx.getSource()); | ||
ServerPlayer op = ctx.getSource().getPlayerOrException(); | ||
BalmMenuProvider menuProvider = new BalmMenuProvider() { | ||
@Override | ||
public Component getDisplayName() { | ||
return Component.translatable( "container.waystones.waystone_admin_selection", target.getScoreboardName()); | ||
} | ||
|
||
@Override | ||
public AbstractContainerMenu createMenu(int i, Inventory playerInventory, Player playerEntity) { | ||
return WaystoneSelectionMenu.createAdminSelection(i, op, target); | ||
} | ||
|
||
@Override | ||
public void writeScreenOpeningData(ServerPlayer player, FriendlyByteBuf buf) { | ||
Map<WaystoneOwnership, List<IWaystone>> all = ListWaystonesCommand.ownedOrActivatedByDistance(player, op); | ||
List<IWaystone> waystones = new ArrayList<>(); | ||
waystones.addAll(all.get(WaystoneOwnership.OWNED)); | ||
waystones.addAll(all.get(WaystoneOwnership.ACTIVATED)); | ||
buf.writeInt(waystones.size()); | ||
waystones.forEach(w -> Waystone.write(buf, w)); | ||
} | ||
}; | ||
Balm.getNetworking().openGui(op, menuProvider); | ||
|
||
return 0; | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
shared/src/main/java/net/blay09/mods/waystones/command/WaystoneOwnership.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package net.blay09.mods.waystones.command; | ||
|
||
public enum WaystoneOwnership { | ||
OWNED, | ||
ACTIVATED | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters