1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

Handle empty packid's in resource pack response packet

This commit is contained in:
onebeastchris
2025-08-03 21:32:10 +02:00
parent 9b04d7e019
commit e6ecfcdfee
3 changed files with 37 additions and 11 deletions

View File

@@ -168,7 +168,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
private final PlatformType platformType;
private final GeyserBootstrap bootstrap;
private final EventBus<EventRegistrar> eventBus;
private final GeyserEventBus eventBus;
private final GeyserExtensionManager extensionManager;
private Metrics metrics;
@@ -754,6 +754,10 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
return this.eventBus;
}
public GeyserEventBus geyserEventBus() {
return this.eventBus;
}
@NonNull
public RemoteServer defaultRemoteServer() {
return getConfig().getRemote();

View File

@@ -27,6 +27,7 @@ package org.geysermc.geyser.event;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.event.Event;
import org.geysermc.event.FireResult;
import org.geysermc.event.PostOrder;
import org.geysermc.event.bus.impl.OwnedEventBusImpl;
import org.geysermc.event.subscribe.OwnedSubscriber;
@@ -34,6 +35,7 @@ import org.geysermc.event.subscribe.Subscribe;
import org.geysermc.geyser.api.event.EventBus;
import org.geysermc.geyser.api.event.EventRegistrar;
import org.geysermc.geyser.api.event.EventSubscriber;
import org.geysermc.geyser.session.GeyserSession;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -68,4 +70,11 @@ public final class GeyserEventBus extends OwnedEventBusImpl<EventRegistrar, Even
public <T extends Event> Set<? extends EventSubscriber<EventRegistrar, T>> subscribers(@NonNull Class<T> eventClass) {
return castGenericSet(super.subscribers(eventClass));
}
public void fireEventElseKick(@NonNull Event event, GeyserSession session) {
FireResult result = this.fire(event);
if (!result.success()) {
session.disconnect("Internal server error occurred! Please contact a server administrator.");
}
}
}

View File

@@ -93,12 +93,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
private boolean finishedResourcePackSending = false;
private final Deque<String> packsToSend = new ArrayDeque<>();
private final CompressionStrategy compressionStrategy;
// Avoid overloading consoles when downloading larger resource packs
private static final int PACKET_SEND_DELAY = 4 * 50;
private final Queue<ResourcePackChunkRequestPacket> chunkRequestQueue = new ConcurrentLinkedQueue<>();
private boolean currentlySendingChunks = false;
private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
@@ -196,8 +194,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
}
if (receivedLoginPacket) {
GeyserImpl.getInstance().getLogger().warning("Received duplicate login packet from " + session.name());
session.disconnect("Received duplicate login packet!");
session.forciblyCloseUpstream();
return PacketSignal.HANDLED;
}
receivedLoginPacket = true;
@@ -219,7 +217,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
}
if (geyser.getSessionManager().isXuidAlreadyPending(session.xuid()) || geyser.getSessionManager().sessionByXuid(session.xuid()) != null) {
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.auth.already_loggedin", session.name()));
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.auth.already_loggedin", session.bedrockUsername()));
return PacketSignal.HANDLED;
}
@@ -233,7 +231,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
session.sendUpstreamPacket(playStatus);
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session);
this.geyser.eventBus().fire(this.resourcePackLoadEvent);
this.geyser.geyserEventBus().fireEventElseKick(this.resourcePackLoadEvent, session);
if (session.isClosed()) {
// Can happen if an error occurs in the resource pack event; that'll disconnect the player
return PacketSignal.HANDLED;
}
ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket();
resourcePacksInfo.getResourcePackInfos().addAll(this.resourcePackLoadEvent.infoPacketEntries());
@@ -267,6 +269,12 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.connect", session.getAuthData().name()));
}
case SEND_PACKS -> {
if (packet.getPackIds().isEmpty()) {
GeyserImpl.getInstance().getLogger().warning("Received empty pack ids in resource pack response packet!");
session.disconnect("Invalid resource pack response packet received!");
chunkRequestQueue.clear();
return PacketSignal.HANDLED;
}
packsToSend.addAll(packet.getPackIds());
sendPackDataInfo(packsToSend.pop());
}
@@ -322,7 +330,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
public PacketSignal handle(PlayerAuthInputPacket packet) {
// This doesn't catch rotation, but for a niche case I don't exactly want to cache rotation...
if (session.isLoggingIn() && !packet.getMotion().equals(Vector2f.ZERO)) {
if (!session.isClosed() && session.isLoggingIn() && !packet.getMotion().equals(Vector2f.ZERO)) {
SetTitlePacket titlePacket = new SetTitlePacket();
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
titlePacket.setText(GeyserLocale.getPlayerLocaleString("geyser.auth.login.wait", session.locale()));
@@ -339,10 +347,16 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
if (session.isClosed()) {
return PacketSignal.HANDLED;
}
if (finishedResourcePackSending) {
GeyserImpl.getInstance().getLogger().warning("Received resource pack chunk packet after stage completed! " + packet.toString());
session.disconnect("Illegal duplicate resource pack packet received!");
return PacketSignal.HANDLED;
}
// Resolve some console pack downloading issues.
// See <https://github.com/PowerNukkitX/PowerNukkitX/pull/1997> for reference
chunkRequestQueue.add(packet);
@@ -359,17 +373,16 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
public void processNextChunk() {
ResourcePackChunkRequestPacket packet = chunkRequestQueue.poll();
if (packet == null) {
if (packet == null || session.isClosed()) {
currentlySendingChunks = 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());
currentlySendingChunks = false;
chunkRequestQueue.clear();
session.disconnect("disconnectionScreen.resourcePack");
return;
}
@@ -380,7 +393,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
ResourcePackLoader.testRemotePack(session, urlPackCodec, holder);
if (!resourcePackLoadEvent.value(holder.uuid(), ResourcePackOption.Type.FALLBACK, true)) {
session.disconnect("Unable to provide downloaded resource pack. Contact an administrator!");
currentlySendingChunks = false;
chunkRequestQueue.clear();
return;
}
}