From a83d04e912943df8c4e0847a6c98641a73d2ee2a Mon Sep 17 00:00:00 2001 From: senseiwells Date: Thu, 1 Aug 2024 17:07:30 +0100 Subject: [PATCH] Fixes #1958 --- .../java/carpet/commands/PlayerCommand.java | 5 ++++ .../carpet/patches/EntityPlayerMPFake.java | 24 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/carpet/commands/PlayerCommand.java b/src/main/java/carpet/commands/PlayerCommand.java index ee25a48d0..86753a988 100644 --- a/src/main/java/carpet/commands/PlayerCommand.java +++ b/src/main/java/carpet/commands/PlayerCommand.java @@ -190,6 +190,11 @@ private static boolean cantSpawn(CommandContext context) MinecraftServer server = context.getSource().getServer(); PlayerList manager = server.getPlayerList(); + if (EntityPlayerMPFake.isSpawningPlayer(playerName)) + { + Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is currently logging on"); + return true; + } if (manager.getPlayerByName(playerName) != null) { Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is already logged on"); diff --git a/src/main/java/carpet/patches/EntityPlayerMPFake.java b/src/main/java/carpet/patches/EntityPlayerMPFake.java index f7bbfbe5c..271b8e629 100644 --- a/src/main/java/carpet/patches/EntityPlayerMPFake.java +++ b/src/main/java/carpet/patches/EntityPlayerMPFake.java @@ -36,6 +36,7 @@ import carpet.fakes.ServerPlayerInterface; import carpet.utils.Messenger; +import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -43,6 +44,8 @@ @SuppressWarnings("EntityConstructor") public class EntityPlayerMPFake extends ServerPlayer { + private static final Set spawning = new HashSet<>(); + public Runnable fixStartingPosition = () -> {}; public boolean isAShadow; @@ -69,7 +72,21 @@ public static boolean createFake(String username, MinecraftServer server, Vec3 p } } GameProfile finalGP = gameprofile; - fetchGameProfile(gameprofile.getName()).thenAcceptAsync(p -> { + + // We need to mark this player as spawning so that we do not + // try to spawn another player with the name while the profile + // is being fetched - preventing multiple players spawning + String name = gameprofile.getName(); + spawning.add(name); + + fetchGameProfile(name).whenCompleteAsync((p, t) -> { + // Always remove the name, even if exception occurs + spawning.remove(name); + if (t != null) + { + return; + } + GameProfile current = finalGP; if (p.isPresent()) { @@ -127,6 +144,11 @@ public static EntityPlayerMPFake respawnFake(MinecraftServer server, ServerLevel return new EntityPlayerMPFake(server, level, profile, cli, false); } + public static boolean isSpawningPlayer(String username) + { + return spawning.contains(username); + } + private EntityPlayerMPFake(MinecraftServer server, ServerLevel worldIn, GameProfile profile, ClientInformation cli, boolean shadow) { super(server, worldIn, profile, cli);