mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-20 07:19:29 +00:00
Handle empty packid's in resource pack response packet
This commit is contained in:
@@ -168,7 +168,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||||||
private final PlatformType platformType;
|
private final PlatformType platformType;
|
||||||
private final GeyserBootstrap bootstrap;
|
private final GeyserBootstrap bootstrap;
|
||||||
|
|
||||||
private final EventBus<EventRegistrar> eventBus;
|
private final GeyserEventBus eventBus;
|
||||||
private final GeyserExtensionManager extensionManager;
|
private final GeyserExtensionManager extensionManager;
|
||||||
|
|
||||||
private Metrics metrics;
|
private Metrics metrics;
|
||||||
@@ -754,6 +754,10 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||||||
return this.eventBus;
|
return this.eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GeyserEventBus geyserEventBus() {
|
||||||
|
return this.eventBus;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public RemoteServer defaultRemoteServer() {
|
public RemoteServer defaultRemoteServer() {
|
||||||
return getConfig().getRemote();
|
return getConfig().getRemote();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ package org.geysermc.geyser.event;
|
|||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.geysermc.event.Event;
|
import org.geysermc.event.Event;
|
||||||
|
import org.geysermc.event.FireResult;
|
||||||
import org.geysermc.event.PostOrder;
|
import org.geysermc.event.PostOrder;
|
||||||
import org.geysermc.event.bus.impl.OwnedEventBusImpl;
|
import org.geysermc.event.bus.impl.OwnedEventBusImpl;
|
||||||
import org.geysermc.event.subscribe.OwnedSubscriber;
|
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.EventBus;
|
||||||
import org.geysermc.geyser.api.event.EventRegistrar;
|
import org.geysermc.geyser.api.event.EventRegistrar;
|
||||||
import org.geysermc.geyser.api.event.EventSubscriber;
|
import org.geysermc.geyser.api.event.EventSubscriber;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
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) {
|
public <T extends Event> Set<? extends EventSubscriber<EventRegistrar, T>> subscribers(@NonNull Class<T> eventClass) {
|
||||||
return castGenericSet(super.subscribers(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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,12 +93,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
private boolean finishedResourcePackSending = false;
|
private boolean finishedResourcePackSending = false;
|
||||||
private final Deque<String> packsToSend = new ArrayDeque<>();
|
private final Deque<String> packsToSend = new ArrayDeque<>();
|
||||||
private final CompressionStrategy compressionStrategy;
|
private final CompressionStrategy compressionStrategy;
|
||||||
|
|
||||||
// Avoid overloading consoles when downloading larger resource packs
|
// Avoid overloading consoles when downloading larger resource packs
|
||||||
private static final int PACKET_SEND_DELAY = 4 * 50;
|
private static final int PACKET_SEND_DELAY = 4 * 50;
|
||||||
private final Queue<ResourcePackChunkRequestPacket> chunkRequestQueue = new ConcurrentLinkedQueue<>();
|
private final Queue<ResourcePackChunkRequestPacket> chunkRequestQueue = new ConcurrentLinkedQueue<>();
|
||||||
private boolean currentlySendingChunks = false;
|
private boolean currentlySendingChunks = false;
|
||||||
|
|
||||||
private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
|
private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
|
||||||
|
|
||||||
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
||||||
@@ -196,8 +194,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (receivedLoginPacket) {
|
if (receivedLoginPacket) {
|
||||||
GeyserImpl.getInstance().getLogger().warning("Received duplicate login packet from " + session.name());
|
|
||||||
session.disconnect("Received duplicate login packet!");
|
session.disconnect("Received duplicate login packet!");
|
||||||
|
session.forciblyCloseUpstream();
|
||||||
return PacketSignal.HANDLED;
|
return PacketSignal.HANDLED;
|
||||||
}
|
}
|
||||||
receivedLoginPacket = true;
|
receivedLoginPacket = true;
|
||||||
@@ -219,7 +217,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (geyser.getSessionManager().isXuidAlreadyPending(session.xuid()) || geyser.getSessionManager().sessionByXuid(session.xuid()) != null) {
|
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;
|
return PacketSignal.HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +231,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
session.sendUpstreamPacket(playStatus);
|
session.sendUpstreamPacket(playStatus);
|
||||||
|
|
||||||
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session);
|
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();
|
ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket();
|
||||||
resourcePacksInfo.getResourcePackInfos().addAll(this.resourcePackLoadEvent.infoPacketEntries());
|
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()));
|
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.connect", session.getAuthData().name()));
|
||||||
}
|
}
|
||||||
case SEND_PACKS -> {
|
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());
|
packsToSend.addAll(packet.getPackIds());
|
||||||
sendPackDataInfo(packsToSend.pop());
|
sendPackDataInfo(packsToSend.pop());
|
||||||
}
|
}
|
||||||
@@ -322,7 +330,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
@Override
|
@Override
|
||||||
public PacketSignal handle(PlayerAuthInputPacket packet) {
|
public PacketSignal handle(PlayerAuthInputPacket packet) {
|
||||||
// This doesn't catch rotation, but for a niche case I don't exactly want to cache rotation...
|
// 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();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
|
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
|
||||||
titlePacket.setText(GeyserLocale.getPlayerLocaleString("geyser.auth.login.wait", session.locale()));
|
titlePacket.setText(GeyserLocale.getPlayerLocaleString("geyser.auth.login.wait", session.locale()));
|
||||||
@@ -339,10 +347,16 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
|
public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
|
||||||
|
if (session.isClosed()) {
|
||||||
|
return PacketSignal.HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
if (finishedResourcePackSending) {
|
if (finishedResourcePackSending) {
|
||||||
|
GeyserImpl.getInstance().getLogger().warning("Received resource pack chunk packet after stage completed! " + packet.toString());
|
||||||
session.disconnect("Illegal duplicate resource pack packet received!");
|
session.disconnect("Illegal duplicate resource pack packet received!");
|
||||||
return PacketSignal.HANDLED;
|
return PacketSignal.HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve some console pack downloading issues.
|
// Resolve some console pack downloading issues.
|
||||||
// See <https://github.com/PowerNukkitX/PowerNukkitX/pull/1997> for reference
|
// See <https://github.com/PowerNukkitX/PowerNukkitX/pull/1997> for reference
|
||||||
chunkRequestQueue.add(packet);
|
chunkRequestQueue.add(packet);
|
||||||
@@ -359,17 +373,16 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
|
|
||||||
public void processNextChunk() {
|
public void processNextChunk() {
|
||||||
ResourcePackChunkRequestPacket packet = chunkRequestQueue.poll();
|
ResourcePackChunkRequestPacket packet = chunkRequestQueue.poll();
|
||||||
if (packet == null) {
|
if (packet == null || session.isClosed()) {
|
||||||
currentlySendingChunks = false;
|
currentlySendingChunks = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourcePackHolder holder = this.resourcePackLoadEvent.getPacks().get(packet.getPackId());
|
ResourcePackHolder holder = this.resourcePackLoadEvent.getPacks().get(packet.getPackId());
|
||||||
|
|
||||||
if (holder == null) {
|
if (holder == null) {
|
||||||
GeyserImpl.getInstance().getLogger().debug("Client {0} tried to request pack id {1} not sent to it!",
|
GeyserImpl.getInstance().getLogger().debug("Client {0} tried to request pack id {1} not sent to it!",
|
||||||
session.bedrockUsername(), packet.getPackId());
|
session.bedrockUsername(), packet.getPackId());
|
||||||
currentlySendingChunks = false;
|
chunkRequestQueue.clear();
|
||||||
session.disconnect("disconnectionScreen.resourcePack");
|
session.disconnect("disconnectionScreen.resourcePack");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -380,7 +393,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
ResourcePackLoader.testRemotePack(session, urlPackCodec, holder);
|
ResourcePackLoader.testRemotePack(session, urlPackCodec, holder);
|
||||||
if (!resourcePackLoadEvent.value(holder.uuid(), ResourcePackOption.Type.FALLBACK, true)) {
|
if (!resourcePackLoadEvent.value(holder.uuid(), ResourcePackOption.Type.FALLBACK, true)) {
|
||||||
session.disconnect("Unable to provide downloaded resource pack. Contact an administrator!");
|
session.disconnect("Unable to provide downloaded resource pack. Contact an administrator!");
|
||||||
currentlySendingChunks = false;
|
chunkRequestQueue.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user