Skip to content

Commit

Permalink
Add bundle drop workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
Camotoy committed Jan 1, 2025
1 parent d40911c commit c7d47ab
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,8 @@ protected void tick() {
}
}

this.bundleCache.tick();

if (spawned) {
// Could move this to the PlayerAuthInput translator, in the event the player lags
// but this will work once we implement matching Java custom tick cycles
Expand Down Expand Up @@ -1473,6 +1475,13 @@ public void useItem(Hand hand) {
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
}

public void releaseItem() {
// Followed to the Minecraft Protocol specification outlined at wiki.vg
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, Vector3i.ZERO,
Direction.DOWN, 0);
sendDownstreamGamePacket(releaseItemPacket);
}

/**
* Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display
* blocking and sends a packet to the Java server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public final class BundleCache {
private final GeyserSession session;
private int nextBundleId;

private int releaseTick = -1;

public BundleCache(GeyserSession session) {
this.session = session;
}
Expand Down Expand Up @@ -216,6 +218,31 @@ public void onInventoryClose(Inventory inventory) {
}
}

/* All utilities to track when a release item packet should be sent.
* As of 1.21.50, Bedrock seems to be picky and inspecific when sending its own release packet,
* but if Java does not receive a release packet, then it will continue to drop items out of a bundle.
* This workaround releases items on behalf of the client if it does not send a packet, while respecting
* if Bedrock sends its own. */

public void awaitRelease() {
if (session.getTagCache().is(ItemTag.BUNDLES, session.getPlayerInventory().getItemInHand())) {
releaseTick = session.getTicks() + 1;
}
}

public void markRelease() {
releaseTick = -1;
}

public void tick() {
if (this.releaseTick != -1) {
if (session.getTicks() >= this.releaseTick) {
session.releaseItem();
markRelease();
}
}
}

/**
* Bidirectional; works for both Bedrock and Java.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ public void translate(GeyserSession session, InventoryTransactionPacket packet)

session.useItem(Hand.MAIN_HAND);

session.getBundleCache().awaitRelease();

List<LegacySetItemSlotData> legacySlots = packet.getLegacySlots();
if (packet.getActions().size() == 1 && !legacySlots.isEmpty()) {
InventoryActionData actionData = packet.getActions().get(0);
Expand Down Expand Up @@ -439,10 +441,8 @@ public void translate(GeyserSession session, InventoryTransactionPacket packet)
break;
case ITEM_RELEASE:
if (packet.getActionType() == 0) {
// Followed to the Minecraft Protocol specification outlined at wiki.vg
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, Vector3i.ZERO,
Direction.DOWN, 0);
session.sendDownstreamGamePacket(releaseItemPacket);
session.releaseItem();
session.getBundleCache().markRelease();
}
break;
case ITEM_USE_ON_ENTITY:
Expand Down

0 comments on commit c7d47ab

Please sign in to comment.