diff --git a/paper-server/patches/sources/net/minecraft/server/network/config/PrepareSpawnTask.java.patch b/paper-server/patches/sources/net/minecraft/server/network/config/PrepareSpawnTask.java.patch index b6b4c0c7b902..301e68fc2fe9 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/config/PrepareSpawnTask.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/config/PrepareSpawnTask.java.patch @@ -156,7 +156,7 @@ ChunkPos spawnChunk = ChunkPos.containing(BlockPos.containing(spawnPosition)); this.chunkLoadCounter .track( -@@ -172,14 +_,47 @@ +@@ -172,14 +_,48 @@ public ServerPlayer spawn(final Connection connection, final CommonListenerCookie cookie) { ChunkPos spawnChunk = ChunkPos.containing(BlockPos.containing(this.spawnPosition)); this.spawnLevel.waitForEntities(spawnChunk, 3); @@ -174,6 +174,7 @@ + player = new ServerPlayer(PrepareSpawnTask.this.server, this.spawnLevel, cookie.gameProfile(), cookie.clientInformation()); + } + // Paper end - configuration api - possibly use legacy saved server player instance ++ PrepareSpawnTask.this.listener.paperConnection.applyPendingEntityId(player); // Paper - internal entity id api - possibly override player network id if plugins used internal API to configure it. try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(player.problemPath(), PrepareSpawnTask.LOGGER)) { Optional input = PrepareSpawnTask.this.server diff --git a/paper-server/src/main/java/io/papermc/paper/connection/PaperPlayerConfigurationConnection.java b/paper-server/src/main/java/io/papermc/paper/connection/PaperPlayerConfigurationConnection.java index 49ea407cd912..a49fcd92382f 100644 --- a/paper-server/src/main/java/io/papermc/paper/connection/PaperPlayerConfigurationConnection.java +++ b/paper-server/src/main/java/io/papermc/paper/connection/PaperPlayerConfigurationConnection.java @@ -31,6 +31,7 @@ import net.minecraft.network.protocol.configuration.ClientboundResetChatPacket; import net.minecraft.resources.Identifier; import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ConfigurationTask; import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; import org.bukkit.plugin.Plugin; @@ -40,11 +41,33 @@ public class PaperPlayerConfigurationConnection extends PaperCommonConnection implements PlayerConfigurationConnection, Audience, PluginMessageBridgeImpl { private @Nullable Pointers adventurePointers; + private @Nullable Integer internalPluginDefinedEntityId; public PaperPlayerConfigurationConnection(final ServerConfigurationPacketListenerImpl packetListener) { super(packetListener); } + /** + * Internal only API that allows plugins to assign a specific entity network id to the player instance once + * configuration phase finishes. + *

+ * It is fully up to the calling plugin to ensure that no other entity has or will have the passed entity id. + * Additionally, as with any other internal API, no backwards compatibility is guaranteed across versions or builds. + * Use at own risk. + * + * @param entityId the network entity id to assign to the player. + */ + public void setInternalPluginDefinedEntityId(final int entityId) { + this.internalPluginDefinedEntityId = entityId; + } + + // Part of the above internal API. + public void applyPendingEntityId(final ServerPlayer player) { + if (this.internalPluginDefinedEntityId != null) { + player.setId(this.internalPluginDefinedEntityId); + } + } + @Override public ClientInformation getClientInformation() { return this.packetListener.clientInformation;