1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2026-01-06 15:41:50 +00:00

Attempt to resolve pack download issues for consoles

This commit is contained in:
onebeastchris
2025-06-09 00:12:15 +02:00
parent 115d709706
commit baec73d38d
2 changed files with 45 additions and 6 deletions

View File

@@ -52,6 +52,7 @@ import org.cloudburstmc.protocol.bedrock.packet.ResourcePacksInfoPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket;
import org.cloudburstmc.protocol.common.PacketSignal;
import org.cloudburstmc.protocol.common.util.Zlib;
import org.geysermc.api.util.BedrockPlatform;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
@@ -80,7 +81,10 @@ import java.nio.channels.SeekableByteChannel;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.OptionalInt;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class UpstreamPacketHandler extends LoggingPacketHandler {
@@ -88,6 +92,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
private final Deque<String> packsToSend = new ArrayDeque<>();
private final CompressionStrategy compressionStrategy;
private static final int PACKET_SEND_DELAY = 4 * 50; // DELAY THE SEND OF PACKETS TO AVOID BURSTING SLOWER AND/OR HIGHER PING CLIENTS
private final Queue<ResourcePackChunkRequestPacket> chunkRequestQueue = new ConcurrentLinkedQueue<>();
private boolean sendingChunks = false;
private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
@@ -297,13 +305,33 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
chunkRequestQueue.add(packet);
if (isConsole()) {
if (!sendingChunks) {
sendingChunks = true;
processNextChunk();
}
} else {
processNextChunk();
}
return PacketSignal.HANDLED;
}
public void processNextChunk() {
ResourcePackChunkRequestPacket packet = chunkRequestQueue.poll();
if (packet == null) {
sendingChunks = false;
return;
}
ResourcePackHolder holder = this.resourcePackLoadEvent.getPacks().get(packet.getPackId());
if (holder == null) {
GeyserImpl.getInstance().getLogger().debug("Client {0} tried to request pack id {1} not sent to it!",
session.bedrockUsername(), packet.getPackId());
sendingChunks = false;
session.disconnect("disconnectionScreen.resourcePack");
return PacketSignal.HANDLED;
return;
}
ResourcePack pack = holder.pack();
@@ -316,7 +344,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
if (!resourcePackLoadEvent.value(pack.uuid(), ResourcePackOption.Type.FALLBACK, true)) {
session.disconnect("Unable to provide downloaded resource pack. Contact an administrator!");
return PacketSignal.HANDLED;
sendingChunks = false;
return;
}
}
@@ -339,14 +368,19 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
data.setData(Unpooled.wrappedBuffer(packData));
session.sendUpstreamPacket(data);
if (isConsole()) {
// Also flushes packets
// Avoids bursting slower / delayed clients
session.sendUpstreamPacketImmediately(data);
GeyserImpl.getInstance().getScheduledThread().schedule(this::processNextChunk, PACKET_SEND_DELAY, TimeUnit.MILLISECONDS);
} else {
session.sendUpstreamPacket(data);
}
// Check if it is the last chunk and send next pack in queue when available.
if (remainingSize <= GeyserResourcePack.CHUNK_SIZE && !packsToSend.isEmpty()) {
sendPackDataInfo(packsToSend.pop());
}
return PacketSignal.HANDLED;
}
private void sendPackDataInfo(String id) {
@@ -394,4 +428,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
session.sendUpstreamPacket(data);
}
private boolean isConsole() {
BedrockPlatform platform = session.platform();
return platform == BedrockPlatform.PS4 || platform == BedrockPlatform.XBOX || platform == BedrockPlatform.NX;
}
}

View File

@@ -41,7 +41,7 @@ public record GeyserResourcePack(
/**
* The size of each chunk to use when sending the resource packs to clients in bytes
*/
public static final int CHUNK_SIZE = 102400;
public static final int CHUNK_SIZE = 1024 * 256;
public static class Builder implements ResourcePack.Builder {