Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.20.80 Support and Protocol Changes #4561

Merged
merged 37 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
070a19a
Make evil more harder
Kas-tle Apr 8, 2024
65b23f3
Deregister more unused packets
Kas-tle Apr 8, 2024
3dc213a
Add more unused packets
Kas-tle Apr 8, 2024
4bad652
Pin protocol to 68dc192
Kas-tle Apr 8, 2024
1d9dd8e
Correction
Kas-tle Apr 8, 2024
92d4642
Update Protocol
Kas-tle Apr 8, 2024
decce7c
More kicking
Kas-tle Apr 10, 2024
94d2cbc
stop reading when there is no item to read (#9)
onebeastchris Apr 10, 2024
aa4306c
Bump protocol
Kas-tle Apr 11, 2024
42f2a4b
1.20.80
Kas-tle Apr 12, 2024
ddd47b6
Merge remote-tracking branch 'upstream/master' into fix/protocol
Kas-tle Apr 12, 2024
5e78331
Remove unused postinitchannel GeyserServerInitializer
Kas-tle Apr 12, 2024
4e6970c
Merge branch 'GeyserMC:master' into fix/protocol
Kas-tle Apr 12, 2024
7e25e2e
Pull protocol jitpack from cloudburst again
Kas-tle Apr 12, 2024
dff08aa
Actually builds
Kas-tle Apr 13, 2024
f200df3
Merge branch 'GeyserMC:master' into fix/protocol
Kas-tle Apr 15, 2024
9fe3207
Merge remote-tracking branch 'upstream/master' into fix/protocol
Kas-tle Apr 17, 2024
4fa183e
Merge branch 'GeyserMC:master' into fix/protocol
Kas-tle Apr 18, 2024
a65738b
Merge branch 'GeyserMC:master' into fix/protocol
Kas-tle Apr 18, 2024
42dd315
Merge branch 'GeyserMC:master' into fix/protocol
Kas-tle Apr 19, 2024
5c3c178
Bump protocol to fix BossEventPacket & EmotePacket
Kas-tle Apr 20, 2024
85c5682
Add remove before merge comment
Kas-tle Apr 20, 2024
5636c7e
Merge remote-tracking branch 'upstream/master' into fix/protocol
Kas-tle Apr 20, 2024
2b5afa1
Bump protocol to fix BlockEntityDataPacket and ignore serverbound Bos…
Kas-tle Apr 20, 2024
319beb3
Bump protocol & add more illegal/ignored packets
Kas-tle Apr 21, 2024
fe26035
Merge remote-tracking branch 'upstream/master' into fix/protocol
Kas-tle Apr 21, 2024
8c2c566
Remove deprecated packet
Kas-tle Apr 21, 2024
66419a1
Ignore ClientCacheStatusPacket instead of disallow
Kas-tle Apr 21, 2024
ca76523
Define static serializers
Kas-tle Apr 21, 2024
c089ae4
Less static class nonsense more correct order
Kas-tle Apr 21, 2024
b5bfc89
Remove unused import
Kas-tle Apr 21, 2024
c3b3550
Merge remote-tracking branch 'upstream/master' into fix/protocol
Kas-tle Apr 22, 2024
eacc89e
Bump protocol
Kas-tle Apr 22, 2024
3612cb3
Move codec processing to CodecProcessor
Kas-tle Apr 22, 2024
daf9501
Falsify recipe symetry assumption
Kas-tle Apr 22, 2024
e2df578
Update Protocol for 2 wrong packet IDs & 5 wrong directions
Kas-tle Apr 23, 2024
a07c90b
Jitpack protocol from Geyser repo
Kas-tle Apr 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t

Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!

### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.73 and Minecraft Java 1.20.4
### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80 and Minecraft Java 1.20.4

## Setting Up
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
Expand Down
229 changes: 219 additions & 10 deletions core/src/main/java/org/geysermc/geyser/network/GameProtocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,62 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582;
import org.cloudburstmc.protocol.bedrock.codec.BedrockPacketSerializer;
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobArmorEquipmentSerializer_v291;
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.MobEquipmentSerializer_v291;
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.PlayerHotbarSerializer_v291;
import org.cloudburstmc.protocol.bedrock.codec.v291.serializer.SetEntityLinkSerializer_v291;
import org.cloudburstmc.protocol.bedrock.codec.v390.serializer.PlayerSkinSerializer_v390;
import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventoryContentSerializer_v407;
import org.cloudburstmc.protocol.bedrock.codec.v407.serializer.InventorySlotSerializer_v407;
import org.cloudburstmc.protocol.bedrock.codec.v486.serializer.BossEventSerializer_v486;
import org.cloudburstmc.protocol.bedrock.codec.v557.serializer.SetEntityDataSerializer_v557;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
import org.cloudburstmc.protocol.bedrock.codec.v662.serializer.SetEntityMotionSerializer_v662;
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.AnvilDamagePacket;
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
import org.cloudburstmc.protocol.bedrock.packet.BossEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.ClientCacheBlobStatusPacket;
import org.cloudburstmc.protocol.bedrock.packet.ClientCacheStatusPacket;
import org.cloudburstmc.protocol.bedrock.packet.ClientCheatAbilityPacket;
import org.cloudburstmc.protocol.bedrock.packet.ClientToServerHandshakePacket;
import org.cloudburstmc.protocol.bedrock.packet.CraftingEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.CreatePhotoPacket;
import org.cloudburstmc.protocol.bedrock.packet.DebugInfoPacket;
import org.cloudburstmc.protocol.bedrock.packet.DisconnectPacket;
import org.cloudburstmc.protocol.bedrock.packet.EditorNetworkPacket;
import org.cloudburstmc.protocol.bedrock.packet.EntityFallPacket;
import org.cloudburstmc.protocol.bedrock.packet.GameTestRequestPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
import org.cloudburstmc.protocol.bedrock.packet.LabTablePacket;
import org.cloudburstmc.protocol.bedrock.packet.MapCreateLockedCopyPacket;
import org.cloudburstmc.protocol.bedrock.packet.MapInfoRequestPacket;
import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket;
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
import org.cloudburstmc.protocol.bedrock.packet.MultiplayerSettingsPacket;
import org.cloudburstmc.protocol.bedrock.packet.NpcRequestPacket;
import org.cloudburstmc.protocol.bedrock.packet.PhotoInfoRequestPacket;
import org.cloudburstmc.protocol.bedrock.packet.PhotoTransferPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerHotbarPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerSkinPacket;
import org.cloudburstmc.protocol.bedrock.packet.PurchaseReceiptPacket;
import org.cloudburstmc.protocol.bedrock.packet.ScriptMessagePacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
import org.cloudburstmc.protocol.bedrock.packet.SettingsCommandPacket;
import org.cloudburstmc.protocol.bedrock.packet.SimpleEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.SubChunkRequestPacket;
import org.cloudburstmc.protocol.bedrock.packet.SubClientLoginPacket;
import org.cloudburstmc.protocol.bedrock.packet.TickSyncPacket;
Kas-tle marked this conversation as resolved.
Show resolved Hide resolved
import org.cloudburstmc.protocol.common.util.VarInts;
import org.geysermc.geyser.session.GeyserSession;

import java.util.ArrayList;
Expand All @@ -48,11 +97,103 @@
* Contains information about the supported protocols in Geyser.
*/
public final class GameProtocol {

@SuppressWarnings("rawtypes")
private static final BedrockPacketSerializer ILLEGAL_SERIALIZER = new BedrockPacketSerializer<>() {
@Override
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
throw new IllegalArgumentException("Server tried to send unused packet " + packet.getClass().getSimpleName() + "!");
}

@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
throw new IllegalArgumentException("Client tried to send unused packet " + packet.getClass().getSimpleName() + "!");
}
};

@SuppressWarnings("rawtypes")
private static final BedrockPacketSerializer IGNORED_SERIALIZER = new BedrockPacketSerializer<>() {
@Override
public void serialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
}

@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BedrockPacket packet) {
}
};

private static final BedrockPacketSerializer<InventoryContentPacket> INVENTORY_CONTENT_SERIALIZER = new InventoryContentSerializer_v407() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventoryContentPacket packet) {
throw new IllegalArgumentException("Client cannot send InventoryContentPacket in server-auth inventory environment!");
}
};

private static final BedrockPacketSerializer<InventorySlotPacket> INVENTORY_SLOT_SERIALIZER = new InventorySlotSerializer_v407() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, InventorySlotPacket packet) {
throw new IllegalArgumentException("Client cannot send InventorySlotPacket in server-auth inventory environment!");
}
};

private static final BedrockPacketSerializer<BossEventPacket> BOSS_EVENT_SERIALIZER = new BossEventSerializer_v486() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, BossEventPacket packet) {
}
};

private static final BedrockPacketSerializer<MobArmorEquipmentPacket> MOB_ARMOR_EQUIPMENT_SERIALIZER = new MobArmorEquipmentSerializer_v291() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobArmorEquipmentPacket packet) {
}
};

private static final BedrockPacketSerializer<PlayerHotbarPacket> PLAYER_HOTBAR_SERIALIZER = new PlayerHotbarSerializer_v291() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerHotbarPacket packet) {
}
};

private static final BedrockPacketSerializer<PlayerSkinPacket> PLAYER_SKIN_SERIALIZER = new PlayerSkinSerializer_v390() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, PlayerSkinPacket packet) {
}
};

private static final BedrockPacketSerializer<SetEntityDataPacket> SET_ENTITY_DATA_SERIALIZER = new SetEntityDataSerializer_v557() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityDataPacket packet) {
}
};

private static final BedrockPacketSerializer<SetEntityMotionPacket> SET_ENTITY_MOTION_SERIALIZER = new SetEntityMotionSerializer_v662() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityMotionPacket packet) {
}
};

private static final BedrockPacketSerializer<SetEntityLinkPacket> SET_ENTITY_LINK_SERIALIZER = new SetEntityLinkSerializer_v291() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, SetEntityLinkPacket packet) {
}
};

private static final BedrockPacketSerializer<MobEquipmentPacket> MOB_EQUIPMENT_SERIALIZER = new MobEquipmentSerializer_v291() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, MobEquipmentPacket packet) {
packet.setRuntimeEntityId(VarInts.readUnsignedLong(buffer));
fakeItemRead(buffer);
packet.setInventorySlot(buffer.readUnsignedByte());
packet.setHotbarSlot(buffer.readUnsignedByte());
packet.setContainerId(buffer.readByte());
}
};

/**
* Default Bedrock codec that should act as a fallback. Should represent the latest available
* release of the game that Geyser supports.
*/
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v662.CODEC);
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = processCodec(Bedrock_v671.CODEC);

/**
* A list of all supported Bedrock versions that can join Geyser
Expand All @@ -75,9 +216,12 @@ public final class GameProtocol {
SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v649.CODEC.toBuilder()
.minecraftVersion("1.20.60/1.20.62")
.build()));
SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder()
SUPPORTED_BEDROCK_CODECS.add(processCodec(Bedrock_v662.CODEC.toBuilder()
.minecraftVersion("1.20.70/1.20.73")
.build()));
SUPPORTED_BEDROCK_CODECS.add(processCodec(DEFAULT_BEDROCK_CODEC.toBuilder()
.minecraftVersion("1.20.80")
.build()));
}

/**
Expand Down Expand Up @@ -168,14 +312,79 @@ public static String getAllSupportedJavaVersions() {
return joiner.toString();
}

@SuppressWarnings("unchecked")
private static BedrockCodec processCodec(BedrockCodec codec) {
return codec.toBuilder()
.updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) {
}
})
.build();
// Illegal unused serverbound EDU packets
.updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(CreatePhotoPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(NpcRequestPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(PhotoInfoRequestPacket.class, ILLEGAL_SERIALIZER)
// Illegal unused serverbound packets for featured servers
.updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER)
// Illegal unused serverbound packets that are deprecated
.updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER)
// Illegal unusued serverbound packets that relate to unused features
.updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(SubClientLoginPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER)
// Ignored serverbound packets
.updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed
.updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER)
.updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER)
.updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER)
.updateSerializer(MapInfoRequestPacket.class, IGNORED_SERIALIZER)
.updateSerializer(SettingsCommandPacket.class, IGNORED_SERIALIZER)
.updateSerializer(AnvilDamagePacket.class, IGNORED_SERIALIZER)
// Illegal when serverbound due to Geyser specific setup
.updateSerializer(InventoryContentPacket.class, INVENTORY_CONTENT_SERIALIZER)
.updateSerializer(InventorySlotPacket.class, INVENTORY_SLOT_SERIALIZER)
// Ignored only when serverbound
.updateSerializer(BossEventPacket.class, BOSS_EVENT_SERIALIZER)
.updateSerializer(MobArmorEquipmentPacket.class, MOB_ARMOR_EQUIPMENT_SERIALIZER)
.updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER)
.updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER)
.updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER)
.updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER)
.updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER)
// Valid serverbound packets where reading of some fields can be skipped
.updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER)
// // Illegal bidirectional packets
.updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER)
// // Ignored bidirectional packets
.updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER)
.updateSerializer(DisconnectPacket.class, IGNORED_SERIALIZER)
.updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER)
.updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER)
.updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER)
.build();
}

/**
* Fake reading an item from the buffer to improve performance.
*
* @param buffer
*/
private static void fakeItemRead(ByteBuf buffer) {
int id = VarInts.readInt(buffer); // Runtime ID
if (id == 0) { // nothing more to read
return;
}
buffer.skipBytes(2); // count
VarInts.readUnsignedInt(buffer); // damage
boolean hasNetId = buffer.readBoolean();
if (hasNetId) {
VarInts.readInt(buffer);
}

VarInts.readInt(buffer); // Block runtime ID
int streamSize = VarInts.readUnsignedInt(buffer);
buffer.skipBytes(streamSize);
}

private GameProtocol() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@

package org.geysermc.geyser.network;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.BedrockPeer;
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
Expand Down Expand Up @@ -63,6 +67,10 @@ public void initSession(@NonNull BedrockServerSession bedrockServerSession) {

bedrockServerSession.setLogging(true);
GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next());

Channel channel = bedrockServerSession.getPeer().getChannel();
channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session));

bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session));
this.geyser.eventBus().fire(new SessionInitializeEvent(session));
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/

package org.geysermc.geyser.network;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.RequiredArgsConstructor;
import org.geysermc.geyser.session.GeyserSession;

import java.util.stream.Stream;

@RequiredArgsConstructor
public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
public static final String NAME = "rak-error-handler";

private final GeyserSession session;

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
Throwable rootCause = Stream.iterate(cause, Throwable::getCause)
.filter(element -> element.getCause() == null)
.findFirst()
.orElse(cause);


if (!(rootCause instanceof IllegalArgumentException)) {
super.exceptionCaught(ctx, cause);
return;
}

// Kick users that try to send illegal packets
session.getGeyser().getLogger().warning(rootCause.getMessage());
session.disconnect("Invalid packet received!");
}
}
Loading