Skip to content

Commit

Permalink
Fix spawn egg triggering twice in water
Browse files Browse the repository at this point in the history
  • Loading branch information
Camotoy committed Jun 20, 2021
1 parent 35450f7 commit 683ac1c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session)
Block place checks end - client is good to go
*/

if (packet.getItemInHand() != null && ItemRegistry.SPAWN_EGGS.contains(packet.getItemInHand().getId())) {
int blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getBlockPosition());
if (blockState == BlockTranslator.JAVA_WATER_ID) {
// Otherwise causes multiple mobs to spawn - just send a use item packet
// TODO when we fix mobile bucket rotation, use it for this, too
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(itemPacket);
break;
}
}

ClientPlayerPlaceBlockPacket blockPacket = new ClientPlayerPlaceBlockPacket(
new Position(packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()),
BlockFace.values()[packet.getBlockFace()],
Expand All @@ -191,25 +202,27 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session)
false);
session.sendDownstreamPacket(blockPacket);

// Otherwise boats will not be able to be placed in survival and buckets won't work on mobile
if (packet.getItemInHand() != null && ItemRegistry.BOATS.contains(packet.getItemInHand().getId())) {
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(itemPacket);
}
// Check actions, otherwise buckets may be activated when block inventories are accessed
else if (packet.getItemInHand() != null && ItemRegistry.BUCKETS.contains(packet.getItemInHand().getId())) {
// Let the server decide if the bucket item should change, not the client, and revert the changes the client made
InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(ContainerId.INVENTORY);
slotPacket.setSlot(packet.getHotbarSlot());
slotPacket.setItem(packet.getItemInHand());
session.sendUpstreamPacket(slotPacket);
// Delay the interaction in case the client doesn't intend to actually use the bucket
// See BedrockActionTranslator.java
session.setBucketScheduledFuture(session.getConnector().getGeneralThreadPool().schedule(() -> {
if (packet.getItemInHand() != null) {
// Otherwise boats will not be able to be placed in survival and buckets won't work on mobile
if (ItemRegistry.BOATS.contains(packet.getItemInHand().getId())) {
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(itemPacket);
}, 5, TimeUnit.MILLISECONDS));
}
// Check actions, otherwise buckets may be activated when block inventories are accessed
else if (ItemRegistry.BUCKETS.contains(packet.getItemInHand().getId())) {
// Let the server decide if the bucket item should change, not the client, and revert the changes the client made
InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(ContainerId.INVENTORY);
slotPacket.setSlot(packet.getHotbarSlot());
slotPacket.setItem(packet.getItemInHand());
session.sendUpstreamPacket(slotPacket);
// Delay the interaction in case the client doesn't intend to actually use the bucket
// See BedrockActionTranslator.java
session.setBucketScheduledFuture(session.getConnector().getGeneralThreadPool().schedule(() -> {
ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.sendDownstreamPacket(itemPacket);
}, 5, TimeUnit.MILLISECONDS));
}
}

if (packet.getActions().isEmpty()) {
Expand Down Expand Up @@ -253,10 +266,15 @@ else if (packet.getItemInHand() != null && ItemRegistry.BUCKETS.contains(packet.
break;
}

// Handled in ITEM_USE if the item is not milk
if (packet.getItemInHand() != null && ItemRegistry.BUCKETS.contains(packet.getItemInHand().getId()) &&
packet.getItemInHand().getId() != ItemRegistry.MILK_BUCKET.getBedrockId()) {
break;
if (packet.getItemInHand() != null) {
if (ItemRegistry.BUCKETS.contains(packet.getItemInHand().getId()) &&
packet.getItemInHand().getId() != ItemRegistry.MILK_BUCKET.getBedrockId()) {
// Handled in case 0 if the item is not milk
break;
} else if (ItemRegistry.SPAWN_EGGS.contains(packet.getItemInHand().getId())) {
// Handled in case 0
break;
}
}

ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@
import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
Expand Down Expand Up @@ -113,6 +110,10 @@ public class ItemRegistry {
* Shield item entry, used in Entity.java and LivingEntity.java
*/
public static ItemEntry SHIELD;
/**
* A list of all spawn eggs by their Bedrock IDs. Used in BedrockInventoryTransactionTranslator.java
*/
public static final IntSet SPAWN_EGGS = new IntArraySet();
/**
* Wheat item entry, used in AbstractHorseEntity.java
*/
Expand Down Expand Up @@ -457,9 +458,9 @@ public static void init() {
}

if (entry.getKey().contains("boat")) {
BOATS.add(entry.getValue().get("bedrock_id").intValue());
BOATS.add(itemEntry.getBedrockId());
} else if (entry.getKey().contains("bucket") && !entry.getKey().contains("milk")) {
BUCKETS.add(entry.getValue().get("bedrock_id").intValue());
BUCKETS.add(itemEntry.getBedrockId());
} else if (entry.getKey().contains("_carpet") && !entry.getKey().contains("moss")) {
// This should be the numerical order Java sends as an integer value for llamas
CARPETS.add(ItemData.builder()
Expand All @@ -471,6 +472,8 @@ public static void init() {
// The Java record level event uses the item ID as the "key" to play the record
EffectRegistry.RECORDS.put(itemIndex, SoundEvent.valueOf("RECORD_" +
entry.getKey().replace("minecraft:music_disc_", "").toUpperCase(Locale.ENGLISH)));
} else if (entry.getKey().endsWith("_spawn_egg")) {
SPAWN_EGGS.add(itemEntry.getBedrockId());
}

itemNames.add(entry.getKey());
Expand Down

0 comments on commit 683ac1c

Please sign in to comment.