From 08c5c3db31626e7df2188f96bae4e192dc7c6e93 Mon Sep 17 00:00:00 2001 From: gnembon <41132274+gnembon@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:04:40 +0200 Subject: [PATCH] fix player skins not showing properly --- .../java/carpet/commands/PlayerCommand.java | 7 +-- .../carpet/patches/EntityPlayerMPFake.java | 53 +++++++++++-------- src/main/resources/carpet.accesswidener | 3 ++ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/main/java/carpet/commands/PlayerCommand.java b/src/main/java/carpet/commands/PlayerCommand.java index 9cfbd1ec..6bbde955 100644 --- a/src/main/java/carpet/commands/PlayerCommand.java +++ b/src/main/java/carpet/commands/PlayerCommand.java @@ -293,13 +293,10 @@ public class PlayerCommand Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world"); return 0; } - Player player = EntityPlayerMPFake.createFake(playerName, source.getServer(), pos, facing.y, facing.x, dimType, mode, flying); - if (player == null) - { + EntityPlayerMPFake.createFake(playerName, source.getServer(), pos, facing.y, facing.x, dimType, mode, flying, () -> { Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " + "Turn the server offline to spawn non-existing players"); - return 0; - } + }); return 1; } diff --git a/src/main/java/carpet/patches/EntityPlayerMPFake.java b/src/main/java/carpet/patches/EntityPlayerMPFake.java index 6c8cb8d8..db022230 100644 --- a/src/main/java/carpet/patches/EntityPlayerMPFake.java +++ b/src/main/java/carpet/patches/EntityPlayerMPFake.java @@ -31,7 +31,8 @@ import net.minecraft.world.phys.Vec3; import carpet.fakes.ServerPlayerInterface; import carpet.utils.Messenger; -import java.util.concurrent.atomic.AtomicReference; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; @SuppressWarnings("EntityConstructor") public class EntityPlayerMPFake extends ServerPlayer @@ -39,7 +40,7 @@ public class EntityPlayerMPFake extends ServerPlayer public Runnable fixStartingPosition = () -> {}; public boolean isAShadow; - public static EntityPlayerMPFake createFake(String username, MinecraftServer server, Vec3 pos, double yaw, double pitch, ResourceKey dimensionId, GameType gamemode, boolean flying) + public static void createFake(String username, MinecraftServer server, Vec3 pos, double yaw, double pitch, ResourceKey dimensionId, GameType gamemode, boolean flying, Runnable onError) { //prolly half of that crap is not necessary, but it works ServerLevel worldIn = server.getLevel(dimensionId); @@ -55,31 +56,37 @@ public class EntityPlayerMPFake extends ServerPlayer { if (!CarpetSettings.allowSpawningOfflinePlayers) { - return null; + onError.run(); + return; } else { gameprofile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(username), username); } } - if (gameprofile.getProperties().containsKey("textures")) - { - AtomicReference result = new AtomicReference<>(); - //SkullBlockEntity.updateGameprofile(gameprofile, result::set); - //gameprofile = result.get(); - } - EntityPlayerMPFake instance = new EntityPlayerMPFake(server, worldIn, gameprofile, false); - instance.fixStartingPosition = () -> instance.moveTo(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); - server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), instance, 0); - instance.teleportTo(worldIn, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); - instance.setHealth(20.0F); - instance.unsetRemoved(); - instance.setMaxUpStep(0.6F); - instance.gameMode.changeGameModeForPlayer(gamemode); - server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(instance, (byte) (instance.yHeadRot * 256 / 360)), dimensionId);//instance.dimension); - server.getPlayerList().broadcastAll(new ClientboundTeleportEntityPacket(instance), dimensionId);//instance.dimension); - //instance.world.getChunkManager(). updatePosition(instance); - instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes) - instance.getAbilities().flying = flying; - return instance; + GameProfile finalGP = gameprofile; + fetchGameProfile(gameprofile.getName()).thenAccept(p -> { + GameProfile current = finalGP; + if (p.isPresent()) + { + current = p.get(); + } + EntityPlayerMPFake instance = new EntityPlayerMPFake(server, worldIn, current, false); + instance.fixStartingPosition = () -> instance.moveTo(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); + server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), instance, 0); + instance.teleportTo(worldIn, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); + instance.setHealth(20.0F); + instance.unsetRemoved(); + instance.setMaxUpStep(0.6F); + instance.gameMode.changeGameModeForPlayer(gamemode); + server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(instance, (byte) (instance.yHeadRot * 256 / 360)), dimensionId);//instance.dimension); + server.getPlayerList().broadcastAll(new ClientboundTeleportEntityPacket(instance), dimensionId);//instance.dimension); + //instance.world.getChunkManager(). updatePosition(instance); + instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes) + instance.getAbilities().flying = flying; + }); + } + + private static CompletableFuture> fetchGameProfile(final String name) { + return SkullBlockEntity.fetchGameProfile(name); } public static EntityPlayerMPFake createShadow(MinecraftServer server, ServerPlayer player) diff --git a/src/main/resources/carpet.accesswidener b/src/main/resources/carpet.accesswidener index ebfed8ee..8aa2dafe 100644 --- a/src/main/resources/carpet.accesswidener +++ b/src/main/resources/carpet.accesswidener @@ -10,8 +10,11 @@ accessible class net/minecraft/server/MinecraftServer$ReloadableResources accessible class net/minecraft/world/level/biome/Biome$ClimateSettings accessible class net/minecraft/world/level/block/entity/SculkSensorBlockEntity$VibrationUser +#TODO fields and methods should be fetched via interfaces unless there is a good reason not to accessible method net/minecraft/world/level/border/WorldBorder getListeners ()Ljava/util/List; accessible method net/minecraft/server/level/DistanceManager purgeStaleTickets ()V +#cause I don't want to deal with the interfaces until stuff is stable +accessible method net/minecraft/world/level/block/entity/SkullBlockEntity fetchGameProfile (Ljava/lang/String;)Ljava/util/concurrent/CompletableFuture; accessible field net/minecraft/world/level/block/state/BlockBehaviour UPDATE_SHAPE_ORDER [Lnet/minecraft/core/Direction;