Skip to content

Updated to add Fabric support. Advertises the fabric:registry/sync pl… - #286

Open
Chadhendrixs wants to merge 1 commit into
MrKinau:mainfrom
Chadhendrixs:add-fabric-support
Open

Updated to add Fabric support. Advertises the fabric:registry/sync pl…#286
Chadhendrixs wants to merge 1 commit into
MrKinau:mainfrom
Chadhendrixs:add-fabric-support

Conversation

@Chadhendrixs

Copy link
Copy Markdown

Updated to add Fabric support. Advertises the fabric:registry/sync plugin channel on join, and on join handles modded items by ignoring them (Previously failed to find fishing rod after modded item)

…ugin channel on join, and on join handles modded items by ignoring them (Previously failed to find fishing rod after modded item)
@MrKinau

MrKinau commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Hi @Chadhendrixs thanks for your PR, can you give me a name/link of a mod (preferable open-source), where this issue happens, this would help me reviewing it

@Chadhendrixs

Copy link
Copy Markdown
Author

Heya! The mod that was causing me issues was Backpacked by Mr.Crayfish after I got it connecting to Fabric servers. It would fail with the error below and disconnect, then it would discard the whole inventory after fixing that so it now only discards the modded item it can't parse.

The items was in the "backpack slot" in the mod, I'm guessing that's what caused the error in the first place.

[2026-07-26 03:05:50] [INFO   ] java.lang.IllegalStateException: java.io.EOFException 
[2026-07-26 03:05:50] [INFO   ] 	at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readByte(ByteStreams.java:376) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.utils.ByteArrayDataInputWrapper.readByte(ByteArrayDataInputWrapper.java:74) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.Packet.readVarInt(Packet.java:81) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.Packet.readVarInt(Packet.java:73) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.Packet.readSlot(Packet.java:336) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.Packet.readSlot(Packet.java:295) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.play.PacketInWindowItems.read(PacketInWindowItems.java:41) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.NetworkHandler.readPacket(NetworkHandler.java:271) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.NetworkHandler.readUncompressed(NetworkHandler.java:217) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.network.protocol.NetworkHandler.readData(NetworkHandler.java:192) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.Bot.connect(Bot.java:402) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.Bot.start(Bot.java:288) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.FishingBot.startBot(FishingBot.java:96) 
[2026-07-26 03:05:50] [INFO   ] 	at systems.kinau.fishingbot.gui.GUIController.lambda$startStop$3(GUIController.java:215) 
[2026-07-26 03:05:50] [INFO   ] 	at java.lang.Thread.run(Unknown Source) 
[2026-07-26 03:05:50] [INFO   ] Caused by: java.io.EOFException 
[2026-07-26 03:05:50] [INFO   ] 	at java.io.DataInputStream.readByte(Unknown Source) 
[2026-07-26 03:05:50] [INFO   ] 	at com.google.common.io.ByteStreams$ByteArrayDataInputStream.readByte(ByteStreams.java:374) 
[2026-07-26 03:05:50] [INFO   ] 	... 14 more 
[2026-07-26 03:05:50] [SEVERE ] Could not receive packet! Shutting down...

...

[2026-07-26 03:11:51] [SEVERE ] Invalid component: 118 
[2026-07-26 03:11:51] [WARNING] Could not read packet PacketInWindowItems: java.lang.IllegalStateException: java.io.EOFException 
[2026-07-26 03:11:51] [INFO   ] Achieved level: 13 
[2026-07-26 03:11:52] [WARNING] No rod has been found...

@MrKinau MrKinau left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi again @Chadhendrixs
First of all, sorry for the delay, I wanted to review your PR earlier, but unfortunately wasn't able to.
Thanks for your PR this will definitely help connecting to fabric modded servers, thanks for taking your time looking into it.

The fabric registration payload and answering the sync packet is a great addition to spoof fabric. However the main issue with the mod mentioned at least is the fact it adds custom item components to the items it adds (e.g. backbacked:unlockable_slots to a backpack). As the single item payload length is no longer sent within the PacketInWindowItems (minecraft:container_set_content) we can't really know the contents of the bots inventory as we can't skip the items we can't read.
I've requested some changes only about allowing logging more exceptions and trying handling the modded components as NBTComponent, but overall your code looks good, I tested it and it works (at least for the mentioned mod and if there is no backback in an inventory slot before a rod, obviously).

Thanks again for your PR.

Comment on lines +343 to +346
} else if (!trySkipAsNbt(input, dataComponentType, protocolId)) {
// no way to know its length, rest of the slot is unneeded
FishingBot.getLog().severe("Invalid component: " + dataComponentType);
throw new IllegalStateException("Unknown data component type " + dataComponentType + ", cannot determine its payload length to skip it");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not just try skipping the component, but if it can be read as NBT, just handle it as a NBTComponent with the correct component type id, that will also allow writing the item back later if necessary. Although this did not work for me for the components added by the backpack mod, I'm sure many modded components are just NBT due to lazyness converting legacy nbt item data to the modern component format.

Suggested change
} else if (!trySkipAsNbt(input, dataComponentType, protocolId)) {
// no way to know its length, rest of the slot is unneeded
FishingBot.getLog().severe("Invalid component: " + dataComponentType);
throw new IllegalStateException("Unknown data component type " + dataComponentType + ", cannot determine its payload length to skip it");
} else {
try {
NBTComponent nbtComponent = new NBTComponent(dataComponentType);
int before = input.getAvailable();
nbtComponent.read(input, protocolId);
int consumed = before - input.getAvailable();
FishingBot.getLog().warning("Unknown component " + dataComponentType + ": heuristically handled as NBT (" + consumed + " byte(s))");
presentComponents.add(nbtComponent);
} catch (Exception e) {
// no way to know its length, rest of the slot is unneeded
FishingBot.getLog().severe("Invalid component: " + dataComponentType);
throw new IllegalStateException("Unknown data component type " + dataComponentType + ", cannot determine its payload length to skip it");
}

Comment on lines +221 to +233
// Best effort for unknown (modded) components: usually just plain NBT data, better compatability with modded items in inventory
private static boolean trySkipAsNbt(ByteArrayDataInputWrapper input, int dataComponentType, int protocolId) {
try {
int before = input.getAvailable();
readNBT(input, protocolId);
int consumed = before - input.getAvailable();
FishingBot.getLog().warning("Unknown component " + dataComponentType + ": heuristically skipped as NBT (" + consumed + " byte(s))");
return true;
} catch (Exception e) {
return false;
}
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see other change request within Packet

Suggested change
// Best effort for unknown (modded) components: usually just plain NBT data, better compatability with modded items in inventory
private static boolean trySkipAsNbt(ByteArrayDataInputWrapper input, int dataComponentType, int protocolId) {
try {
int before = input.getAvailable();
readNBT(input, protocolId);
int consumed = before - input.getAvailable();
FishingBot.getLog().warning("Unknown component " + dataComponentType + ": heuristically skipped as NBT (" + consumed + " byte(s))");
return true;
} catch (Exception e) {
return false;
}
}

this.slots.add(readSlot(in, protocolId, networkHandler.getDataComponentRegistry()));
} catch (Exception e) {
// Keep the slots read so far instead of tossing the whole snapshot
FishingBot.getLog().warning("Could not read slot " + i + "/" + count + " of PacketInWindowItems (window " + windowId + "): " + e);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh I'm not sure if it is a good idea to let this packet pass, as the inventory is not complete and may contain wrong items, but there might be the chance a fishing rod be read before the modded items which can't be read, thus allowing the automatic rod detection work. The bot not having full and/or incorrect inventory data may not be more of an issue than having no inventory data at all.
The only issue I see is that there is no way of logging the full exception, in case of an actual issue within reading items. I think it would be good to print the full exception when FishingBot.getInstance().getConfig().isLogItemData() is enabled

Suggested change
FishingBot.getLog().warning("Could not read slot " + i + "/" + count + " of PacketInWindowItems (window " + windowId + "): " + e);
FishingBot.getLog().warning("Could not read slot " + i + "/" + count + " of PacketInWindowItems (window " + windowId + "): " + e);
if (FishingBot.getInstance().getConfig().isLogItemData())
e.printStackTrace();

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.

2 participants