From f505f132162f6cac0ac6aa451f9c5b123829f822 Mon Sep 17 00:00:00 2001 From: Kevin Ludwig <32491319+valaphee@users.noreply.github.com> Date: Thu, 24 Nov 2022 21:19:55 +0100 Subject: [PATCH] Fix issues with sending multiple Bedrock resource packs (#3416) --- .../geyser/network/UpstreamPacketHandler.java | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java index c2a91fd75..227f0ed5a 100644 --- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java +++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java @@ -46,9 +46,13 @@ import org.geysermc.geyser.util.MathUtils; import java.io.FileInputStream; import java.io.InputStream; +import java.util.ArrayDeque; +import java.util.Deque; public class UpstreamPacketHandler extends LoggingPacketHandler { + private Deque packsToSent = new ArrayDeque<>(); + public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) { super(geyser, session); } @@ -161,24 +165,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { break; case SEND_PACKS: - for(String id : packet.getPackIds()) { - ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket(); - String[] packID = id.split("_"); - ResourcePack pack = ResourcePack.PACKS.get(packID[0]); - ResourcePackManifest.Header header = pack.getManifest().getHeader(); - - data.setPackId(header.getUuid()); - int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE); - data.setChunkCount(chunkCount); - data.setCompressedPackSize(pack.getFile().length()); - data.setMaxChunkSize(ResourcePack.CHUNK_SIZE); - data.setHash(pack.getSha256()); - data.setPackVersion(packID[1]); - data.setPremium(false); - data.setType(ResourcePackType.RESOURCE); - - session.sendUpstreamPacket(data); - } + packsToSent.addAll(packet.getPackIds()); + sendPackDataInfo(packsToSent.pop()); break; case HAVE_ALL_PACKS: @@ -271,7 +259,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { data.setPackId(packet.getPackId()); int offset = packet.getChunkIndex() * ResourcePack.CHUNK_SIZE; - byte[] packData = new byte[(int) MathUtils.constrain(pack.getFile().length() - offset, 0, ResourcePack.CHUNK_SIZE)]; + long remainingSize = pack.getFile().length() - offset; + byte[] packData = new byte[(int) MathUtils.constrain(remainingSize, 0, ResourcePack.CHUNK_SIZE)]; try (InputStream inputStream = new FileInputStream(pack.getFile())) { inputStream.skip(offset); @@ -283,6 +272,31 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { data.setData(packData); session.sendUpstreamPacket(data); + + // Check if it is the last chunk and send next pack in queue when available. + if (remainingSize <= ResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) { + sendPackDataInfo(packsToSent.pop()); + } + return true; } + + private void sendPackDataInfo(String id) { + ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket(); + String[] packID = id.split("_"); + ResourcePack pack = ResourcePack.PACKS.get(packID[0]); + ResourcePackManifest.Header header = pack.getManifest().getHeader(); + + data.setPackId(header.getUuid()); + int chunkCount = (int) Math.ceil((int) pack.getFile().length() / (double) ResourcePack.CHUNK_SIZE); + data.setChunkCount(chunkCount); + data.setCompressedPackSize(pack.getFile().length()); + data.setMaxChunkSize(ResourcePack.CHUNK_SIZE); + data.setHash(pack.getSha256()); + data.setPackVersion(packID[1]); + data.setPremium(false); + data.setType(ResourcePackType.RESOURCE); + + session.sendUpstreamPacket(data); + } }