Document, add preliminary resource pack support.

This commit is contained in:
Owen1212055 2025-04-16 13:38:58 -04:00
parent 83d4a9dbcf
commit d929733f77
No known key found for this signature in database
GPG Key ID: 2133292072886A30
8 changed files with 84 additions and 22 deletions

View File

@ -1,9 +1,14 @@
package io.papermc.paper.connection;
import net.kyori.adventure.resource.ResourcePackRequest;
import net.kyori.adventure.resource.ResourcePackRequestLike;
import org.bukkit.ServerLinks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.NullMarked;
import java.util.Map;
import java.util.UUID;
/**
* Represents a connection that has properties shared between the GAME and CONFIG stage.
@ -11,6 +16,12 @@ import java.util.Map;
@NullMarked
public interface PlayerCommonConnection extends CookieConnection {
void sendResourcePacks(final @NotNull ResourcePackRequest request);
void removeResourcePacks(final @NotNull UUID id, final @NotNull UUID... others);
void clearResourcePacks();
/**
* Sends data to appear in this connection's report logs.
* This is useful for debugging server state that may be causing

View File

@ -3,7 +3,9 @@ package io.papermc.paper.event.connection.configuration;
import io.papermc.paper.connection.PlayerConfigurationConnection;
import io.papermc.paper.connection.PlayerLoginConnection;
import org.bukkit.event.Event;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
abstract class PlayerConfigurationConnectionEvent extends Event {
private final PlayerConfigurationConnection loginConnection;

View File

@ -304,6 +304,11 @@ public class AsyncPlayerPreLoginEvent extends Event {
return this.transferred;
}
/**
* Gets the connection for the player logging in.
* @return connection
*/
@NotNull
public PlayerLoginConnection getPlayerLoginConnection() {
return playerLoginConnection;
}

View File

@ -1,8 +1,8 @@
package org.bukkit.event.player;
import io.papermc.paper.connection.PlayerCommonConnection;
import io.papermc.paper.connection.PlayerConfigurationConnection;
import org.bukkit.ServerLinks;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
@ -17,11 +17,11 @@ public class PlayerLinksSendEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ServerLinks links;
private final PlayerConfigurationConnection configurationConnection;
private final PlayerCommonConnection connection;
@ApiStatus.Internal
public PlayerLinksSendEvent(@NotNull final PlayerConfigurationConnection connection, @NotNull final ServerLinks links) {
this.configurationConnection = connection;
this.connection = connection;
this.links = links;
}
@ -29,8 +29,9 @@ public class PlayerLinksSendEvent extends Event {
* Gets the connection that received the links.
* @return connection
*/
public PlayerConfigurationConnection getConfigurationConnection() {
return configurationConnection;
@NotNull
public PlayerCommonConnection getConnection() {
return connection;
}
/**

View File

@ -336,10 +336,10 @@ index 7de11ba404f0b60e7f7b7c16954811a343688219..bd07e6a5aa1883786d789ea71711a0c0
this.channels
.add(
diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index fc82af47a6be4afc7380d317b0ab91e95860ef26..4261db0f3b274632964323ff499961d9e7b5e2de 100644
index 7b85b777bec03370d0886a357e7937e14fc63b95..f37d43d1c31037ff810977ecd125f662956c2ee3 100644
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -253,11 +253,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
@@ -255,11 +255,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
}
SecretKey secretKey = packet.getSecretKey(_private);

View File

@ -67,13 +67,26 @@
}
}
@@ -97,21 +_,28 @@
@@ -97,21 +_,40 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id());
- this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"));
- }
+ this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"), io.papermc.paper.connection.DisconnectionReason.RESOURCE_PACK_REJECTION); // Paper - kick event cause
}
+ }
+ // Paper start - adventure pack callbacks
+ // call the callbacks before the previously-existing event so the event has final say
+ final net.kyori.adventure.resource.ResourcePackCallback callback;
+ if (packet.action().isTerminal()) {
+ callback = this.packCallbacks.remove(packet.id());
+ } else {
+ callback = this.packCallbacks.get(packet.id());
+ }
+ if (callback != null) {
+ callback.packEventReceived(packet.id(), net.kyori.adventure.resource.ResourcePackStatus.valueOf(packet.action().name()), null); // TODO TODO:
+ }
+ // Paper end
}
@Override

View File

@ -2591,7 +2591,7 @@
if (!this.receivedMovementThisTick) {
this.player.setKnownMovement(Vec3.ZERO);
}
@@ -2048,4 +_,156 @@
@@ -2048,4 +_,144 @@
interface EntityInteraction {
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
}
@ -2701,18 +2701,6 @@
+ @Override
+ public void handleResourcePackResponse(final net.minecraft.network.protocol.common.ServerboundResourcePackPacket packet) {
+ super.handleResourcePackResponse(packet);
+ // Paper start - adventure pack callbacks
+ // call the callbacks before the previously-existing event so the event has final say
+ final net.kyori.adventure.resource.ResourcePackCallback callback;
+ if (packet.action().isTerminal()) {
+ callback = this.packCallbacks.remove(packet.id());
+ } else {
+ callback = this.packCallbacks.get(packet.id());
+ }
+ if (callback != null) {
+ callback.packEventReceived(packet.id(), net.kyori.adventure.resource.ResourcePackStatus.valueOf(packet.action().name()), this.getCraftPlayer());
+ }
+ // Paper end
+ // Paper start - store last pack status
+ org.bukkit.event.player.PlayerResourcePackStatusEvent.Status packStatus = org.bukkit.event.player.PlayerResourcePackStatusEvent.Status.values()[packet.action().ordinal()];
+ this.player.getBukkitEntity().resourcePackStatus = packStatus;

View File

@ -1,15 +1,25 @@
package io.papermc.paper.connection;
import io.papermc.paper.adventure.PaperAdventure;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import net.kyori.adventure.resource.ResourcePackRequest;
import net.kyori.adventure.resource.ResourcePackRequestLike;
import net.kyori.adventure.text.Component;
import net.minecraft.network.protocol.common.ClientboundCustomReportDetailsPacket;
import net.minecraft.network.protocol.common.ClientboundResourcePackPopPacket;
import net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket;
import net.minecraft.network.protocol.common.ClientboundServerLinksPacket;
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
import org.bukkit.ServerLinks;
import org.bukkit.craftbukkit.CraftServerLinks;
import org.jetbrains.annotations.NotNull;
public abstract class PaperCommonConnection<T extends ServerCommonPacketListenerImpl> extends CommonCookieConnection implements PlayerCommonConnection {
@ -20,6 +30,38 @@ public abstract class PaperCommonConnection<T extends ServerCommonPacketListener
this.handle = serverConfigurationPacketListenerImpl;
}
@Override
public void sendResourcePacks(@NotNull ResourcePackRequest request) {
final List<ClientboundResourcePackPushPacket> packs = new java.util.ArrayList<>(request.packs().size());
if (request.replace()) {
this.clearResourcePacks();
}
final net.minecraft.network.chat.Component prompt = io.papermc.paper.adventure.PaperAdventure.asVanilla(request.prompt());
for (final java.util.Iterator<net.kyori.adventure.resource.ResourcePackInfo> iter = request.packs().iterator(); iter.hasNext();) {
final net.kyori.adventure.resource.ResourcePackInfo pack = iter.next();
packs.add(new ClientboundResourcePackPushPacket(pack.id(), pack.uri().toASCIIString(), pack.hash(), request.required(), iter.hasNext() ? Optional.empty() : Optional.ofNullable(prompt)));
if (request.callback() != net.kyori.adventure.resource.ResourcePackCallback.noOp()) {
this.handle.packCallbacks.put(pack.id(), request.callback()); // just override if there is a previously existing callback
}
}
this.sendBundle(packs);
}
@Override
public void removeResourcePacks(@NotNull UUID id, @NotNull UUID... others) {
this.sendBundle(net.kyori.adventure.util.MonkeyBars.nonEmptyArrayToList(pack -> new ClientboundResourcePackPopPacket(Optional.of(pack)), id, others));
}
@Override
public void clearResourcePacks() {
this.handle.connection.send(new ClientboundResourcePackPopPacket(Optional.empty()));
}
@SuppressWarnings({"unchecked", "rawtypes"})
void sendBundle(final List<? extends net.minecraft.network.protocol.Packet<? extends net.minecraft.network.protocol.common.ClientCommonPacketListener>> packet) {
this.handle.connection.send(new net.minecraft.network.protocol.game.ClientboundBundlePacket((List) packet));
}
@Override
public void sendReportDetails(final Map<String, String> details) {
this.handle.send(new ClientboundCustomReportDetailsPacket(details));