Skip to content

Commit da3cd68

Browse files
committed
Add whois command
1 parent 8a36a44 commit da3cd68

File tree

7 files changed

+113
-5
lines changed

7 files changed

+113
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [1.4.6] - 2025-12-01
10+
### Added
11+
- `/whois <target>` command
12+
913
## [1.4.5] - 2025-11-15
1014
### Added
1115
- Simple `/repair` command

COMMANDS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
| `/fly [<player>]` | | `fabric-essentials.command.fly` ||
3939
| `/flyspeed [<flyspeed>] [<target>]` | | `fabric-essentials.command.flyspeed` ||
4040
| `/walkspeed [<walkspeed>] [<target>]` | | `fabric-essentials.command.walkspeed` ||
41+
| `/whois <target>` | | `fabric-essentials.command.whois` ||
4142
| `/invulnerable [<player>]` | `/godmode` | `fabric-essentials.command.invulnerable` ||
4243
| `/tellmessage <targets> <message>` | | `fabric-essentials.command.tellmessage` ||
4344
| `/message-to-vanilla quicktext <message>`, `/message-to-vanilla simplifiedtext <message>` | | `fabric-essentials.command.message-to-vanilla` ||

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ modrinth_minecraft_versions=[VERSIONED]
88
java_version=[VERSIONED]
99
loader_version=0.17.3
1010
# Mod Properties
11-
mod_version=1.4.5
11+
mod_version=1.4.6
1212
maven_group=me.drex
1313
archives_base_name=fabric-essentials
1414
# Dependencies

src/main/java/me/drex/essentials/command/CommandManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class CommandManager {
7979
new FlyCommand(),
8080
new FlySpeedCommand(),
8181
new WalkSpeedCommand(),
82+
new WhoIsCommand(),
8283
new InvulnerableCommand(),
8384
new TellMessageCommand(),
8485
new MessageToVanilla(),
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package me.drex.essentials.command.impl.misc;
2+
3+
import com.mojang.authlib.GameProfile;
4+
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
5+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
6+
import com.mojang.serialization.Dynamic;
7+
import eu.pb4.placeholders.api.PlaceholderContext;
8+
import me.drex.essentials.command.Command;
9+
import me.drex.essentials.command.CommandProperties;
10+
import net.fabricmc.fabric.impl.event.interaction.FakePlayerNetworkHandler;
11+
import net.minecraft.commands.CommandBuildContext;
12+
import net.minecraft.commands.CommandSourceStack;
13+
import net.minecraft.commands.Commands;
14+
import net.minecraft.commands.arguments.EntityArgument;
15+
import net.minecraft.commands.arguments.GameProfileArgument;
16+
import net.minecraft.nbt.CompoundTag;
17+
import net.minecraft.nbt.NbtOps;
18+
import net.minecraft.resources.ResourceKey;
19+
import net.minecraft.server.MinecraftServer;
20+
import net.minecraft.server.level.ClientInformation;
21+
import net.minecraft.server.level.ServerLevel;
22+
import net.minecraft.server.level.ServerPlayer;
23+
//? if >= 1.21.9 {
24+
import net.minecraft.server.players.NameAndId;
25+
import net.minecraft.world.level.storage.TagValueInput;
26+
//?}
27+
import net.minecraft.server.players.PlayerList;
28+
import net.minecraft.world.level.Level;
29+
import net.minecraft.world.level.dimension.DimensionType;
30+
//? if >= 1.21.6 {
31+
import net.minecraft.util.ProblemReporter;
32+
import net.minecraft.world.level.storage.ValueInput;
33+
//?}
34+
35+
import java.util.Collection;
36+
import java.util.Collections;
37+
import java.util.Optional;
38+
39+
import static me.drex.message.api.LocalizedMessage.localized;
40+
41+
public class WhoIsCommand extends Command {
42+
public WhoIsCommand() {
43+
super(CommandProperties.create("whois", 2));
44+
}
45+
46+
@Override
47+
protected void registerArguments(LiteralArgumentBuilder<CommandSourceStack> literal, CommandBuildContext commandBuildContext) {
48+
literal.then(
49+
Commands.argument("target", GameProfileArgument.gameProfile())
50+
.executes(ctx -> whois(ctx.getSource(), GameProfileArgument.getGameProfiles(ctx, "target")))
51+
);
52+
}
53+
54+
private int whois(CommandSourceStack source, Collection</*? if >= 1.21.9 {*/ NameAndId /*?} else {*/ /*GameProfile *//*?}*/> targets) throws CommandSyntaxException {
55+
if (targets.isEmpty()) throw EntityArgument.NO_PLAYERS_FOUND.create();
56+
if (targets.size() > 1) throw EntityArgument.ERROR_NOT_SINGLE_PLAYER.create();
57+
var target = targets.iterator().next();
58+
MinecraftServer server = source.getServer();
59+
60+
ServerPlayer serverPlayer = loadPlayer(server, target);
61+
source.sendSuccess(() -> localized("fabric-essentials.commands.whois", Collections.emptyMap(), PlaceholderContext.of(serverPlayer)), false);
62+
return 1;
63+
}
64+
65+
private ServerPlayer loadPlayer(MinecraftServer server, /*? if >= 1.21.9 {*/ NameAndId /*?} else {*/ /*GameProfile *//*?}*/ target) {
66+
PlayerList playerList = server.getPlayerList();
67+
ServerPlayer player = playerList.getPlayer(/*? if >= 1.21.9 {*/ target.id()/*?} else {*/ /*target.getId()*/ /*?}*/);
68+
if (player != null) return player;
69+
70+
ServerPlayer serverPlayer = new ServerPlayer(server, server.overworld(), /*? if >= 1.21.9 {*/ new GameProfile(target.id(), target.name()) /*?} else {*/ /*target *//*?}*/, ClientInformation.createDefault());
71+
new FakePlayerNetworkHandler(serverPlayer);
72+
//? if >= 1.21.6 {
73+
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(serverPlayer.problemPath(), LOGGER)) {
74+
//? if >= 1.21.9 {
75+
Optional<ValueInput> optional = playerList.loadPlayerData(target)
76+
.map(compoundTag -> TagValueInput.create(scopedCollector, server.registryAccess(), compoundTag));
77+
optional.ifPresent(serverPlayer::load);
78+
//?} else {
79+
/*Optional<ValueInput> optional = playerList.load(serverPlayer, scopedCollector);
80+
ResourceKey<Level> resourceKey = optional.flatMap(valueInput -> valueInput.read("Dimension", Level.RESOURCE_KEY_CODEC))
81+
.orElse(Level.OVERWORLD);
82+
ServerLevel serverLevel = server.getLevel(resourceKey);
83+
if (serverLevel == null) {
84+
serverLevel = server.overworld();
85+
}
86+
serverPlayer.setServerLevel(serverLevel);
87+
*///?}
88+
}
89+
//?} else {
90+
/*Optional<CompoundTag> optional = playerList.load(serverPlayer);
91+
ResourceKey<Level> resourceKey = optional.flatMap(compoundTag -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))).resultOrPartial(LOGGER::error)).orElse(Level.OVERWORLD);
92+
ServerLevel serverLevel = server.getLevel(resourceKey);
93+
if (serverLevel == null) {
94+
serverLevel = server.overworld();
95+
}
96+
serverPlayer.setServerLevel(serverLevel);
97+
*///?}
98+
return serverPlayer;
99+
}
100+
}

src/main/java/me/drex/essentials/util/AsyncChunkLoadUtil.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public class AsyncChunkLoadUtil {
2121
//? if >= 1.21.9 {
2222
public static final TicketType ASYNC_CHUNK_LOAD = new TicketType(0L, TicketType.FLAG_LOADING);
2323
//?} else if >= 1.21.5 {
24-
// public static final TicketType ASYNC_CHUNK_LOAD = register("essentials_async_chunk_load", 0L, false, TicketType.TicketUse.LOADING);
25-
//?} else {
24+
/*public static final TicketType ASYNC_CHUNK_LOAD = register("essentials_async_chunk_load", 0L, false, TicketType.TicketUse.LOADING);
25+
*///?} else {
2626
/*public static final TicketType<Unit> ASYNC_CHUNK_LOAD = TicketType.create("essentials_async_chunk_load", (unit, unit2) -> 0);
2727
*///?}
2828
public static CompletableFuture<ChunkResult<ChunkAccess>> scheduleChunkLoadWithRadius(ServerLevel world, ChunkPos pos, int radius) {
@@ -70,6 +70,6 @@ public static CompletableFuture<ChunkResult<ChunkAccess>> scheduleChunkLoadWithL
7070
//? if >= 1.21.5 && <= 1.21.8 {
7171
/*private static TicketType register(String string, long l, boolean bl, TicketType.TicketUse ticketUse) {
7272
return Registry.register(BuiltInRegistries.TICKET_TYPE, string, new TicketType(l, bl, ticketUse));
73-
}*/
74-
//?}
73+
}
74+
*///?}
7575
}

src/main/resources/messages/en_us.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@
131131
"fabric-essentials.commands.warps.list.separator": "<gray>, </gray>",
132132
"fabric-essentials.commands.warps.list.element": "<hover:show_text:'<gray>Pos: <white>${location_pos_x} ${location_pos_y} ${location_pos_z}\n<gray>World: <white>${location_dimension}\n<aqua>Click to teleport!'><run_cmd:'/warp ${warp_name}'><yellow>${warp_name}",
133133

134+
"fabric-essentials.commands.whois": "<gold><bold>Whois %player:name%</bold></gold>\n<gold>Display Name:</gold> <yellow>%player:displayname%</yellow>\n<gold>UUID:</gold> <yellow><hover show_text '<aqua>Click to copy!'><click copy_to_clipboard '%player:uuid%'>%player:uuid%</click></hover></yellow>\n<gold>Position:</gold> <hover show_text '<aqua>Click to teleport!'><click run_command '/execute in %world:id% run tp @s %player:pos_x% %player:pos_y% %player:pos_z%'><yellow>%player:pos_x% %player:pos_y% %player:pos_z%</yellow> <gold>in</gold> <yellow>%world:id%</yellow></click></hover>\n<gold>Playtime:</gold> <yellow>%player:playtime%</yellow>",
135+
134136
"fabric-essentials.commandspy": "<dark_gray>[<light_purple>CommandSpy<dark_gray>] <dark_gray>[<reset>%player:displayname%<dark_gray>] <hover:show_text:'Click to copy!'><click:copy_to_clipboard:'/${command}'><gray>/${command}",
135137

136138
"fabric-essentials.location.world.unknown": "<red>The target world no longer exists!",

0 commit comments

Comments
 (0)