Skip to content

fix: intercept DecoderException in Connection.exceptionCaught to respect ignorePacketTranslationErrors#1172

Closed
Watermelcn wants to merge 3 commits into
ViaVersion:ver/26.1from
Watermelcn:fix/1169-unknown-enchantment-death-v2
Closed

fix: intercept DecoderException in Connection.exceptionCaught to respect ignorePacketTranslationErrors#1172
Watermelcn wants to merge 3 commits into
ViaVersion:ver/26.1from
Watermelcn:fix/1169-unknown-enchantment-death-v2

Conversation

@Watermelcn
Copy link
Copy Markdown

Description

Fixes #1169 - Kick when player gets killed using unknown enchantment

Root Cause Analysis

The exception propagates through ByteToMessageDecoder which catches DecoderException internally and re-dispatches via exceptionCaught - never reaching ViaFabricPlusDecoder try-catch.

Changes

1. MixinConnection.java - Made exceptionCaught cancellable; intercept DecoderException when ignorePacketTranslationErrors > 0, swallow via ci.cancel()

2. Enchantments1_14_4.java - Added density, breach, wind_burst

Previous Attempt

Replaces #1170 which incorrectly fixed in ViaFabricPlusDecoder catch block (ineffective)

@Watermelcn Watermelcn requested a review from a team May 19, 2026 11:55
@m1919810
Copy link
Copy Markdown

also we just figure out that byteBuf remain bytes should be skipped if a DecodeException thrown and we decide to ignore it, or it will cause a series of Packet size mismatch in DecoderHandler(yarn mapping)

@Watermelcn
Copy link
Copy Markdown
Author

Good catch. I've updated the PR to also override exceptionCaught in ViaFabricPlusDecoder to catch the DecoderException at the decoder pipeline level and prevent it from propagating to Connection.exceptionCaught.

However, you're right about the remaining bytes issue — when ByteToMessageDecoder (DecoderHandler) fires exceptionCaught, its internal cumulation buffer still has the unprocessed bytes. On the next channelRead, these leftover bytes will be prepended to new data and cause "Packet size mismatch".

I see two approaches to handle this:

  1. Pass through ViaFabricPlusDecoder: When we catch DecoderException in ViaFabricPlusDecoder.exceptionCaught, we reset the DecoderHandler's state (e.g. ctx.pipeline().replace("decoder", "decoder", new DecoderHandler(...)))
  2. Handle at MixinConnection level: Fire a user event through the pipeline to trigger decoder reset

What's the standard approach in ViaFabricPlus for this kind of decoder state cleanup? Or does the current approach already work in practice since the cumulation buffer is typically empty after a failed decode?

@florianreuth
Copy link
Copy Markdown
Member

All the changes here look unneeded and not actually fixing any real issues. I'll take a closer look at it at some point.

@florianreuth
Copy link
Copy Markdown
Member

Waiting for #1169 to provide the server for testing; Closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kick when player got killed using unknown enchantment

3 participants