diff --git a/README.md b/README.md
index d4b375a5c..593514e52 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,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.17.30 - 1.17.41 + 1.18.0 - 1.18.2 and Minecraft Java 1.18/1.18.1.
+### Currently supporting Minecraft Bedrock 1.17.41 + 1.18.0 - 1.18.10 and Minecraft Java 1.18/1.18.1.
## Setting Up
Take a look [here](https://github.com/GeyserMC/Geyser/wiki/Setup) for how to set up Geyser.
diff --git a/ap/pom.xml b/ap/pom.xml
index cc282dd55..dce28a7d7 100644
--- a/ap/pom.xml
+++ b/ap/pom.xml
@@ -6,9 +6,9 @@
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
ap
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
\ No newline at end of file
diff --git a/api/base/pom.xml b/api/base/pom.xml
index 0d7ed05da..17edb1a85 100644
--- a/api/base/pom.xml
+++ b/api/base/pom.xml
@@ -5,7 +5,7 @@
org.geysermc
api-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
4.0.0
diff --git a/api/geyser/pom.xml b/api/geyser/pom.xml
index 435643b0a..de9c63e83 100644
--- a/api/geyser/pom.xml
+++ b/api/geyser/pom.xml
@@ -5,7 +5,7 @@
org.geysermc
api-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
../pom.xml
4.0.0
@@ -35,7 +35,7 @@
org.geysermc
base-api
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/api/pom.xml b/api/pom.xml
index f66b982fb..b6d865cb4 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
../pom.xml
diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml
index 9dcd0943e..45a08c7db 100644
--- a/bootstrap/bungeecord/pom.xml
+++ b/bootstrap/bungeecord/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
bootstrap-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-bungeecord
@@ -14,7 +14,7 @@
org.geysermc
core
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml
index 3b0bdda55..58c651455 100644
--- a/bootstrap/pom.xml
+++ b/bootstrap/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-parent
pom
@@ -34,7 +34,7 @@
org.geysermc
ap
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
provided
diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml
index 5aa2c59cf..6eda527f3 100644
--- a/bootstrap/spigot/pom.xml
+++ b/bootstrap/spigot/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
bootstrap-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-spigot
@@ -25,7 +25,7 @@
org.geysermc
core
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java
index 999353d8a..981d00b97 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/world/GeyserPistonListener.java
@@ -97,7 +97,7 @@ public class GeyserPistonListener implements Listener {
int dX = Math.abs(location.getBlockX() - player.getLocation().getBlockX()) >> 4;
int dZ = Math.abs(location.getBlockZ() - player.getLocation().getBlockZ()) >> 4;
- if ((dX * dX + dZ * dZ) > session.getRenderDistance() * session.getRenderDistance()) {
+ if ((dX * dX + dZ * dZ) > session.getServerRenderDistance() * session.getServerRenderDistance()) {
// Ignore pistons outside the player's render distance
continue;
}
diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml
index fa7989b43..ab3b7d970 100644
--- a/bootstrap/sponge/pom.xml
+++ b/bootstrap/sponge/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
bootstrap-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-sponge
@@ -14,7 +14,7 @@
org.geysermc
core
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml
index 00c0410e4..881c87e6c 100644
--- a/bootstrap/standalone/pom.xml
+++ b/bootstrap/standalone/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
bootstrap-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-standalone
@@ -18,7 +18,7 @@
org.geysermc
core
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml
index e1e3331ef..ff052471d 100644
--- a/bootstrap/velocity/pom.xml
+++ b/bootstrap/velocity/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
bootstrap-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
bootstrap-velocity
@@ -14,7 +14,7 @@
org.geysermc
core
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
diff --git a/common/pom.xml b/common/pom.xml
index 8e7be26f4..fde2605bc 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
common
diff --git a/core/pom.xml b/core/pom.xml
index 6f4e0fa3c..31f9a075f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -6,7 +6,7 @@
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
core
@@ -20,19 +20,19 @@
org.geysermc
ap
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
provided
org.geysermc
geyser-api
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
org.geysermc
common
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
compile
@@ -119,8 +119,8 @@
com.github.CloudburstMC.Protocol
- bedrock-v475
- c22aa595
+ bedrock-v486
+ 0cd24c0
compile
diff --git a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
index e24146cb2..f754368f0 100644
--- a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -64,7 +64,7 @@ public class GeyserSession {
}
public int getRenderDistance() {
- return this.handle.getRenderDistance();
+ return this.handle.getServerRenderDistance();
}
public boolean isSentSpawnPacket() {
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
index 47aa905ea..68bb69b46 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
@@ -68,6 +68,7 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.SessionManager;
import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.skin.FloodgateSkinUploader;
+import org.geysermc.geyser.skin.SkinProvider;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
@@ -211,6 +212,8 @@ public class GeyserImpl implements GeyserApi {
ScoreboardUpdater.init();
+ SkinProvider.registerCacheImageTask(this);
+
ResourcePack.loadPacks();
this.extensionManager.enableExtensions();
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java
index a61c5db25..b47801cb5 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserLogger.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserLogger.java
@@ -25,6 +25,8 @@
package org.geysermc.geyser;
+import javax.annotation.Nullable;
+
public interface GeyserLogger {
/**
@@ -78,6 +80,15 @@ public interface GeyserLogger {
*/
void debug(String message);
+ /**
+ * Logs an object to console if debug mode is enabled
+ *
+ * @param object the object to log
+ */
+ default void debug(@Nullable Object object) {
+ debug(String.valueOf(object));
+ }
+
/**
* Sets if the logger should print debug messages
*
diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
index 3fc7971b0..3b7cad44c 100644
--- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
+++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java
@@ -76,6 +76,10 @@ public interface GeyserConfiguration {
boolean isShowCoordinates();
+ boolean isDisableBedrockScaffolding();
+
+ boolean isAlwaysQuickChangeArmor();
+
EmoteOffhandWorkaroundOption getEmoteOffhandWorkaround();
String getDefaultLocale();
diff --git a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
index 55721f894..97c5bfea8 100644
--- a/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
+++ b/core/src/main/java/org/geysermc/geyser/configuration/GeyserJacksonConfiguration.java
@@ -105,6 +105,12 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
@JsonProperty("show-coordinates")
private boolean showCoordinates = true;
+ @JsonProperty("disable-bedrock-scaffolding")
+ private boolean disableBedrockScaffolding = false;
+
+ @JsonProperty("always-quick-change-armor")
+ private boolean alwaysQuickChangeArmor = false;
+
@JsonDeserialize(using = EmoteOffhandWorkaroundOption.Deserializer.class)
@JsonProperty("emote-offhand-workaround")
private EmoteOffhandWorkaroundOption emoteOffhandWorkaround = EmoteOffhandWorkaroundOption.DISABLED;
diff --git a/core/src/main/java/org/geysermc/geyser/entity/GeyserDirtyMetadata.java b/core/src/main/java/org/geysermc/geyser/entity/GeyserDirtyMetadata.java
index caa373549..f0095d26a 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/GeyserDirtyMetadata.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/GeyserDirtyMetadata.java
@@ -34,7 +34,7 @@ import java.util.Map;
/**
* A write-only wrapper for temporarily storing entity metadata that will be sent to Bedrock.
*/
-public class GeyserDirtyMetadata {
+public final class GeyserDirtyMetadata {
private final Map metadata = new Object2ObjectLinkedOpenHashMap<>();
public void put(EntityData entityData, Object value) {
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
index 9139e0a99..69aac5a26 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemFrameEntity.java
@@ -37,12 +37,11 @@ import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
-import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
import lombok.Getter;
import org.geysermc.geyser.entity.EntityDefinition;
+import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
-import org.geysermc.geyser.registry.type.ItemMapping;
import java.util.UUID;
@@ -85,10 +84,8 @@ public class ItemFrameEntity extends Entity {
.putInt("version", session.getBlockMappings().getBlockStateVersion());
NbtMapBuilder statesBuilder = NbtMap.builder()
.putInt("facing_direction", direction.ordinal())
- .putByte("item_frame_map_bit", (byte) 0);
- if (session.getUpstream().getProtocolVersion() >= Bedrock_v465.V465_CODEC.getProtocolVersion()) {
- statesBuilder.putByte("item_frame_photo_bit", (byte) 0);
- }
+ .putByte("item_frame_map_bit", (byte) 0)
+ .putByte("item_frame_photo_bit", (byte) 0);
blockBuilder.put("states", statesBuilder.build());
bedrockRuntimeId = session.getBlockMappings().getItemFrame(blockBuilder.build());
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java
index 9980cd2c1..10086be9c 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java
@@ -136,7 +136,7 @@ public class ArmorStandEntity extends LivingEntity {
}
isSmall = newIsSmall;
- if (!isMarker) {
+ if (!isMarker && !isInvisible) { // Addition for isInvisible check caused by https://github.com/GeyserMC/Geyser/issues/2780
toggleSmallStatus();
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java
index 71bab079d..70b5ede99 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java
@@ -382,15 +382,26 @@ public class PlayerEntity extends LivingEntity {
@Override
protected void setDimensions(Pose pose) {
float height;
+ float width;
switch (pose) {
- case SNEAKING -> height = SNEAKING_POSE_HEIGHT;
- case FALL_FLYING, SPIN_ATTACK, SWIMMING -> height = 0.6f;
+ case SNEAKING -> {
+ height = SNEAKING_POSE_HEIGHT;
+ width = definition.width();
+ }
+ case FALL_FLYING, SPIN_ATTACK, SWIMMING -> {
+ height = 0.6f;
+ width = definition.width();
+ }
+ case DYING -> {
+ height = 0.2f;
+ width = 0.2f;
+ }
default -> {
super.setDimensions(pose);
return;
}
}
- setBoundingBoxWidth(definition.width());
+ setBoundingBoxWidth(width);
setBoundingBoxHeight(height);
}
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/BedrockContainerSlot.java b/core/src/main/java/org/geysermc/geyser/inventory/BedrockContainerSlot.java
index e225c5f4d..87c0c92a3 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/BedrockContainerSlot.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/BedrockContainerSlot.java
@@ -26,10 +26,6 @@
package org.geysermc.geyser.inventory;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerSlotType;
-import lombok.Value;
-@Value
-public class BedrockContainerSlot {
- ContainerSlotType container;
- int slot;
+public record BedrockContainerSlot(ContainerSlotType container, int slot) {
}
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Container.java b/core/src/main/java/org/geysermc/geyser/inventory/Container.java
index cf47b8bd6..569802a5a 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/Container.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/Container.java
@@ -27,9 +27,11 @@ package org.geysermc.geyser.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import lombok.Getter;
-import lombok.NonNull;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
+import org.jetbrains.annotations.Range;
+
+import javax.annotation.Nonnull;
/**
* Combination of {@link Inventory} and {@link PlayerInventory}
@@ -60,7 +62,12 @@ public class Container extends Inventory {
}
@Override
- public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {
+ public int getOffsetForHotbar(@Range(from = 0, to = 8) int slot) {
+ return playerInventory.getOffsetForHotbar(slot) - InventoryTranslator.PLAYER_INVENTORY_OFFSET + this.size;
+ }
+
+ @Override
+ public void setItem(int slot, @Nonnull GeyserItemStack newItem, GeyserSession session) {
if (slot < this.size) {
super.setItem(slot, newItem, session);
} else {
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
index a78c9cf51..ca7e90a25 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/Inventory.java
@@ -31,17 +31,19 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.math.vector.Vector3i;
import lombok.Getter;
-import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
+import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.jetbrains.annotations.Range;
+import javax.annotation.Nonnull;
import java.util.Arrays;
@ToString
-public class Inventory {
-
+public abstract class Inventory {
@Getter
protected final int id;
@@ -69,8 +71,7 @@ public class Inventory {
protected final ContainerType containerType;
@Getter
- @Setter
- protected String title;
+ protected final String title;
protected final GeyserItemStack[] items;
@@ -110,7 +111,9 @@ public class Inventory {
return items[slot];
}
- public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {
+ public abstract int getOffsetForHotbar(@Range(from = 0, to = 8) int slot);
+
+ public void setItem(int slot, @Nonnull GeyserItemStack newItem, GeyserSession session) {
if (slot > this.size) {
session.getGeyser().getLogger().debug("Tried to set an item out of bounds! " + this);
return;
@@ -133,7 +136,9 @@ public class Inventory {
protected void updateItemNetId(GeyserItemStack oldItem, GeyserItemStack newItem, GeyserSession session) {
if (!newItem.isEmpty()) {
- if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) {
+ ItemMapping oldMapping = ItemTranslator.getBedrockItemMapping(session, oldItem);
+ ItemMapping newMapping = ItemTranslator.getBedrockItemMapping(session, newItem);
+ if (oldMapping.getBedrockId() == newMapping.getBedrockId()) {
newItem.setNetId(oldItem.getNetId());
} else {
newItem.setNetId(session.getNextItemNetId());
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java
index c4a6a8363..14c796a5f 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/PlayerInventory.java
@@ -26,10 +26,12 @@
package org.geysermc.geyser.inventory;
import lombok.Getter;
-import lombok.NonNull;
import lombok.Setter;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession;
+import org.jetbrains.annotations.Range;
+
+import javax.annotation.Nonnull;
public class PlayerInventory extends Inventory {
/**
@@ -41,7 +43,7 @@ public class PlayerInventory extends Inventory {
private int heldItemSlot;
@Getter
- @NonNull
+ @Nonnull
private GeyserItemStack cursor = GeyserItemStack.EMPTY;
public PlayerInventory() {
@@ -49,7 +51,12 @@ public class PlayerInventory extends Inventory {
heldItemSlot = 0;
}
- public void setCursor(@NonNull GeyserItemStack newCursor, GeyserSession session) {
+ @Override
+ public int getOffsetForHotbar(@Range(from = 0, to = 8) int slot) {
+ return slot + 36;
+ }
+
+ public void setCursor(@Nonnull GeyserItemStack newCursor, GeyserSession session) {
updateItemNetId(cursor, newCursor, session);
cursor = newCursor;
}
@@ -62,7 +69,7 @@ public class PlayerInventory extends Inventory {
return items[36 + heldItemSlot];
}
- public void setItemInHand(@NonNull GeyserItemStack item) {
+ public void setItemInHand(@Nonnull GeyserItemStack item) {
if (36 + heldItemSlot > this.size) {
GeyserImpl.getInstance().getLogger().debug("Held item slot was larger than expected!");
return;
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
index 0a1d0a36e..b0cca53d9 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/click/ClickPlan.java
@@ -40,20 +40,22 @@ import org.geysermc.geyser.inventory.SlotType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.CraftingInventoryTranslator;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
-import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
import org.geysermc.geyser.util.InventoryUtils;
import org.jetbrains.annotations.Contract;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
-public class ClickPlan {
+public final class ClickPlan {
private final List plan = new ArrayList<>();
private final Int2ObjectMap simulatedItems;
+ /**
+ * Used for 1.17.1+ proper packet translation - any non-cursor item that is changed in a single transaction gets sent here.
+ */
+ private Int2ObjectMap changedItems;
private GeyserItemStack simulatedCursor;
- private boolean simulating;
+ private boolean finished;
private final GeyserSession session;
private final InventoryTranslator translator;
@@ -66,16 +68,11 @@ public class ClickPlan {
this.inventory = inventory;
this.simulatedItems = new Int2ObjectOpenHashMap<>(inventory.getSize());
+ this.changedItems = null;
this.simulatedCursor = session.getPlayerInventory().getCursor().copy();
- this.simulating = true;
+ this.finished = false;
- if (translator instanceof PlayerInventoryTranslator) {
- gridSize = 4;
- } else if (translator instanceof CraftingInventoryTranslator) {
- gridSize = 9;
- } else {
- gridSize = -1;
- }
+ gridSize = translator.getGridSize();
}
private void resetSimulation() {
@@ -88,7 +85,7 @@ public class ClickPlan {
}
public void add(Click click, int slot, boolean force) {
- if (!simulating)
+ if (finished)
throw new UnsupportedOperationException("ClickPlan already executed");
if (click == Click.LEFT_OUTSIDE || click == Click.RIGHT_OUTSIDE) {
@@ -97,6 +94,8 @@ public class ClickPlan {
ClickAction action = new ClickAction(click, slot, force);
plan.add(action);
+ // RUNNING THE SIMULATION HERE IS IMPORTANT. The contents of the simulation are used in complex, multi-stage tasks
+ // such as autocrafting.
simulateAction(action);
}
@@ -112,33 +111,48 @@ public class ClickPlan {
refresh = true;
}
- //int stateId = stateIdHack(action);
+ changedItems = new Int2ObjectOpenHashMap<>();
- //simulateAction(action);
+ boolean emulatePost1_16Logic = session.isEmulatePost1_16Logic();
+
+ int stateId;
+ if (emulatePost1_16Logic) {
+ stateId = stateIdHack(action);
+ simulateAction(action);
+ } else {
+ stateId = inventory.getStateId();
+ }
ItemStack clickedItemStack;
if (!planIter.hasNext() && refresh) {
clickedItemStack = InventoryUtils.REFRESH_ITEM;
- } else if (action.click.actionType == ContainerActionType.DROP_ITEM || action.slot == Click.OUTSIDE_SLOT) {
- clickedItemStack = null;
} else {
- //// The action must be simulated first as Java expects the new contents of the cursor (as of 1.18.1)
- //clickedItemStack = simulatedCursor.getItemStack(); TODO fix - this is the proper behavior but it terribly breaks 1.16.5
- clickedItemStack = getItem(action.slot).getItemStack();
+ if (emulatePost1_16Logic) {
+ // The action must be simulated first as Java expects the new contents of the cursor (as of 1.18.1)
+ clickedItemStack = simulatedCursor.getItemStack();
+ } else {
+ if (action.click.actionType == ContainerActionType.DROP_ITEM || action.slot == Click.OUTSIDE_SLOT) {
+ clickedItemStack = null;
+ } else {
+ clickedItemStack = getItem(action.slot).getItemStack();
+ }
+ }
+ }
+
+ if (!emulatePost1_16Logic) {
+ simulateAction(action);
}
ServerboundContainerClickPacket clickPacket = new ServerboundContainerClickPacket(
inventory.getId(),
- inventory.getStateId(),
+ stateId,
action.slot,
action.click.actionType,
action.click.action,
clickedItemStack,
- Collections.emptyMap() // Anything else we change, at this time, should have a packet sent to address
+ changedItems
);
- simulateAction(action);
-
session.sendDownstreamPacket(clickPacket);
}
@@ -146,19 +160,11 @@ public class ClickPlan {
for (Int2ObjectMap.Entry simulatedSlot : simulatedItems.int2ObjectEntrySet()) {
inventory.setItem(simulatedSlot.getIntKey(), simulatedSlot.getValue(), session);
}
- simulating = false;
+ finished = true;
}
public GeyserItemStack getItem(int slot) {
- return getItem(slot, true);
- }
-
- public GeyserItemStack getItem(int slot, boolean generate) {
- if (generate) {
- return simulatedItems.computeIfAbsent(slot, k -> inventory.getItem(slot).copy());
- } else {
- return simulatedItems.getOrDefault(slot, inventory.getItem(slot));
- }
+ return simulatedItems.computeIfAbsent(slot, k -> inventory.getItem(slot).copy());
}
public GeyserItemStack getCursor() {
@@ -166,23 +172,40 @@ public class ClickPlan {
}
private void setItem(int slot, GeyserItemStack item) {
- if (simulating) {
- simulatedItems.put(slot, item);
- } else {
- inventory.setItem(slot, item, session);
- }
+ simulatedItems.put(slot, item);
+ onSlotItemChange(slot, item);
}
private void setCursor(GeyserItemStack item) {
- if (simulating) {
- simulatedCursor = item;
- } else {
- session.getPlayerInventory().setCursor(item, session);
+ simulatedCursor = item;
+ }
+
+ private void add(int slot, GeyserItemStack itemStack, int amount) {
+ itemStack.add(amount);
+ onSlotItemChange(slot, itemStack);
+ }
+
+ private void sub(int slot, GeyserItemStack itemStack, int amount) {
+ itemStack.sub(amount);
+ onSlotItemChange(slot, itemStack);
+ }
+
+ private void setAmount(int slot, GeyserItemStack itemStack, int amount) {
+ itemStack.setAmount(amount);
+ onSlotItemChange(slot, itemStack);
+ }
+
+ /**
+ * Does not need to be called for the cursor
+ */
+ private void onSlotItemChange(int slot, GeyserItemStack itemStack) {
+ if (changedItems != null) {
+ changedItems.put(slot, itemStack.getItemStack());
}
}
private void simulateAction(ClickAction action) {
- GeyserItemStack cursor = simulating ? getCursor() : session.getPlayerInventory().getCursor();
+ GeyserItemStack cursor = getCursor();
switch (action.click) {
case LEFT_OUTSIDE -> {
setCursor(GeyserItemStack.EMPTY);
@@ -196,7 +219,7 @@ public class ClickPlan {
}
}
- GeyserItemStack clicked = simulating ? getItem(action.slot) : inventory.getItem(action.slot);
+ GeyserItemStack clicked = getItem(action.slot);
if (translator.getSlotType(action.slot) == SlotType.OUTPUT) {
switch (action.click) {
case LEFT, RIGHT -> {
@@ -206,6 +229,7 @@ public class ClickPlan {
cursor.add(clicked.getAmount());
}
reduceCraftingGrid(false);
+ setItem(action.slot, GeyserItemStack.EMPTY); // Matches Java Edition 1.18.1
}
case LEFT_SHIFT -> reduceCraftingGrid(true);
}
@@ -217,55 +241,55 @@ public class ClickPlan {
setItem(action.slot, cursor);
} else {
setCursor(GeyserItemStack.EMPTY);
- clicked.add(cursor.getAmount());
+ add(action.slot, clicked, cursor.getAmount());
}
break;
case RIGHT:
if (cursor.isEmpty() && !clicked.isEmpty()) {
int half = clicked.getAmount() / 2; //smaller half
setCursor(clicked.copy(clicked.getAmount() - half)); //larger half
- clicked.setAmount(half);
+ setAmount(action.slot, clicked, half);
} else if (!cursor.isEmpty() && clicked.isEmpty()) {
cursor.sub(1);
setItem(action.slot, cursor.copy(1));
} else if (InventoryUtils.canStack(cursor, clicked)) {
cursor.sub(1);
- clicked.add(1);
+ add(action.slot, clicked, 1);
}
break;
case SWAP_TO_HOTBAR_1:
- swap(action.slot, 36, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(0), clicked);
break;
case SWAP_TO_HOTBAR_2:
- swap(action.slot, 37, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(1), clicked);
break;
case SWAP_TO_HOTBAR_3:
- swap(action.slot, 38, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(2), clicked);
break;
case SWAP_TO_HOTBAR_4:
- swap(action.slot, 39, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(3), clicked);
break;
case SWAP_TO_HOTBAR_5:
- swap(action.slot, 40, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(4), clicked);
break;
case SWAP_TO_HOTBAR_6:
- swap(action.slot, 41, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(5), clicked);
break;
case SWAP_TO_HOTBAR_7:
- swap(action.slot, 42, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(6), clicked);
break;
case SWAP_TO_HOTBAR_8:
- swap(action.slot, 43, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(7), clicked);
break;
case SWAP_TO_HOTBAR_9:
- swap(action.slot, 44, clicked);
+ swap(action.slot, inventory.getOffsetForHotbar(8), clicked);
break;
case LEFT_SHIFT:
//TODO
break;
case DROP_ONE:
if (!clicked.isEmpty()) {
- clicked.sub(1);
+ sub(action.slot, clicked, 1);
}
break;
case DROP_ALL:
@@ -279,7 +303,7 @@ public class ClickPlan {
* Swap between two inventory slots without a cursor. This should only be used with {@link ContainerActionType#MOVE_TO_HOTBAR_SLOT}
*/
private void swap(int sourceSlot, int destSlot, GeyserItemStack sourceItem) {
- GeyserItemStack destinationItem = simulating ? getItem(destSlot) : inventory.getItem(destSlot);
+ GeyserItemStack destinationItem = getItem(destSlot);
setItem(sourceSlot, destinationItem);
setItem(destSlot, sourceItem);
}
@@ -292,63 +316,44 @@ public class ClickPlan {
stateId = inventory.getStateId();
}
- // This is a hack.
- // Java will never ever send more than one container click packet per set of actions.
+ // Java will never ever send more than one container click packet per set of actions*.
+ // *(exception being Java's "quick craft"/painting feature)
// Bedrock might, and this would generally fall into one of two categories:
// - Bedrock is sending an item directly from one slot to another, without picking it up, that cannot
// be expressed with a shift click
// - Bedrock wants to pick up or place an arbitrary amount of items that cannot be expressed from
// one left/right click action.
- // When Bedrock does one of these actions and sends multiple packets, a 1.17.1+ server will
- // increment the state ID on each confirmation packet it sends back (I.E. set slot). Then when it
- // reads our next packet, because we kept the same state ID but the server incremented it, it'll be
- // desynced and send the entire inventory contents back at us.
- // This hack therefore increments the state ID to what the server will presumably send back to us.
- // (This won't be perfect, but should get us through most vanilla situations, and if this is wrong the
- // server will just send a set content packet back at us)
+ // Java typically doesn't increment the state ID if you send a vanilla-accurate container click packet,
+ // but it will increment the state ID with a vanilla client in at least the crafting table
if (inventory.getContainerType() == ContainerType.CRAFTING && CraftingInventoryTranslator.isCraftingGrid(action.slot)) {
// 1.18.1 sends a second set slot update for any action in the crafting grid
// And an additional packet if something is removed (Mojmap: CraftingContainer#removeItem)
- //TODO this code kind of really sucks; it's potentially possible to see what Bedrock sends us and send a PlaceRecipePacket
int stateIdIncrements;
GeyserItemStack clicked = getItem(action.slot);
if (action.click == Click.LEFT) {
if (!clicked.isEmpty() && !InventoryUtils.canStack(simulatedCursor, clicked)) {
// An item is removed from the crafting table; yes deletion
- stateIdIncrements = 3;
+ stateIdIncrements = 2;
} else {
// We can stack and we add all the items to the crafting slot; no deletion
- stateIdIncrements = 2;
+ stateIdIncrements = 1;
}
} else if (action.click == Click.RIGHT) {
- if (simulatedCursor.isEmpty() && !clicked.isEmpty()) {
- // Items are taken; yes deletion
- stateIdIncrements = 3;
- } else if ((!simulatedCursor.isEmpty() && clicked.isEmpty()) || InventoryUtils.canStack(simulatedCursor, clicked)) {
- // Adding our cursor item to the slot; no deletion
- stateIdIncrements = 2;
- } else {
- // ?? nothing I guess
- stateIdIncrements = 2;
- }
+ stateIdIncrements = 1;
+ } else if (action.click.actionType == ContainerActionType.MOVE_TO_HOTBAR_SLOT) {
+ stateIdIncrements = 1;
} else {
if (session.getGeyser().getConfig().isDebugMode()) {
session.getGeyser().getLogger().debug("Not sure how to handle state ID hack in crafting table: " + plan);
}
- stateIdIncrements = 2;
+ stateIdIncrements = 1;
}
inventory.incrementStateId(stateIdIncrements);
- } else if (action.click.action instanceof MoveToHotbarAction) {
- // Two slot changes sent
- inventory.incrementStateId(2);
- } else {
- inventory.incrementStateId(1);
}
return stateId;
}
- //TODO
private void reduceCraftingGrid(boolean makeAll) {
if (gridSize == -1)
return;
@@ -370,9 +375,12 @@ public class ClickPlan {
}
for (int i = 0; i < gridSize; i++) {
- GeyserItemStack item = getItem(i + 1);
- if (!item.isEmpty())
- item.sub(crafted);
+ final int slot = i + 1;
+ GeyserItemStack item = getItem(slot);
+ if (!item.isEmpty()) {
+ // These changes should be broadcasted to the server
+ sub(slot, item, crafted);
+ }
}
}
@@ -385,6 +393,10 @@ public class ClickPlan {
for (ClickAction action : plan) {
if (translator.getSlotType(action.slot) == SlotType.NORMAL && action.slot != Click.OUTSIDE_SLOT) {
affectedSlots.add(action.slot);
+ if (action.click.actionType == ContainerActionType.MOVE_TO_HOTBAR_SLOT) {
+ //TODO won't work if offhand is added
+ affectedSlots.add(inventory.getOffsetForHotbar(((MoveToHotbarAction) action.click.action).ordinal()));
+ }
}
}
return affectedSlots;
diff --git a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java
index d28b95203..c4bd05b13 100644
--- a/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java
+++ b/core/src/main/java/org/geysermc/geyser/network/MinecraftProtocol.java
@@ -28,9 +28,9 @@ package org.geysermc.geyser.network;
import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
import com.github.steveice10.mc.protocol.codec.PacketCodec;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
-import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
+import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
import java.util.ArrayList;
import java.util.Arrays;
@@ -45,7 +45,7 @@ public final class MinecraftProtocol {
* Default Bedrock codec that should act as a fallback. Should represent the latest available
* release of the game that Geyser supports.
*/
- public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v475.V475_CODEC;
+ public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v486.V486_CODEC;
/**
* A list of all supported Bedrock versions that can join Geyser
*/
@@ -58,8 +58,8 @@ public final class MinecraftProtocol {
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
static {
- SUPPORTED_BEDROCK_CODECS.add(Bedrock_v465.V465_CODEC);
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v471.V471_CODEC);
+ SUPPORTED_BEDROCK_CODECS.add(Bedrock_v475.V475_CODEC.toBuilder().minecraftVersion("1.18.0/1.18.1/1.18.2").build());
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
}
diff --git a/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java b/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java
new file mode 100644
index 000000000..892f4a6df
--- /dev/null
+++ b/core/src/main/java/org/geysermc/geyser/registry/IntMappedRegistry.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2019-2022 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.registry;
+
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import org.geysermc.geyser.registry.loader.RegistryLoader;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.function.Supplier;
+
+/**
+ * A mapped registry with an integer as the key. This class is designed to minimize the need for boxing/unboxing keys.
+ *
+ * @param the value
+ */
+public class IntMappedRegistry extends AbstractMappedRegistry> {
+ protected IntMappedRegistry(I input, RegistryLoader> registryLoader) {
+ super(input, registryLoader);
+ }
+
+ /**
+ * Returns the value registered by the given integer.
+ *
+ * @param i the integer
+ * @return the value registered by the given integer.
+ */
+ public V get(int i) {
+ return this.mappings.get(i);
+ }
+
+ @Nullable
+ @Override
+ @Deprecated
+ public V get(Integer key) {
+ return super.get(key);
+ }
+
+ /**
+ * Returns the value registered by the given key or the default value
+ * specified if null.
+ *
+ * @param i the key
+ * @param defaultValue the default value
+ * @return the value registered by the given key or the default value
+ * specified if null.
+ */
+ public V getOrDefault(int i, V defaultValue) {
+ return this.mappings.getOrDefault(i, defaultValue);
+ }
+
+ @Override
+ @Deprecated
+ public V getOrDefault(Integer key, V defaultValue) {
+ return super.getOrDefault(key, defaultValue);
+ }
+
+ /**
+ * Registers a new value into this registry with the given key.
+ *
+ * @param i the key
+ * @param value the value
+ * @return a new value into this registry with the given key.
+ */
+ public V register(int i, V value) {
+ return this.mappings.put(i, value);
+ }
+
+ @Override
+ @Deprecated
+ public V register(Integer key, V value) {
+ return super.register(key, value);
+ }
+
+ /**
+ * Creates a new integer mapped registry with the given {@link RegistryLoader}. The
+ * input type is not specified here, meaning the loader return type is either
+ * predefined, or the registry is populated at a later point.
+ *
+ * @param registryLoader the registry loader
+ * @param the input
+ * @param the map value
+ * @return a new registry with the given RegistryLoader
+ */
+ public static IntMappedRegistry create(RegistryLoader> registryLoader) {
+ return new IntMappedRegistry<>(null, registryLoader);
+ }
+
+ /**
+ * Creates a new integer mapped registry with the given {@link RegistryLoader} and input.
+ *
+ * @param registryLoader the registry loader
+ * @param the input
+ * @param the map value
+ * @return a new registry with the given RegistryLoader supplier
+ */
+ public static IntMappedRegistry create(I input, Supplier>> registryLoader) {
+ return new IntMappedRegistry<>(input, registryLoader.get());
+ }
+}
diff --git a/core/src/main/java/org/geysermc/geyser/registry/Registries.java b/core/src/main/java/org/geysermc/geyser/registry/Registries.java
index 173bfbd1a..791134aa7 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/Registries.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/Registries.java
@@ -44,20 +44,20 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.api.extension.ExtensionLoader;
import org.geysermc.geyser.entity.EntityDefinition;
-import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
-import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
-import org.geysermc.geyser.translator.sound.SoundTranslator;
-import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
-import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
-import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
import org.geysermc.geyser.registry.loader.*;
import org.geysermc.geyser.registry.populator.ItemRegistryPopulator;
+import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
import org.geysermc.geyser.registry.populator.RecipeRegistryPopulator;
import org.geysermc.geyser.registry.type.EnchantmentData;
import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.registry.type.ParticleMapping;
import org.geysermc.geyser.registry.type.SoundMapping;
+import org.geysermc.geyser.translator.collision.BlockCollision;
+import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
+import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
+import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
+import org.geysermc.geyser.translator.sound.SoundTranslator;
import java.util.EnumMap;
import java.util.List;
@@ -96,7 +96,7 @@ public final class Registries {
/**
* A mapped registry containing which holds block IDs to its {@link BlockCollision}.
*/
- public static final SimpleMappedRegistry COLLISIONS = SimpleMappedRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collision.json"), CollisionRegistryLoader::new);
+ public static final IntMappedRegistry COLLISIONS = IntMappedRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collision.json"), CollisionRegistryLoader::new);
/**
* A versioned registry which holds a {@link RecipeType} to a corresponding list of {@link CraftingData}.
@@ -154,7 +154,7 @@ public final class Registries {
* A mapped registry holding the available records, with the ID of the record being the key, and the {@link com.nukkitx.protocol.bedrock.data.SoundEvent}
* as the value.
*/
- public static final SimpleMappedRegistry RECORDS = SimpleMappedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
+ public static final IntMappedRegistry RECORDS = IntMappedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
/**
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
diff --git a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java
index c6cd092d4..b74573a4e 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/loader/CollisionRegistryLoader.java
@@ -50,10 +50,10 @@ import java.util.regex.Pattern;
/**
* Loads collision data from the given resource path.
*/
-public class CollisionRegistryLoader extends MultiResourceRegistryLoader> {
+public class CollisionRegistryLoader extends MultiResourceRegistryLoader> {
@Override
- public Map load(Pair input) {
+ public Int2ObjectMap load(Pair input) {
Int2ObjectMap collisions = new Int2ObjectOpenHashMap<>();
Map, CollisionInfo> annotationMap = new IdentityHashMap<>();
diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
index b1066c79c..8238bcea1 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
@@ -28,8 +28,8 @@ package org.geysermc.geyser.registry.populator;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableMap;
import com.nukkitx.nbt.*;
-import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
+import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
@@ -46,7 +46,10 @@ import org.geysermc.geyser.util.BlockUtils;
import java.io.DataInputStream;
import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.Map;
import java.util.function.BiFunction;
import java.util.zip.GZIPInputStream;
@@ -59,8 +62,34 @@ public class BlockRegistryPopulator {
static {
ImmutableMap.Builder, BiFunction> stateMapperBuilder = ImmutableMap., BiFunction>builder()
- .put(ObjectIntPair.of("1_17_30", Bedrock_v465.V465_CODEC.getProtocolVersion()), EMPTY_MAPPER)
- .put(ObjectIntPair.of("1_17_40", Bedrock_v471.V471_CODEC.getProtocolVersion()), EMPTY_MAPPER);
+ .put(ObjectIntPair.of("1_17_40", Bedrock_v471.V471_CODEC.getProtocolVersion()), EMPTY_MAPPER)
+ .put(ObjectIntPair.of("1_18_10", Bedrock_v486.V486_CODEC.getProtocolVersion()), (bedrockIdentifier, statesBuilder) -> {
+ statesBuilder.remove("no_drop_bit"); // Used in skulls
+ if (bedrockIdentifier.equals("minecraft:glow_lichen")) {
+ // Moved around north, south, west
+ int bits = (int) statesBuilder.get("multi_face_direction_bits");
+ boolean north = (bits & (1 << 2)) != 0;
+ boolean south = (bits & (1 << 3)) != 0;
+ boolean west = (bits & (1 << 4)) != 0;
+ if (north) {
+ bits |= 1 << 4;
+ } else {
+ bits &= ~(1 << 4);
+ }
+ if (south) {
+ bits |= 1 << 2;
+ } else {
+ bits &= ~(1 << 2);
+ }
+ if (west) {
+ bits |= 1 << 3;
+ } else {
+ bits &= ~(1 << 3);
+ }
+ statesBuilder.put("multi_face_direction_bits", bits);
+ }
+ return null;
+ });
BLOCK_MAPPERS = stateMapperBuilder.build();
}
diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java
index d448bfa6a..1b56a83de 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java
@@ -35,9 +35,9 @@ import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
-import com.nukkitx.protocol.bedrock.v465.Bedrock_v465;
import com.nukkitx.protocol.bedrock.v471.Bedrock_v471;
import com.nukkitx.protocol.bedrock.v475.Bedrock_v475;
+import com.nukkitx.protocol.bedrock.v486.Bedrock_v486;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
@@ -63,9 +63,9 @@ public class ItemRegistryPopulator {
static {
PALETTE_VERSIONS = new Object2ObjectOpenHashMap<>();
- PALETTE_VERSIONS.put("1_17_30", new PaletteVersion(Bedrock_v465.V465_CODEC.getProtocolVersion(), Collections.emptyMap()));
PALETTE_VERSIONS.put("1_17_40", new PaletteVersion(Bedrock_v471.V471_CODEC.getProtocolVersion(), Collections.emptyMap()));
PALETTE_VERSIONS.put("1_18_0", new PaletteVersion(Bedrock_v475.V475_CODEC.getProtocolVersion(), Collections.emptyMap()));
+ PALETTE_VERSIONS.put("1_18_10", new PaletteVersion(Bedrock_v486.V486_CODEC.getProtocolVersion(), Collections.emptyMap()));
}
private record PaletteVersion(int protocolVersion, Map additionalTranslatedItems) {
diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
index 591934d6d..c79980f6f 100644
--- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
@@ -38,10 +38,14 @@ import com.github.steveice10.mc.protocol.data.ProtocolState;
import com.github.steveice10.mc.protocol.data.UnexpectedEncryptionException;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
+import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference;
import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
+import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility;
+import com.github.steveice10.mc.protocol.data.game.setting.SkinPart;
import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic;
import com.github.steveice10.mc.protocol.data.game.statistic.Statistic;
import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket;
+import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket;
@@ -245,7 +249,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
@Setter
private Vector2i lastChunkPosition = null;
- private int renderDistance;
+ @Setter
+ private int clientRenderDistance = -1;
+ private int serverRenderDistance;
// Exposed for GeyserConnect usage
protected boolean sentSpawnPacket;
@@ -355,6 +361,15 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
@Setter
private Int2ObjectMap stonecutterRecipes;
+ /**
+ * Starting in 1.17, Java servers expect the carriedItem
parameter of the serverbound click container
+ * packet to be the current contents of the mouse after the transaction has been done. 1.16 expects the clicked slot
+ * contents before any transaction is done. With the current ViaVersion structure, if we do not send what 1.16 expects
+ * and send multiple click container packets, then successive transactions will be rejected.
+ */
+ @Setter
+ private boolean emulatePost1_16Logic = true;
+
/**
* The current attack speed of the player. Used for sending proper cooldown timings.
* Setting a default fixes cooldowns not showing up on a fresh world.
@@ -790,6 +805,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
FloodgateSkinUploader skinUploader = geyser.getSkinUploader();
FloodgateCipher cipher = geyser.getCipher();
+ String bedrockAddress = upstream.getAddress().getAddress().getHostAddress();
+ // both BungeeCord and Velocity remove the IPv6 scope (if there is one) for Spigot
+ int ipv6ScopeIndex = bedrockAddress.indexOf('%');
+ if (ipv6ScopeIndex != -1) {
+ bedrockAddress = bedrockAddress.substring(0, ipv6ScopeIndex);
+ }
+
encryptedData = cipher.encryptFromString(BedrockData.of(
clientData.getGameVersion(),
authData.name(),
@@ -798,7 +820,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
clientData.getLanguageCode(),
clientData.getUiProfile().ordinal(),
clientData.getCurrentInputMode().ordinal(),
- upstream.getAddress().getAddress().getHostAddress(),
+ bedrockAddress,
skinUploader.getId(),
skinUploader.getVerifyCode()
).toString());
@@ -1160,9 +1182,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
return clientData.getLanguageCode();
}
- public void setRenderDistance(int renderDistance) {
+ public void setServerRenderDistance(int renderDistance) {
renderDistance = GenericMath.ceil(++renderDistance * MathUtils.SQRT_OF_TWO); //square to circle
- this.renderDistance = renderDistance;
+ this.serverRenderDistance = renderDistance;
ChunkRadiusUpdatedPacket chunkRadiusUpdatedPacket = new ChunkRadiusUpdatedPacket();
chunkRadiusUpdatedPacket.setRadius(renderDistance);
@@ -1420,6 +1442,27 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
sendUpstreamPacket(adventureSettingsPacket);
}
+ private int getRenderDistance() {
+ if (clientRenderDistance != -1) {
+ // The client has sent a render distance
+ return clientRenderDistance;
+ }
+ return serverRenderDistance;
+ }
+
+ // We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc
+ private static final List SKIN_PARTS = Arrays.asList(SkinPart.values());
+
+ /**
+ * Send a packet to the server to indicate client render distance, locale, skin parts, and hand preference.
+ */
+ public void sendJavaClientSettings() {
+ ServerboundClientInformationPacket clientSettingsPacket = new ServerboundClientInformationPacket(locale(),
+ getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS,
+ HandPreference.RIGHT_HAND, false, true);
+ sendDownstreamPacket(clientSettingsPacket);
+ }
+
/**
* Used for updating statistic values since we only get changes from the server
*
diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java
index f0cbbb189..05c2628df 100644
--- a/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java
+++ b/core/src/main/java/org/geysermc/geyser/session/cache/LodestoneCache.java
@@ -30,9 +30,6 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
import org.geysermc.geyser.inventory.GeyserItemStack;
import javax.annotation.Nullable;
@@ -43,7 +40,7 @@ import java.util.WeakHashMap;
* A temporary cache for lodestone information.
* Bedrock requests the lodestone position information separately from the item.
*/
-public class LodestoneCache {
+public final class LodestoneCache {
/**
* A list of any GeyserItemStacks that are lodestones. Used mainly to minimize Bedrock's "pop-in" effect
* when a new item has been created; instead we can re-use already existing IDs
@@ -121,8 +118,16 @@ public class LodestoneCache {
}
public @Nullable LodestonePos getPos(int id) {
- // We should not need to check the activeLodestones map as Bedrock should already be aware of this ID
- return this.lodestones.remove(id);
+ LodestonePos pos = this.lodestones.remove(id);
+ if (pos != null) {
+ return pos;
+ }
+ for (LodestonePos activePos : this.activeLodestones.values()) {
+ if (activePos.id == id) {
+ return activePos;
+ }
+ }
+ return null;
}
public void clear() {
@@ -131,16 +136,7 @@ public class LodestoneCache {
this.lodestones.clear();
}
- @Getter
- @AllArgsConstructor
- @EqualsAndHashCode
- public static class LodestonePos {
- private final int id;
- private final int x;
- private final int y;
- private final int z;
- private final String dimension;
-
+ public record LodestonePos(int id, int x, int y, int z, String dimension) {
boolean equals(int x, int y, int z, String dimension) {
return this.x == x && this.y == y && this.z == z && this.dimension.equals(dimension);
}
diff --git a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java
index 67364f5c6..4383dc4e9 100644
--- a/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java
+++ b/core/src/main/java/org/geysermc/geyser/skin/SkinProvider.java
@@ -115,10 +115,12 @@ public class SkinProvider {
WEARING_CUSTOM_SKULL = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkull\"}}", wearingCustomSkull, false);
String wearingCustomSkullSlim = new String(FileUtils.readAllBytes("bedrock/skin/geometry.humanoid.wearingCustomSkullSlim.json"), StandardCharsets.UTF_8);
WEARING_CUSTOM_SKULL_SLIM = new SkinGeometry("{\"geometry\" :{\"default\" :\"geometry.humanoid.wearingCustomSkullSlim\"}}", wearingCustomSkullSlim, false);
+ }
+ public static void registerCacheImageTask(GeyserImpl geyser) {
// Schedule Daily Image Expiry if we are caching them
- if (GeyserImpl.getInstance().getConfig().getCacheImages() > 0) {
- GeyserImpl.getInstance().getScheduledThread().scheduleAtFixedRate(() -> {
+ if (geyser.getConfig().getCacheImages() > 0) {
+ geyser.getScheduledThread().scheduleAtFixedRate(() -> {
File cacheFolder = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("images").toFile();
if (!cacheFolder.exists()) {
return;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java
index f6abdfcd2..f194d0d3f 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BeaconInventoryTranslator.java
@@ -38,17 +38,16 @@ import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequ
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket;
+import it.unimi.dsi.fastutil.ints.IntSets;
import org.geysermc.geyser.inventory.BeaconContainer;
+import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.PlayerInventory;
-import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.holder.BlockInventoryHolder;
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
+import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InventoryUtils;
-import java.util.Collections;
-
public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator {
public BeaconInventoryTranslator() {
super(1, new BlockInventoryHolder("minecraft:beacon", com.nukkitx.protocol.bedrock.data.inventory.ContainerType.BEACON) {
@@ -104,7 +103,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
}
@Override
- public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
+ protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return action.getType() == StackRequestActionType.BEACON_PAYMENT;
}
@@ -114,7 +113,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
BeaconPaymentStackRequestActionData beaconPayment = (BeaconPaymentStackRequestActionData) request.getActions()[0];
ServerboundSetBeaconPacket packet = new ServerboundSetBeaconPacket(beaconPayment.getPrimaryEffect(), beaconPayment.getSecondaryEffect());
session.sendDownstreamPacket(packet);
- return acceptRequest(request, makeContainerEntries(session, inventory, Collections.emptySet()));
+ return acceptRequest(request, makeContainerEntries(session, inventory, IntSets.emptySet()));
}
@Override
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java
index ec3335f3c..61e2258b6 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/CraftingInventoryTranslator.java
@@ -37,6 +37,11 @@ public class CraftingInventoryTranslator extends AbstractBlockInventoryTranslato
super(10, "minecraft:crafting_table", ContainerType.WORKBENCH, UIInventoryUpdater.INSTANCE);
}
+ @Override
+ public int getGridSize() {
+ return 9;
+ }
+
@Override
public SlotType getSlotType(int javaSlot) {
if (javaSlot == 0) {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java
index 97b78aec5..800b35901 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/EnchantingInventoryTranslator.java
@@ -27,23 +27,22 @@ package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
-import com.nukkitx.protocol.bedrock.data.inventory.*;
+import com.nukkitx.protocol.bedrock.data.inventory.ContainerSlotType;
+import com.nukkitx.protocol.bedrock.data.inventory.EnchantOptionData;
+import com.nukkitx.protocol.bedrock.data.inventory.ItemStackRequest;
+import com.nukkitx.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.CraftRecipeStackRequestActionData;
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket;
import com.nukkitx.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
-import org.geysermc.geyser.inventory.EnchantingContainer;
-import org.geysermc.geyser.inventory.GeyserEnchantOption;
-import org.geysermc.geyser.inventory.Inventory;
-import org.geysermc.geyser.inventory.PlayerInventory;
-import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.inventory.BedrockContainerSlot;
-import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
+import it.unimi.dsi.fastutil.ints.IntSets;
+import org.geysermc.geyser.inventory.*;
import org.geysermc.geyser.inventory.item.Enchantment;
+import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
+import org.geysermc.geyser.session.GeyserSession;
import java.util.Arrays;
-import java.util.Collections;
public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator {
public EnchantingInventoryTranslator() {
@@ -104,7 +103,7 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
}
@Override
- public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
+ protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return action.getType() == StackRequestActionType.CRAFT_RECIPE;
}
@@ -130,7 +129,7 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
}
ServerboundContainerButtonClickPacket packet = new ServerboundContainerButtonClickPacket(inventory.getId(), javaSlot);
session.sendDownstreamPacket(packet);
- return acceptRequest(request, makeContainerEntries(session, inventory, Collections.emptySet()));
+ return acceptRequest(request, makeContainerEntries(session, inventory, IntSets.emptySet()));
}
@Override
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
index 8318e18f6..e6a9faf74 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
@@ -26,12 +26,11 @@
package org.geysermc.geyser.translator.inventory;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
-import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
+import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData;
import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData;
-import com.github.steveice10.mc.protocol.data.game.inventory.ContainerType;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerSlotType;
@@ -43,15 +42,10 @@ import it.unimi.dsi.fastutil.ints.*;
import lombok.AllArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.inventory.CartographyContainer;
-import org.geysermc.geyser.inventory.GeyserItemStack;
-import org.geysermc.geyser.inventory.Inventory;
-import org.geysermc.geyser.inventory.PlayerInventory;
-import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.inventory.BedrockContainerSlot;
-import org.geysermc.geyser.inventory.SlotType;
+import org.geysermc.geyser.inventory.*;
import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.inventory.click.ClickPlan;
+import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.chest.DoubleChestInventoryTranslator;
import org.geysermc.geyser.translator.inventory.chest.SingleChestInventoryTranslator;
import org.geysermc.geyser.translator.inventory.furnace.BlastFurnaceInventoryTranslator;
@@ -119,6 +113,13 @@ public abstract class InventoryTranslator {
public abstract SlotType getSlotType(int javaSlot);
public abstract Inventory createInventory(String name, int windowId, ContainerType containerType, PlayerInventory playerInventory);
+ /**
+ * Used for crafting-related transactions. Will override in PlayerInventoryTranslator and CraftingInventoryTranslator.
+ */
+ public int getGridSize() {
+ return -1;
+ }
+
/**
* Should be overwritten in cases where specific inventories should reject an item being in a specific spot.
* For examples, looms use this to reject items that are dyes in Bedrock but not in Java.
@@ -136,7 +137,7 @@ public abstract class InventoryTranslator {
* Should be overrided if this request matches a certain criteria and shouldn't be treated normally.
* E.G. anvil renaming or enchanting
*/
- public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
+ protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return false;
}
@@ -147,7 +148,7 @@ public abstract class InventoryTranslator {
return rejectRequest(request);
}
- public void translateRequests(GeyserSession session, Inventory inventory, List requests) {
+ public final void translateRequests(GeyserSession session, Inventory inventory, List requests) {
boolean refresh = false;
ItemStackResponsePacket responsePacket = new ItemStackResponsePacket();
for (ItemStackRequest request : requests) {
@@ -199,10 +200,6 @@ public abstract class InventoryTranslator {
case PLACE: {
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) {
- if (session.getGameMode().equals(GameMode.CREATIVE) && transferAction.getSource().getContainer() == ContainerSlotType.CRAFTING_INPUT &&
- transferAction.getSource().getSlot() >= 28 && transferAction.getSource().getSlot() <= 31) {
- return rejectRequest(request, false);
- }
if (session.getGeyser().getConfig().isDebugMode()) {
session.getGeyser().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.name());
dumpStackRequestDetails(session, inventory, transferAction.getSource(), transferAction.getDestination());
@@ -212,17 +209,19 @@ public abstract class InventoryTranslator {
int sourceSlot = bedrockSlotToJava(transferAction.getSource());
int destSlot = bedrockSlotToJava(transferAction.getDestination());
+ boolean isSourceCursor = isCursor(transferAction.getSource());
+ boolean isDestCursor = isCursor(transferAction.getDestination());
if (shouldRejectItemPlace(session, inventory, transferAction.getSource().getContainer(),
- isCursor(transferAction.getSource()) ? -1 : sourceSlot,
- transferAction.getDestination().getContainer(), isCursor(transferAction.getDestination()) ? -1 : destSlot)) {
+ isSourceCursor ? -1 : sourceSlot,
+ transferAction.getDestination().getContainer(), isDestCursor ? -1 : destSlot)) {
// This item would not be here in Java
return rejectRequest(request, false);
}
- if (isCursor(transferAction.getSource()) && isCursor(transferAction.getDestination())) { //???
+ if (isSourceCursor && isDestCursor) { //???
return rejectRequest(request);
- } else if (isCursor(transferAction.getSource())) { //releasing cursor
+ } else if (isSourceCursor) { //releasing cursor
int sourceAmount = cursor.getAmount();
if (transferAction.getCount() == sourceAmount) { //release all
plan.add(Click.LEFT, destSlot);
@@ -231,7 +230,7 @@ public abstract class InventoryTranslator {
plan.add(Click.RIGHT, destSlot);
}
}
- } else if (isCursor(transferAction.getDestination())) { //picking up into cursor
+ } else if (isDestCursor) { //picking up into cursor
GeyserItemStack sourceItem = plan.getItem(sourceSlot);
int sourceAmount = sourceItem.getAmount();
if (cursor.isEmpty()) { //picking up into empty cursor
@@ -313,18 +312,7 @@ public abstract class InventoryTranslator {
if (!isSourceCursor && destination.getContainer() == ContainerSlotType.HOTBAR || destination.getContainer() == ContainerSlotType.HOTBAR_AND_INVENTORY) {
// Tell the server we're pressing one of the hotbar keys to save clicks
- Click click = switch (destination.getSlot()) {
- case 0 -> Click.SWAP_TO_HOTBAR_1;
- case 1 -> Click.SWAP_TO_HOTBAR_2;
- case 2 -> Click.SWAP_TO_HOTBAR_3;
- case 3 -> Click.SWAP_TO_HOTBAR_4;
- case 4 -> Click.SWAP_TO_HOTBAR_5;
- case 5 -> Click.SWAP_TO_HOTBAR_6;
- case 6 -> Click.SWAP_TO_HOTBAR_7;
- case 7 -> Click.SWAP_TO_HOTBAR_8;
- case 8 -> Click.SWAP_TO_HOTBAR_9;
- default -> null;
- };
+ Click click = InventoryUtils.getClickForHotbarSwap(destination.getSlot());
if (click != null) {
plan.add(click, sourceSlot);
break;
@@ -442,6 +430,8 @@ public abstract class InventoryTranslator {
int leftover = 0;
ClickPlan plan = new ClickPlan(session, this, inventory);
+ // Track all the crafting table slots to report back the contents of the slots after crafting
+ IntSet affectedSlots = new IntOpenHashSet();
for (StackRequestActionData action : request.getActions()) {
switch (action.getType()) {
case CRAFT_RECIPE: {
@@ -473,6 +463,7 @@ public abstract class InventoryTranslator {
return rejectRequest(request);
}
craftState = CraftState.INGREDIENTS;
+ affectedSlots.add(bedrockSlotToJava(((ConsumeStackRequestActionData) action).getSource()));
break;
}
case TAKE:
@@ -533,21 +524,16 @@ public abstract class InventoryTranslator {
}
}
plan.execute(false);
- return acceptRequest(request, makeContainerEntries(session, inventory, plan.getAffectedSlots()));
+ affectedSlots.addAll(plan.getAffectedSlots());
+ return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots));
}
public ItemStackResponsePacket.Response translateAutoCraftingRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
- int gridSize;
- int gridDimensions;
- if (this instanceof PlayerInventoryTranslator) {
- gridSize = 4;
- gridDimensions = 2;
- } else if (this instanceof CraftingInventoryTranslator) {
- gridSize = 9;
- gridDimensions = 3;
- } else {
+ final int gridSize = getGridSize();
+ if (gridSize == -1) {
return rejectRequest(request);
}
+ int gridDimensions = gridSize == 4 ? 2 : 3;
Recipe recipe;
Ingredient[] ingredients = new Ingredient[0];
@@ -733,7 +719,7 @@ public abstract class InventoryTranslator {
/**
* Handled in {@link PlayerInventoryTranslator}
*/
- public ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
+ protected ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
return rejectRequest(request);
}
@@ -768,14 +754,14 @@ public abstract class InventoryTranslator {
}
}
- public static ItemStackResponsePacket.Response acceptRequest(ItemStackRequest request, List containerEntries) {
+ protected static ItemStackResponsePacket.Response acceptRequest(ItemStackRequest request, List containerEntries) {
return new ItemStackResponsePacket.Response(ItemStackResponsePacket.ResponseStatus.OK, request.getRequestId(), containerEntries);
}
/**
* Reject an incorrect ItemStackRequest.
*/
- public static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request) {
+ protected static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request) {
return rejectRequest(request, true);
}
@@ -785,7 +771,7 @@ public abstract class InventoryTranslator {
* @param throwError whether this request was truly erroneous (true), or known as an outcome and should not be treated
* as bad (false).
*/
- public static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request, boolean throwError) {
+ protected static ItemStackResponsePacket.Response rejectRequest(ItemStackRequest request, boolean throwError) {
if (throwError && GeyserImpl.getInstance().getConfig().isDebugMode()) {
new Throwable("DEBUGGING: ItemStackRequest rejected " + request.toString()).printStackTrace();
}
@@ -860,12 +846,15 @@ public abstract class InventoryTranslator {
return -1;
}
- public List makeContainerEntries(GeyserSession session, Inventory inventory, Set affectedSlots) {
+ protected final List makeContainerEntries(GeyserSession session, Inventory inventory, IntSet affectedSlots) {
Map> containerMap = new HashMap<>();
- for (int slot : affectedSlots) {
+ // Manually call iterator to prevent Integer boxing
+ IntIterator it = affectedSlots.iterator();
+ while (it.hasNext()) {
+ int slot = it.nextInt();
BedrockContainerSlot bedrockSlot = javaSlotToBedrockContainer(slot);
- List list = containerMap.computeIfAbsent(bedrockSlot.getContainer(), k -> new ArrayList<>());
- list.add(makeItemEntry(session, bedrockSlot.getSlot(), inventory.getItem(slot)));
+ List list = containerMap.computeIfAbsent(bedrockSlot.container(), k -> new ArrayList<>());
+ list.add(makeItemEntry(session, bedrockSlot.slot(), inventory.getItem(slot)));
}
List containerEntries = new ArrayList<>();
@@ -879,7 +868,7 @@ public abstract class InventoryTranslator {
return containerEntries;
}
- public static ItemStackResponsePacket.ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
+ private static ItemStackResponsePacket.ItemEntry makeItemEntry(GeyserSession session, int bedrockSlot, GeyserItemStack itemStack) {
ItemStackResponsePacket.ItemEntry itemEntry;
if (!itemStack.isEmpty()) {
// As of 1.16.210: Bedrock needs confirmation on what the current item durability is.
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java
index acdaaf4c1..a862a7e0d 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/LoomInventoryTranslator.java
@@ -117,7 +117,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
}
@Override
- public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
+ protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
// If the LOOM_MATERIAL slot is not empty, we are crafting a pattern that does not come from an item
// Remove the CRAFT_NON_IMPLEMENTED_DEPRECATED when 1.17.30 is dropped
return (action.getType() == StackRequestActionType.CRAFT_NON_IMPLEMENTED_DEPRECATED || action.getType() == StackRequestActionType.CRAFT_LOOM)
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
index 04de68a1e..e2349e5a5 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
@@ -35,6 +35,7 @@ import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.*;
import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket;
+import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import org.geysermc.geyser.inventory.*;
@@ -55,6 +56,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
super(46);
}
+ @Override
+ public int getGridSize() {
+ return 4;
+ }
+
@Override
public void updateInventory(GeyserSession session, Inventory inventory) {
updateCraftingGrid(session, inventory);
@@ -370,14 +376,17 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
}
}
}
- for (int slot : affectedSlots) {
+ // Manually call iterator to prevent Integer boxing
+ IntIterator it = affectedSlots.iterator();
+ while (it.hasNext()) {
+ int slot = it.nextInt();
sendCreativeAction(session, inventory, slot);
}
return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots));
}
@Override
- public ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
+ protected ItemStackResponsePacket.Response translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
ItemStack javaCreativeItem = null;
IntSet affectedSlots = new IntOpenHashSet();
CraftState craftState = CraftState.START;
@@ -478,7 +487,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
return rejectRequest(request);
}
}
- for (int slot : affectedSlots) {
+ // Manually call iterator to prevent Integer boxing
+ IntIterator it = affectedSlots.iterator();
+ while (it.hasNext()) {
+ int slot = it.nextInt();
sendCreativeAction(session, inventory, slot);
}
return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots));
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
index 3bc881696..ae25a9ffd 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/StonecutterInventoryTranslator.java
@@ -52,7 +52,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
}
@Override
- public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
+ protected boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
// First is pre-1.18. TODO remove after 1.17.40 support is dropped and refactor stonecutter support to use CraftRecipeStackRequestActionData's recipe ID
return action.getType() == StackRequestActionType.CRAFT_NON_IMPLEMENTED_DEPRECATED || action.getType() == StackRequestActionType.CRAFT_RECIPE;
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/BannerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/BannerTranslator.java
index 3c566e76c..a5c3235a2 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/BannerTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/BannerTranslator.java
@@ -155,7 +155,7 @@ public class BannerTranslator extends ItemTranslator {
}
@Override
- public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
+ protected ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
if (itemStack.getNbt() == null) {
return super.translateToBedrock(itemStack, mapping, mappings);
}
@@ -163,9 +163,7 @@ public class BannerTranslator extends ItemTranslator {
ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings);
CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag");
- if (blockEntityTag != null && blockEntityTag.contains("Patterns")) {
- ListTag patterns = blockEntityTag.get("Patterns");
-
+ if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) {
NbtMapBuilder nbtBuilder = builder.build().getTag().toBuilder(); //TODO fix ugly hack
if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
// Remove the current patterns and set the ominous banner type
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CompassTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CompassTranslator.java
index 65f26542f..9637f1aa9 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CompassTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/CompassTranslator.java
@@ -26,7 +26,9 @@
package org.geysermc.geyser.translator.inventory.item;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
-import com.github.steveice10.opennbt.tag.builtin.*;
+import com.github.steveice10.opennbt.tag.builtin.ByteTag;
+import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
+import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.network.MinecraftProtocol;
import org.geysermc.geyser.registry.Registries;
@@ -51,19 +53,30 @@ public class CompassTranslator extends ItemTranslator {
}
@Override
- public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
- if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, mapping, mappings);
-
- Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked");
- if (lodestoneTag instanceof ByteTag) {
- // Get the fake lodestonecompass entry
- mapping = mappings.getStoredItems().lodestoneCompass();
- // NBT will be translated in nbt/LodestoneCompassTranslator
+ protected ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
+ if (isLodestoneCompass(itemStack.getNbt())) {
+ // NBT will be translated in nbt/LodestoneCompassTranslator if applicable
+ return super.translateToBedrock(itemStack, mappings.getStoredItems().lodestoneCompass(), mappings);
}
-
return super.translateToBedrock(itemStack, mapping, mappings);
}
+ @Override
+ protected ItemMapping getItemMapping(int javaId, CompoundTag nbt, ItemMappings mappings) {
+ if (isLodestoneCompass(nbt)) {
+ return mappings.getStoredItems().lodestoneCompass();
+ }
+ return super.getItemMapping(javaId, nbt, mappings);
+ }
+
+ private boolean isLodestoneCompass(CompoundTag nbt) {
+ if (nbt != null) {
+ Tag lodestoneTag = nbt.get("LodestoneTracked");
+ return lodestoneTag instanceof ByteTag;
+ }
+ return false;
+ }
+
@Override
public ItemStack translateToJava(ItemData itemData, ItemMapping mapping, ItemMappings mappings) {
if (mapping.getBedrockIdentifier().equals("minecraft:lodestone_compass")) {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
index 34e9364ce..c8e492634 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
@@ -37,6 +37,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings;
@@ -157,18 +158,13 @@ public abstract class ItemTranslator {
nbt = translateDisplayProperties(session, nbt, bedrockItem);
if (session.isAdvancedTooltips()) {
- nbt = addAdvancedTooltips(nbt, session.getItemMappings().getMapping(stack), session.locale());
+ nbt = addAdvancedTooltips(nbt, bedrockItem, session.locale());
}
ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt);
- ItemData.Builder builder;
- ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
- if (itemStackTranslator != null) {
- builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem, session.getItemMappings());
- } else {
- builder = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem, session.getItemMappings());
- }
+ ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.getOrDefault(bedrockItem.getJavaId(), DEFAULT_TRANSLATOR);
+ ItemData.Builder builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem, session.getItemMappings());
if (bedrockItem.isBlock()) {
builder.blockRuntimeId(bedrockItem.getBedrockBlockId());
}
@@ -263,6 +259,19 @@ public abstract class ItemTranslator {
return canModifyBedrock;
}
+ /**
+ * Given an item stack, determine the item mapping that should be applied to Bedrock players.
+ */
+ @Nonnull
+ public static ItemMapping getBedrockItemMapping(GeyserSession session, @Nonnull GeyserItemStack itemStack) {
+ if (itemStack.isEmpty()) {
+ return ItemMapping.AIR;
+ }
+ int javaId = itemStack.getJavaId();
+ return ITEM_STACK_TRANSLATORS.getOrDefault(javaId, DEFAULT_TRANSLATOR)
+ .getItemMapping(javaId, itemStack.getNbt(), session.getItemMappings());
+ }
+
private static final ItemTranslator DEFAULT_TRANSLATOR = new ItemTranslator() {
@Override
public List getAppliedItems() {
@@ -270,7 +279,7 @@ public abstract class ItemTranslator {
}
};
- public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
+ protected ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
if (itemStack == null) {
// Return, essentially, air
return ItemData.builder();
@@ -295,6 +304,10 @@ public abstract class ItemTranslator {
public abstract List getAppliedItems();
+ protected ItemMapping getItemMapping(int javaId, CompoundTag nbt, ItemMappings mappings) {
+ return mappings.getMapping(javaId);
+ }
+
public NbtMap translateNbtToBedrock(CompoundTag tag) {
NbtMapBuilder builder = NbtMap.builder();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
@@ -469,9 +482,8 @@ public abstract class ItemTranslator {
public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemMapping mapping, char translationColor) {
boolean hasCustomName = false;
if (tag != null) {
- CompoundTag display = tag.get("display");
- if (display != null && display.contains("Name")) {
- String name = ((StringTag) display.get("Name")).getValue();
+ if (tag.get("display") instanceof CompoundTag display && display.get("Name") instanceof StringTag tagName) {
+ String name = tagName.getValue();
// Get the translated name and prefix it with a reset char
name = MessageTranslator.convertMessageLenient(name, session.locale());
@@ -491,8 +503,10 @@ public abstract class ItemTranslator {
if (tag == null) {
tag = new CompoundTag("");
}
- CompoundTag display = tag.get("display");
- if (display == null) {
+ CompoundTag display;
+ if (tag.get("display") instanceof CompoundTag oldDisplay) {
+ display = oldDisplay;
+ } else {
display = new CompoundTag("display");
// Add to the new root tag
tag.put(display);
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/PotionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/PotionTranslator.java
index 272092da6..54a6deadb 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/PotionTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/PotionTranslator.java
@@ -54,7 +54,7 @@ public class PotionTranslator extends ItemTranslator {
}
@Override
- public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
+ protected ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, mapping, mappings);
Tag potionTag = itemStack.getNbt().get("Potion");
if (potionTag instanceof StringTag) {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/TippedArrowTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/TippedArrowTranslator.java
index 4925d3e69..35e8baa07 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/TippedArrowTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/TippedArrowTranslator.java
@@ -59,7 +59,7 @@ public class TippedArrowTranslator extends ItemTranslator {
}
@Override
- public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
+ protected ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
if (!mapping.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) {
// We're only concerned about minecraft:arrow when translating Bedrock -> Java
return super.translateToBedrock(itemStack, mapping, mappings);
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
index d50a8c579..72ef0cf0a 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
@@ -51,13 +51,11 @@ public class BasicItemTranslator extends NbtItemStackTranslator {
}
}
- CompoundTag displayTag = itemTag.get("display");
- if (displayTag == null) {
+ if (!(itemTag.get("display") instanceof CompoundTag displayTag)) {
return;
}
- Tag loreTag = displayTag.get("Lore");
- if (loreTag instanceof ListTag listTag) {
+ if (displayTag.get("Lore") instanceof ListTag listTag) {
List lore = new ArrayList<>();
for (Tag tag : listTag.getValue()) {
if (!(tag instanceof StringTag)) continue;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java
index 93ce71a3d..d00914fb1 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockBlockEntityDataTranslator.java
@@ -41,12 +41,14 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator SignUtils.JAVA_CHARACTER_WIDTH_MAX) {
@@ -111,7 +113,7 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator {
+ Vector3i blockPos = BlockUtils.getBlockPosition(packet.getBlockPosition(), packet.getBlockFace());
+
+ if (session.getGeyser().getConfig().isDisableBedrockScaffolding()) {
+ float yaw = session.getPlayerEntity().getYaw();
+ boolean isGodBridging = switch (packet.getBlockFace()) {
+ case 2 -> yaw <= -135f || yaw > 135f;
+ case 3 -> yaw <= 45f && yaw > -45f;
+ case 4 -> yaw > 45f && yaw <= 135f;
+ case 5 -> yaw <= -45f && yaw > -135f;
+ default -> false;
+ };
+ if (isGodBridging) {
+ restoreCorrectBlock(session, blockPos, packet);
+ return;
+ }
+ }
+
// Check to make sure the client isn't spamming interaction
// Based on Nukkit 1.0, with changes to ensure holding down still works
boolean hasAlreadyClicked = System.currentTimeMillis() - session.getLastInteractionTime() < 110.0 &&
@@ -138,7 +163,6 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator {
- if (packet.getActions().size() == 1 && packet.getLegacySlots().size() > 0) {
- InventoryActionData actionData = packet.getActions().get(0);
- LegacySetItemSlotData slotData = packet.getLegacySlots().get(0);
- if (slotData.getContainerId() == 6 && actionData.getToItem().getId() != 0) {
- // The player is trying to swap out an armor piece that already has an item in it
- // Java Edition does not allow this; let's revert it
- session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory());
- }
- }
-
// Handled when sneaking
if (session.getPlayerInventory().getItemInHand().getJavaId() == mappings.getStoredItems().shield().getJavaId()) {
break;
@@ -282,6 +296,43 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator legacySlots = packet.getLegacySlots();
+ if (packet.getActions().size() == 1 && legacySlots.size() > 0) {
+ InventoryActionData actionData = packet.getActions().get(0);
+ LegacySetItemSlotData slotData = legacySlots.get(0);
+ if (slotData.getContainerId() == 6 && actionData.getToItem().getId() != 0) {
+ // The player is trying to swap out an armor piece that already has an item in it
+ if (session.getGeyser().getConfig().isAlwaysQuickChangeArmor()) {
+ // Java doesn't know when a player is in its own inventory and not, so we
+ // can abuse this feature to send a swap inventory packet
+ int bedrockHotbarSlot = packet.getHotbarSlot();
+ Click click = InventoryUtils.getClickForHotbarSwap(bedrockHotbarSlot);
+ if (click != null && slotData.getSlots().length != 0) {
+ Inventory playerInventory = session.getPlayerInventory();
+ // Bedrock sends us the index of the slot in the armor container; armor in Java
+ // Edition is offset by 5 in the player inventory
+ int armorSlot = slotData.getSlots()[0] + 5;
+ GeyserItemStack armorSlotItem = playerInventory.getItem(armorSlot);
+ GeyserItemStack hotbarItem = playerInventory.getItem(playerInventory.getOffsetForHotbar(bedrockHotbarSlot));
+ playerInventory.setItem(armorSlot, hotbarItem, session);
+ playerInventory.setItem(bedrockHotbarSlot, armorSlotItem, session);
+
+ Int2ObjectMap changedSlots = new Int2ObjectOpenHashMap<>(2);
+ changedSlots.put(armorSlot, hotbarItem.getItemStack());
+ changedSlots.put(bedrockHotbarSlot, armorSlotItem.getItemStack());
+
+ ServerboundContainerClickPacket clickPacket = new ServerboundContainerClickPacket(
+ playerInventory.getId(), playerInventory.getStateId(), armorSlot,
+ click.actionType, click.action, null, changedSlots);
+ session.sendDownstreamPacket(clickPacket);
+ }
+ } else {
+ // Disallowed; let's revert
+ session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory());
+ }
+ }
+ }
}
case 2 -> {
int blockState = session.getGameMode() == GameMode.CREATIVE ?
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java
index a6551afbd..f3d0ff344 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java
@@ -58,14 +58,14 @@ public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTran
// Build the NBT data for the update
NbtMapBuilder builder = NbtMap.builder();
- builder.putInt("dim", DimensionUtils.javaToBedrock(pos.getDimension()));
+ builder.putInt("dim", DimensionUtils.javaToBedrock(pos.dimension()));
builder.putString("id", "0x" + String.format("%08X", packet.getTrackingId()));
builder.putByte("version", (byte) 1); // Not sure what this is for
builder.putByte("status", (byte) 0); // Not sure what this is for
// Build the position for the update
- builder.putList("pos", NbtType.INT, pos.getX(), pos.getY(), pos.getZ());
+ builder.putList("pos", NbtType.INT, pos.x(), pos.y(), pos.z());
broadcastPacket.setTag(builder.build());
session.sendUpstreamPacket(broadcastPacket);
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java
new file mode 100644
index 000000000..0a27f7b64
--- /dev/null
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRequestChunkRadiusTranslator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019-2022 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.translator.protocol.bedrock;
+
+import com.nukkitx.protocol.bedrock.packet.RequestChunkRadiusPacket;
+import org.geysermc.geyser.session.GeyserSession;
+import org.geysermc.geyser.translator.protocol.PacketTranslator;
+import org.geysermc.geyser.translator.protocol.Translator;
+
+/**
+ * Sent when the client updates its desired render distance.
+ */
+@Translator(packet = RequestChunkRadiusPacket.class)
+public class BedrockRequestChunkRadiusTranslator extends PacketTranslator {
+
+ @Override
+ public void translate(GeyserSession session, RequestChunkRadiusPacket packet) {
+ session.setClientRenderDistance(packet.getRadius());
+
+ if (session.isLoggedIn()) {
+ session.sendJavaClientSettings();
+ }
+ }
+}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java
index 77b7143b2..1631ea4c7 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockRespawnTranslator.java
@@ -27,10 +27,7 @@ package org.geysermc.geyser.translator.protocol.bedrock;
import com.github.steveice10.mc.protocol.data.game.ClientCommand;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
-import com.nukkitx.math.vector.Vector3f;
-import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
-import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@@ -41,28 +38,6 @@ public class BedrockRespawnTranslator extends PacketTranslator {
@Override
public void translate(GeyserSession session, RespawnPacket packet) {
if (packet.getState() == RespawnPacket.State.CLIENT_READY) {
- // Previously we only sent the respawn packet before the server finished loading
- // The message included was 'Otherwise when immediate respawn is on the client never loads'
- // But I assume the new if statement below fixes that problem
- RespawnPacket respawnPacket = new RespawnPacket();
- respawnPacket.setRuntimeEntityId(0);
- respawnPacket.setPosition(Vector3f.ZERO);
- respawnPacket.setState(RespawnPacket.State.SERVER_READY);
- session.sendUpstreamPacket(respawnPacket);
-
- if (session.isSpawned()) {
- // Client might be stuck; resend spawn information
- PlayerEntity entity = session.getPlayerEntity();
- entity.updateBedrockMetadata(); // TODO test?
-
- MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
- movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
- movePlayerPacket.setPosition(entity.getPosition());
- movePlayerPacket.setRotation(entity.getBedrockRotation());
- movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN);
- session.sendUpstreamPacket(movePlayerPacket);
- }
-
ServerboundClientCommandPacket javaRespawnPacket = new ServerboundClientCommandPacket(ClientCommand.RESPAWN);
session.sendDownstreamPacket(javaRespawnPacket);
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java
index 035a2afe2..1a6771cc5 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockTextTranslator.java
@@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.protocol.bedrock;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.session.GeyserSession;
+import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.text.MessageTranslator;
@@ -44,6 +45,18 @@ public class BedrockTextTranslator extends PacketTranslator {
return;
}
+ if (message.indexOf(ChatColor.ESCAPE) != -1) {
+ // Filter out all escape characters - Java doesn't let you type these
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < message.length(); i++) {
+ char c = message.charAt(i);
+ if (c != ChatColor.ESCAPE) {
+ builder.append(c);
+ }
+ }
+ message = builder.toString();
+ }
+
if (MessageTranslator.isTooLong(message, session)) {
return;
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java
index 08a913b77..14dc37e5d 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java
@@ -25,31 +25,25 @@
package org.geysermc.geyser.translator.protocol.java;
-import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference;
-import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility;
-import com.github.steveice10.mc.protocol.data.game.setting.SkinPart;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
-import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket;
import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
-import com.nukkitx.protocol.bedrock.packet.*;
-import org.geysermc.geyser.session.auth.AuthType;
+import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
+import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
+import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
+import org.geysermc.geyser.session.auth.AuthType;
+import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
-import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.geyser.util.ChunkUtils;
import org.geysermc.geyser.util.DimensionUtils;
import org.geysermc.geyser.util.PluginMessageUtils;
-import java.util.Arrays;
-import java.util.List;
-
@Translator(packet = ClientboundLoginPacket.class)
public class JavaLoginTranslator extends PacketTranslator {
- private static final List SKIN_PART_VALUES = Arrays.asList(SkinPart.values());
@Override
public void translate(GeyserSession session, ClientboundLoginPacket packet) {
@@ -99,13 +93,10 @@ public class JavaLoginTranslator extends PacketTranslator= Bedrock_v486.V486_CODEC.getProtocolVersion();
+
Int2ObjectMap recipeMap = new Int2ObjectOpenHashMap<>(Registries.RECIPES.forVersion(session.getUpstream().getProtocolVersion()));
Int2ObjectMap> unsortedStonecutterData = new Int2ObjectOpenHashMap<>();
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
@@ -128,6 +132,27 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator {
+ // Required to translate these as of 1.18.10, or else they cannot be crafted
+ if (!applySmithingRecipes) {
+ continue;
+ }
+
+ SmithingRecipeData recipeData = (SmithingRecipeData) recipe.getData();
+ ItemData output = ItemTranslator.translateToBedrock(session, recipeData.getResult());
+ for (ItemStack base : recipeData.getBase().getOptions()) {
+ ItemData bedrockBase = ItemTranslator.translateToBedrock(session, base);
+
+ for (ItemStack addition : recipeData.getAddition().getOptions()) {
+ ItemData bedrockAddition = ItemTranslator.translateToBedrock(session, addition);
+
+ UUID uuid = UUID.randomUUID();
+ craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
+ Arrays.asList(bedrockBase, bedrockAddition),
+ Collections.singletonList(output), uuid, "smithing_table", 2, netId++));
+ }
+ }
+ }
default -> {
List craftingData = recipeTypes.get(recipe.getType());
if (craftingData != null) {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java
index f34f7bd17..de4a2c22b 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaEntityEventTranslator.java
@@ -245,8 +245,8 @@ public class JavaEntityEventTranslator extends PacketTranslator {
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java
index e2fe1103f..97487ea6a 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java
@@ -86,13 +86,14 @@ public class JavaPlayerPositionTranslator extends PacketTranslator inventorySize) {
+ GeyserImpl geyser = session.getGeyser();
+ geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.name()
+ + " that exceeds inventory size!");
+ if (geyser.getConfig().isDebugMode()) {
+ geyser.getLogger().debug(packet);
+ geyser.getLogger().debug(inventory);
+ }
+ InventoryTranslator translator = session.getInventoryTranslator();
+ if (translator != null) {
+ translator.updateInventory(session, inventory);
+ }
+ // 1.18.1 behavior: the previous items will be correctly set, but the state ID and carried item will not
+ // as this produces a stack trace on the client.
+ // If Java processes this correctly in the future, we can revert this behavior
+ return;
+ }
+
GeyserItemStack newItem = GeyserItemStack.from(packet.getItems()[i]);
inventory.setItem(i, newItem, session);
}
@@ -55,6 +73,10 @@ public class JavaContainerSetContentTranslator extends PacketTranslator 0 || stateId != inventory.getStateId());
+ inventory.setStateId(stateId);
+
session.getPlayerInventory().setCursor(GeyserItemStack.from(packet.getCarriedItem()), session);
InventoryUtils.updateCursor(session);
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
index 283d95fc4..4bb2a8e60 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
@@ -30,7 +30,6 @@ import com.github.steveice10.mc.protocol.data.game.recipe.Ingredient;
import com.github.steveice10.mc.protocol.data.game.recipe.Recipe;
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData;
-import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
@@ -40,17 +39,15 @@ import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.translator.protocol.PacketTranslator;
-import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
-import org.geysermc.geyser.translator.inventory.CraftingInventoryTranslator;
import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
+import org.geysermc.geyser.translator.protocol.PacketTranslator;
+import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.util.InventoryUtils;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -72,14 +69,16 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator 0 || stateId != inventory.getStateId());
+ inventory.setStateId(stateId);
InventoryTranslator translator = session.getInventoryTranslator();
if (translator != null) {
if (session.getCraftingGridFuture() != null) {
session.getCraftingGridFuture().cancel(false);
}
- session.setCraftingGridFuture(session.scheduleInEventLoop(() -> updateCraftingGrid(session, packet, inventory, translator), 150, TimeUnit.MILLISECONDS));
+ updateCraftingGrid(session, packet.getSlot(), packet.getItem(), inventory, translator);
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
if (packet.getContainerId() == 0 && !(translator instanceof PlayerInventoryTranslator)) {
@@ -93,21 +92,23 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator {
int offset = gridSize == 4 ? 28 : 32;
int gridDimensions = gridSize == 4 ? 2 : 3;
int firstRow = -1, height = -1;
@@ -135,62 +136,10 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator 0 ? packet.getVillagerLevel() - 1 : 0); // -1 crashes client
- recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice()));
- if (trade.getSecondInput() != null) {
- recipe.put("buyB", getItemTag(session, trade.getSecondInput(), 0));
- }
+ recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice(), trade.getDemand(), trade.getPriceMultiplier()));
+ recipe.put("buyB", getItemTag(session, trade.getSecondInput()));
recipe.putInt("uses", trade.getNumUses());
recipe.putByte("rewardExp", (byte) 1);
tags.add(recipe.build());
@@ -144,12 +146,31 @@ public class JavaMerchantOffersTranslator extends PacketTranslator effectPacket.setType(LevelEventType.PARTICLE_EYE_OF_ENDER_DEATH);
case MOB_SPAWN -> effectPacket.setType(LevelEventType.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java
case BONEMEAL_GROW_WITH_SOUND, BONEMEAL_GROW -> {
- effectPacket.setType((particleEvent == ParticleEvent.BONEMEAL_GROW
- && session.getUpstream().getProtocolVersion() >= Bedrock_v465.V465_CODEC.getProtocolVersion()) ? LevelEventType.PARTICLE_TURTLE_EGG : LevelEventType.PARTICLE_CROP_GROWTH);
+ effectPacket.setType(particleEvent == ParticleEvent.BONEMEAL_GROW ? LevelEventType.PARTICLE_TURTLE_EGG : LevelEventType.PARTICLE_CROP_GROWTH);
BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData();
effectPacket.setData(growEventData.getParticleCount());
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java
index 8fee27250..3a0a77cc0 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/level/JavaSetChunkCacheRadiusTranslator.java
@@ -35,6 +35,6 @@ public class JavaSetChunkCacheRadiusTranslator extends PacketTranslator Click.SWAP_TO_HOTBAR_1;
+ case 1 -> Click.SWAP_TO_HOTBAR_2;
+ case 2 -> Click.SWAP_TO_HOTBAR_3;
+ case 3 -> Click.SWAP_TO_HOTBAR_4;
+ case 4 -> Click.SWAP_TO_HOTBAR_5;
+ case 5 -> Click.SWAP_TO_HOTBAR_6;
+ case 6 -> Click.SWAP_TO_HOTBAR_7;
+ case 7 -> Click.SWAP_TO_HOTBAR_8;
+ case 8 -> Click.SWAP_TO_HOTBAR_9;
+ default -> null;
+ };
+ }
+
+ /**
+ * Test all known recipes to find a valid match
+ *
+ * @param output if not null, the recipe has to output this item
+ */
+ @Nullable
+ public static Recipe getValidRecipe(final GeyserSession session, final @Nullable ItemStack output, final IntFunction inventoryGetter,
+ final int gridDimensions, final int firstRow, final int height, final int firstCol, final int width) {
+ int nonAirCount = 0; // Used for shapeless recipes for amount of items needed in recipe
+ for (int row = firstRow; row < height + firstRow; row++) {
+ for (int col = firstCol; col < width + firstCol; col++) {
+ if (!inventoryGetter.apply(col + (row * gridDimensions) + 1).isEmpty()) {
+ nonAirCount++;
+ }
+ }
+ }
+
+ recipes:
+ for (Recipe recipe : session.getCraftingRecipes().values()) {
+ if (recipe.getType() == RecipeType.CRAFTING_SHAPED) {
+ ShapedRecipeData data = (ShapedRecipeData) recipe.getData();
+ if (output != null && !data.getResult().equals(output)) {
+ continue;
+ }
+ Ingredient[] ingredients = data.getIngredients();
+ if (data.getWidth() != width || data.getHeight() != height || width * height != ingredients.length) {
+ continue;
+ }
+
+ if (!testShapedRecipe(ingredients, inventoryGetter, gridDimensions, firstRow, height, firstCol, width)) {
+ Ingredient[] mirroredIngredients = new Ingredient[ingredients.length];
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ mirroredIngredients[col + (row * width)] = ingredients[(width - 1 - col) + (row * width)];
+ }
+ }
+
+ if (Arrays.equals(ingredients, mirroredIngredients) ||
+ !testShapedRecipe(mirroredIngredients, inventoryGetter, gridDimensions, firstRow, height, firstCol, width)) {
+ continue;
+ }
+ }
+ return recipe;
+ } else if (recipe.getType() == RecipeType.CRAFTING_SHAPELESS) {
+ ShapelessRecipeData data = (ShapelessRecipeData) recipe.getData();
+ if (output != null && !data.getResult().equals(output)) {
+ continue;
+ }
+ if (nonAirCount != data.getIngredients().length) {
+ // There is an amount of items on the crafting table that is not the same as the ingredient count so this is invalid
+ continue;
+ }
+ for (int i = 0; i < data.getIngredients().length; i++) {
+ Ingredient ingredient = data.getIngredients()[i];
+ for (ItemStack itemStack : ingredient.getOptions()) {
+ boolean inventoryHasItem = false;
+ // Iterate only over the crafting table to find this item
+ crafting:
+ for (int row = firstRow; row < height + firstRow; row++) {
+ for (int col = firstCol; col < width + firstCol; col++) {
+ GeyserItemStack geyserItemStack = inventoryGetter.apply(col + (row * gridDimensions) + 1);
+ if (geyserItemStack.isEmpty()) {
+ inventoryHasItem = itemStack == null || itemStack.getId() == 0;
+ if (inventoryHasItem) {
+ break crafting;
+ }
+ } else if (itemStack.equals(geyserItemStack.getItemStack(1))) {
+ inventoryHasItem = true;
+ break crafting;
+ }
+ }
+ }
+ if (!inventoryHasItem) {
+ continue recipes;
+ }
+ }
+ }
+ return recipe;
+ }
+ }
+ return null;
+ }
+
+ private static boolean testShapedRecipe(final Ingredient[] ingredients, final IntFunction inventoryGetter,
+ final int gridDimensions, final int firstRow, final int height, final int firstCol, final int width) {
+ int ingredientIndex = 0;
+ for (int row = firstRow; row < height + firstRow; row++) {
+ for (int col = firstCol; col < width + firstCol; col++) {
+ GeyserItemStack geyserItemStack = inventoryGetter.apply(col + (row * gridDimensions) + 1);
+ Ingredient ingredient = ingredients[ingredientIndex++];
+ if (ingredient.getOptions().length == 0) {
+ if (!geyserItemStack.isEmpty()) {
+ return false;
+ }
+ } else {
+ boolean inventoryHasItem = false;
+ for (ItemStack item : ingredient.getOptions()) {
+ if (Objects.equals(geyserItemStack.getItemStack(1), item)) {
+ inventoryHasItem = true;
+ break;
+ }
+ }
+ if (!inventoryHasItem) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
}
diff --git a/core/src/main/resources/bedrock/block_palette.1_17_30.nbt b/core/src/main/resources/bedrock/block_palette.1_17_30.nbt
deleted file mode 100644
index fde145ca5..000000000
Binary files a/core/src/main/resources/bedrock/block_palette.1_17_30.nbt and /dev/null differ
diff --git a/core/src/main/resources/bedrock/block_palette.1_18_10.nbt b/core/src/main/resources/bedrock/block_palette.1_18_10.nbt
new file mode 100644
index 000000000..637bfc952
Binary files /dev/null and b/core/src/main/resources/bedrock/block_palette.1_18_10.nbt differ
diff --git a/core/src/main/resources/bedrock/creative_items.1_17_30.json b/core/src/main/resources/bedrock/creative_items.1_18_10.json
similarity index 91%
rename from core/src/main/resources/bedrock/creative_items.1_17_30.json
rename to core/src/main/resources/bedrock/creative_items.1_18_10.json
index bb73854dc..dadabf91f 100644
--- a/core/src/main/resources/bedrock/creative_items.1_17_30.json
+++ b/core/src/main/resources/bedrock/creative_items.1_18_10.json
@@ -2,39 +2,35 @@
"items" : [
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5794
+ "blockRuntimeId" : 5800
},
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5795
+ "blockRuntimeId" : 5801
},
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5796
+ "blockRuntimeId" : 5802
},
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5797
+ "blockRuntimeId" : 5803
},
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5798
+ "blockRuntimeId" : 5804
},
{
"id" : "minecraft:planks",
- "blockRuntimeId" : 5799
+ "blockRuntimeId" : 5805
},
{
"id" : "minecraft:crimson_planks",
- "blockRuntimeId" : 3839
+ "blockRuntimeId" : 3840
},
{
"id" : "minecraft:warped_planks",
- "blockRuntimeId" : 7594
- },
- {
- "id" : "minecraft:cobblestone_wall",
- "blockRuntimeId" : 1318
+ "blockRuntimeId" : 7596
},
{
"id" : "minecraft:cobblestone_wall",
@@ -56,69 +52,69 @@
"id" : "minecraft:cobblestone_wall",
"blockRuntimeId" : 1323
},
- {
- "id" : "minecraft:cobblestone_wall",
- "blockRuntimeId" : 1330
- },
- {
- "id" : "minecraft:cobblestone_wall",
- "blockRuntimeId" : 1325
- },
- {
- "id" : "minecraft:cobblestone_wall",
- "blockRuntimeId" : 1326
- },
{
"id" : "minecraft:cobblestone_wall",
"blockRuntimeId" : 1324
},
- {
- "id" : "minecraft:cobblestone_wall",
- "blockRuntimeId" : 1327
- },
{
"id" : "minecraft:cobblestone_wall",
"blockRuntimeId" : 1331
},
+ {
+ "id" : "minecraft:cobblestone_wall",
+ "blockRuntimeId" : 1326
+ },
+ {
+ "id" : "minecraft:cobblestone_wall",
+ "blockRuntimeId" : 1327
+ },
+ {
+ "id" : "minecraft:cobblestone_wall",
+ "blockRuntimeId" : 1325
+ },
{
"id" : "minecraft:cobblestone_wall",
"blockRuntimeId" : 1328
},
+ {
+ "id" : "minecraft:cobblestone_wall",
+ "blockRuntimeId" : 1332
+ },
{
"id" : "minecraft:cobblestone_wall",
"blockRuntimeId" : 1329
},
+ {
+ "id" : "minecraft:cobblestone_wall",
+ "blockRuntimeId" : 1330
+ },
{
"id" : "minecraft:blackstone_wall",
"blockRuntimeId" : 507
},
{
"id" : "minecraft:polished_blackstone_wall",
- "blockRuntimeId" : 6038
+ "blockRuntimeId" : 6044
},
{
"id" : "minecraft:polished_blackstone_brick_wall",
- "blockRuntimeId" : 5835
+ "blockRuntimeId" : 5841
},
{
"id" : "minecraft:cobbled_deepslate_wall",
- "blockRuntimeId" : 1155
+ "blockRuntimeId" : 1156
},
{
"id" : "minecraft:deepslate_tile_wall",
- "blockRuntimeId" : 4297
+ "blockRuntimeId" : 4298
},
{
"id" : "minecraft:polished_deepslate_wall",
- "blockRuntimeId" : 6213
+ "blockRuntimeId" : 6219
},
{
"id" : "minecraft:deepslate_brick_wall",
- "blockRuntimeId" : 4114
- },
- {
- "id" : "minecraft:fence",
- "blockRuntimeId" : 4773
+ "blockRuntimeId" : 4115
},
{
"id" : "minecraft:fence",
@@ -141,24 +137,28 @@
"blockRuntimeId" : 4778
},
{
- "id" : "minecraft:nether_brick_fence",
- "blockRuntimeId" : 5686
- },
- {
- "id" : "minecraft:crimson_fence",
- "blockRuntimeId" : 3817
- },
- {
- "id" : "minecraft:warped_fence",
- "blockRuntimeId" : 7572
- },
- {
- "id" : "minecraft:fence_gate",
+ "id" : "minecraft:fence",
"blockRuntimeId" : 4779
},
+ {
+ "id" : "minecraft:nether_brick_fence",
+ "blockRuntimeId" : 5690
+ },
+ {
+ "id" : "minecraft:crimson_fence",
+ "blockRuntimeId" : 3818
+ },
+ {
+ "id" : "minecraft:warped_fence",
+ "blockRuntimeId" : 7574
+ },
+ {
+ "id" : "minecraft:fence_gate",
+ "blockRuntimeId" : 4780
+ },
{
"id" : "minecraft:spruce_fence_gate",
- "blockRuntimeId" : 7006
+ "blockRuntimeId" : 7007
},
{
"id" : "minecraft:birch_fence_gate",
@@ -166,7 +166,7 @@
},
{
"id" : "minecraft:jungle_fence_gate",
- "blockRuntimeId" : 5252
+ "blockRuntimeId" : 5254
},
{
"id" : "minecraft:acacia_fence_gate",
@@ -174,35 +174,35 @@
},
{
"id" : "minecraft:dark_oak_fence_gate",
- "blockRuntimeId" : 3980
+ "blockRuntimeId" : 3981
},
{
"id" : "minecraft:crimson_fence_gate",
- "blockRuntimeId" : 3818
+ "blockRuntimeId" : 3819
},
{
"id" : "minecraft:warped_fence_gate",
- "blockRuntimeId" : 7573
+ "blockRuntimeId" : 7575
},
{
"id" : "minecraft:normal_stone_stairs",
- "blockRuntimeId" : 5705
+ "blockRuntimeId" : 5709
},
{
"id" : "minecraft:stone_stairs",
- "blockRuntimeId" : 7277
+ "blockRuntimeId" : 7278
},
{
"id" : "minecraft:mossy_cobblestone_stairs",
- "blockRuntimeId" : 5667
+ "blockRuntimeId" : 5669
},
{
"id" : "minecraft:oak_stairs",
- "blockRuntimeId" : 5714
+ "blockRuntimeId" : 5718
},
{
"id" : "minecraft:spruce_stairs",
- "blockRuntimeId" : 7038
+ "blockRuntimeId" : 7039
},
{
"id" : "minecraft:birch_stairs",
@@ -210,7 +210,7 @@
},
{
"id" : "minecraft:jungle_stairs",
- "blockRuntimeId" : 5284
+ "blockRuntimeId" : 5286
},
{
"id" : "minecraft:acacia_stairs",
@@ -218,47 +218,47 @@
},
{
"id" : "minecraft:dark_oak_stairs",
- "blockRuntimeId" : 4012
+ "blockRuntimeId" : 4013
},
{
"id" : "minecraft:stone_brick_stairs",
- "blockRuntimeId" : 7183
+ "blockRuntimeId" : 7184
},
{
"id" : "minecraft:mossy_stone_brick_stairs",
- "blockRuntimeId" : 5675
+ "blockRuntimeId" : 5677
},
{
"id" : "minecraft:sandstone_stairs",
- "blockRuntimeId" : 6707
+ "blockRuntimeId" : 6713
},
{
"id" : "minecraft:smooth_sandstone_stairs",
- "blockRuntimeId" : 6899
+ "blockRuntimeId" : 6900
},
{
"id" : "minecraft:red_sandstone_stairs",
- "blockRuntimeId" : 6634
+ "blockRuntimeId" : 6640
},
{
"id" : "minecraft:smooth_red_sandstone_stairs",
- "blockRuntimeId" : 6891
+ "blockRuntimeId" : 6892
},
{
"id" : "minecraft:granite_stairs",
- "blockRuntimeId" : 4988
+ "blockRuntimeId" : 4990
},
{
"id" : "minecraft:polished_granite_stairs",
- "blockRuntimeId" : 6383
+ "blockRuntimeId" : 6389
},
{
"id" : "minecraft:diorite_stairs",
- "blockRuntimeId" : 4475
+ "blockRuntimeId" : 4476
},
{
"id" : "minecraft:polished_diorite_stairs",
- "blockRuntimeId" : 6375
+ "blockRuntimeId" : 6381
},
{
"id" : "minecraft:andesite_stairs",
@@ -266,7 +266,7 @@
},
{
"id" : "minecraft:polished_andesite_stairs",
- "blockRuntimeId" : 5811
+ "blockRuntimeId" : 5817
},
{
"id" : "minecraft:brick_stairs",
@@ -274,47 +274,47 @@
},
{
"id" : "minecraft:nether_brick_stairs",
- "blockRuntimeId" : 5687
+ "blockRuntimeId" : 5691
},
{
"id" : "minecraft:red_nether_brick_stairs",
- "blockRuntimeId" : 6622
+ "blockRuntimeId" : 6628
},
{
"id" : "minecraft:end_brick_stairs",
- "blockRuntimeId" : 4719
+ "blockRuntimeId" : 4720
},
{
"id" : "minecraft:quartz_stairs",
- "blockRuntimeId" : 6556
+ "blockRuntimeId" : 6562
},
{
"id" : "minecraft:smooth_quartz_stairs",
- "blockRuntimeId" : 6883
+ "blockRuntimeId" : 6884
},
{
"id" : "minecraft:purpur_stairs",
- "blockRuntimeId" : 6534
+ "blockRuntimeId" : 6540
},
{
"id" : "minecraft:prismarine_stairs",
- "blockRuntimeId" : 6446
+ "blockRuntimeId" : 6452
},
{
"id" : "minecraft:dark_prismarine_stairs",
- "blockRuntimeId" : 4036
+ "blockRuntimeId" : 4037
},
{
"id" : "minecraft:prismarine_bricks_stairs",
- "blockRuntimeId" : 6438
+ "blockRuntimeId" : 6444
},
{
"id" : "minecraft:crimson_stairs",
- "blockRuntimeId" : 3859
+ "blockRuntimeId" : 3860
},
{
"id" : "minecraft:warped_stairs",
- "blockRuntimeId" : 7614
+ "blockRuntimeId" : 7616
},
{
"id" : "minecraft:blackstone_stairs",
@@ -322,59 +322,59 @@
},
{
"id" : "minecraft:polished_blackstone_stairs",
- "blockRuntimeId" : 6030
+ "blockRuntimeId" : 6036
},
{
"id" : "minecraft:polished_blackstone_brick_stairs",
- "blockRuntimeId" : 5827
+ "blockRuntimeId" : 5833
},
{
"id" : "minecraft:cut_copper_stairs",
- "blockRuntimeId" : 3912
+ "blockRuntimeId" : 3913
},
{
"id" : "minecraft:exposed_cut_copper_stairs",
- "blockRuntimeId" : 4755
+ "blockRuntimeId" : 4756
},
{
"id" : "minecraft:weathered_cut_copper_stairs",
- "blockRuntimeId" : 7741
+ "blockRuntimeId" : 7743
},
{
"id" : "minecraft:oxidized_cut_copper_stairs",
- "blockRuntimeId" : 5755
+ "blockRuntimeId" : 5760
},
{
"id" : "minecraft:waxed_cut_copper_stairs",
- "blockRuntimeId" : 7685
+ "blockRuntimeId" : 7687
},
{
"id" : "minecraft:waxed_exposed_cut_copper_stairs",
- "blockRuntimeId" : 7699
+ "blockRuntimeId" : 7701
},
{
"id" : "minecraft:waxed_weathered_cut_copper_stairs",
- "blockRuntimeId" : 7727
+ "blockRuntimeId" : 7729
},
{
"id" : "minecraft:waxed_oxidized_cut_copper_stairs",
- "blockRuntimeId" : 7713
+ "blockRuntimeId" : 7715
},
{
"id" : "minecraft:cobbled_deepslate_stairs",
- "blockRuntimeId" : 1147
+ "blockRuntimeId" : 1148
},
{
"id" : "minecraft:deepslate_tile_stairs",
- "blockRuntimeId" : 4289
+ "blockRuntimeId" : 4290
},
{
"id" : "minecraft:polished_deepslate_stairs",
- "blockRuntimeId" : 6205
+ "blockRuntimeId" : 6211
},
{
"id" : "minecraft:deepslate_brick_stairs",
- "blockRuntimeId" : 4106
+ "blockRuntimeId" : 4107
},
{
"id" : "minecraft:wooden_door"
@@ -405,11 +405,11 @@
},
{
"id" : "minecraft:trapdoor",
- "blockRuntimeId" : 7359
+ "blockRuntimeId" : 7360
},
{
"id" : "minecraft:spruce_trapdoor",
- "blockRuntimeId" : 7062
+ "blockRuntimeId" : 7063
},
{
"id" : "minecraft:birch_trapdoor",
@@ -417,7 +417,7 @@
},
{
"id" : "minecraft:jungle_trapdoor",
- "blockRuntimeId" : 5308
+ "blockRuntimeId" : 5310
},
{
"id" : "minecraft:acacia_trapdoor",
@@ -425,51 +425,27 @@
},
{
"id" : "minecraft:dark_oak_trapdoor",
- "blockRuntimeId" : 4020
+ "blockRuntimeId" : 4021
},
{
"id" : "minecraft:iron_trapdoor",
- "blockRuntimeId" : 5167
+ "blockRuntimeId" : 5169
},
{
"id" : "minecraft:crimson_trapdoor",
- "blockRuntimeId" : 3886
+ "blockRuntimeId" : 3887
},
{
"id" : "minecraft:warped_trapdoor",
- "blockRuntimeId" : 7641
+ "blockRuntimeId" : 7643
},
{
"id" : "minecraft:iron_bars",
- "blockRuntimeId" : 5132
+ "blockRuntimeId" : 5134
},
{
"id" : "minecraft:glass",
- "blockRuntimeId" : 4882
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7084
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7092
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7091
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7099
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7096
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7098
+ "blockRuntimeId" : 4884
},
{
"id" : "minecraft:stained_glass",
@@ -477,11 +453,15 @@
},
{
"id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7088
+ "blockRuntimeId" : 7093
},
{
"id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7089
+ "blockRuntimeId" : 7092
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7100
},
{
"id" : "minecraft:stained_glass",
@@ -489,59 +469,55 @@
},
{
"id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7093
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7087
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7095
- },
- {
- "id" : "minecraft:stained_glass",
- "blockRuntimeId" : 7094
+ "blockRuntimeId" : 7099
},
{
"id" : "minecraft:stained_glass",
"blockRuntimeId" : 7086
},
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7089
+ },
{
"id" : "minecraft:stained_glass",
"blockRuntimeId" : 7090
},
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7098
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7094
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7088
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7096
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7095
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7087
+ },
+ {
+ "id" : "minecraft:stained_glass",
+ "blockRuntimeId" : 7091
+ },
{
"id" : "minecraft:tinted_glass",
- "blockRuntimeId" : 7348
+ "blockRuntimeId" : 7349
},
{
"id" : "minecraft:glass_pane",
- "blockRuntimeId" : 4883
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7100
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7108
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7107
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7115
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7112
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7114
+ "blockRuntimeId" : 4885
},
{
"id" : "minecraft:stained_glass_pane",
@@ -549,11 +525,15 @@
},
{
"id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7104
+ "blockRuntimeId" : 7109
},
{
"id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7105
+ "blockRuntimeId" : 7108
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7116
},
{
"id" : "minecraft:stained_glass_pane",
@@ -561,59 +541,71 @@
},
{
"id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7109
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7103
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7111
- },
- {
- "id" : "minecraft:stained_glass_pane",
- "blockRuntimeId" : 7110
+ "blockRuntimeId" : 7115
},
{
"id" : "minecraft:stained_glass_pane",
"blockRuntimeId" : 7102
},
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7105
+ },
{
"id" : "minecraft:stained_glass_pane",
"blockRuntimeId" : 7106
},
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7114
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7110
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7104
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7112
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7111
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7103
+ },
+ {
+ "id" : "minecraft:stained_glass_pane",
+ "blockRuntimeId" : 7107
+ },
{
"id" : "minecraft:ladder",
- "blockRuntimeId" : 5356
+ "blockRuntimeId" : 5358
},
{
"id" : "minecraft:scaffolding",
- "blockRuntimeId" : 6727
+ "blockRuntimeId" : 6733
},
{
"id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7219
+ "blockRuntimeId" : 7220
},
{
"id" : "minecraft:double_stone_slab4",
- "blockRuntimeId" : 7269
+ "blockRuntimeId" : 7270
},
{
"id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7222
+ "blockRuntimeId" : 7223
},
{
"id" : "minecraft:double_stone_slab2",
- "blockRuntimeId" : 7240
- },
- {
- "id" : "minecraft:wooden_slab",
- "blockRuntimeId" : 7899
- },
- {
- "id" : "minecraft:wooden_slab",
- "blockRuntimeId" : 7900
+ "blockRuntimeId" : 7241
},
{
"id" : "minecraft:wooden_slab",
@@ -632,76 +624,12 @@
"blockRuntimeId" : 7904
},
{
- "id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7224
+ "id" : "minecraft:wooden_slab",
+ "blockRuntimeId" : 7905
},
{
- "id" : "minecraft:double_stone_slab4",
- "blockRuntimeId" : 7267
- },
- {
- "id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7220
- },
- {
- "id" : "minecraft:double_stone_slab4",
- "blockRuntimeId" : 7270
- },
- {
- "id" : "minecraft:double_stone_slab2",
- "blockRuntimeId" : 7241
- },
- {
- "id" : "minecraft:double_stone_slab2",
- "blockRuntimeId" : 7235
- },
- {
- "id" : "minecraft:double_stone_slab4",
- "blockRuntimeId" : 7271
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7252
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7257
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7258
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7255
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7256
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7254
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7253
- },
- {
- "id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7223
- },
- {
- "id" : "minecraft:double_stone_slab",
- "blockRuntimeId" : 7226
- },
- {
- "id" : "minecraft:double_stone_slab2",
- "blockRuntimeId" : 7242
- },
- {
- "id" : "minecraft:double_stone_slab3",
- "blockRuntimeId" : 7251
+ "id" : "minecraft:wooden_slab",
+ "blockRuntimeId" : 7906
},
{
"id" : "minecraft:double_stone_slab",
@@ -711,10 +639,78 @@
"id" : "minecraft:double_stone_slab4",
"blockRuntimeId" : 7268
},
+ {
+ "id" : "minecraft:double_stone_slab",
+ "blockRuntimeId" : 7221
+ },
+ {
+ "id" : "minecraft:double_stone_slab4",
+ "blockRuntimeId" : 7271
+ },
+ {
+ "id" : "minecraft:double_stone_slab2",
+ "blockRuntimeId" : 7242
+ },
{
"id" : "minecraft:double_stone_slab2",
"blockRuntimeId" : 7236
},
+ {
+ "id" : "minecraft:double_stone_slab4",
+ "blockRuntimeId" : 7272
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7253
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7258
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7259
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7256
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7257
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7255
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7254
+ },
+ {
+ "id" : "minecraft:double_stone_slab",
+ "blockRuntimeId" : 7224
+ },
+ {
+ "id" : "minecraft:double_stone_slab",
+ "blockRuntimeId" : 7227
+ },
+ {
+ "id" : "minecraft:double_stone_slab2",
+ "blockRuntimeId" : 7243
+ },
+ {
+ "id" : "minecraft:double_stone_slab3",
+ "blockRuntimeId" : 7252
+ },
+ {
+ "id" : "minecraft:double_stone_slab",
+ "blockRuntimeId" : 7226
+ },
+ {
+ "id" : "minecraft:double_stone_slab4",
+ "blockRuntimeId" : 7269
+ },
{
"id" : "minecraft:double_stone_slab2",
"blockRuntimeId" : 7237
@@ -727,13 +723,17 @@
"id" : "minecraft:double_stone_slab2",
"blockRuntimeId" : 7239
},
+ {
+ "id" : "minecraft:double_stone_slab2",
+ "blockRuntimeId" : 7240
+ },
{
"id" : "minecraft:crimson_slab",
- "blockRuntimeId" : 3857
+ "blockRuntimeId" : 3858
},
{
"id" : "minecraft:warped_slab",
- "blockRuntimeId" : 7612
+ "blockRuntimeId" : 7614
},
{
"id" : "minecraft:blackstone_slab",
@@ -741,59 +741,59 @@
},
{
"id" : "minecraft:polished_blackstone_slab",
- "blockRuntimeId" : 6028
+ "blockRuntimeId" : 6034
},
{
"id" : "minecraft:polished_blackstone_brick_slab",
- "blockRuntimeId" : 5825
+ "blockRuntimeId" : 5831
},
{
"id" : "minecraft:cut_copper_slab",
- "blockRuntimeId" : 3910
+ "blockRuntimeId" : 3911
},
{
"id" : "minecraft:exposed_cut_copper_slab",
- "blockRuntimeId" : 4753
+ "blockRuntimeId" : 4754
},
{
"id" : "minecraft:weathered_cut_copper_slab",
- "blockRuntimeId" : 7739
+ "blockRuntimeId" : 7741
},
{
"id" : "minecraft:oxidized_cut_copper_slab",
- "blockRuntimeId" : 5753
+ "blockRuntimeId" : 5758
},
{
"id" : "minecraft:waxed_cut_copper_slab",
- "blockRuntimeId" : 7683
+ "blockRuntimeId" : 7685
},
{
"id" : "minecraft:waxed_exposed_cut_copper_slab",
- "blockRuntimeId" : 7697
+ "blockRuntimeId" : 7699
},
{
"id" : "minecraft:waxed_weathered_cut_copper_slab",
- "blockRuntimeId" : 7725
+ "blockRuntimeId" : 7727
},
{
"id" : "minecraft:waxed_oxidized_cut_copper_slab",
- "blockRuntimeId" : 7711
+ "blockRuntimeId" : 7713
},
{
"id" : "minecraft:cobbled_deepslate_slab",
- "blockRuntimeId" : 1145
+ "blockRuntimeId" : 1146
},
{
"id" : "minecraft:polished_deepslate_slab",
- "blockRuntimeId" : 6203
+ "blockRuntimeId" : 6209
},
{
"id" : "minecraft:deepslate_tile_slab",
- "blockRuntimeId" : 4287
+ "blockRuntimeId" : 4288
},
{
"id" : "minecraft:deepslate_brick_slab",
- "blockRuntimeId" : 4104
+ "blockRuntimeId" : 4105
},
{
"id" : "minecraft:brick_block",
@@ -805,15 +805,11 @@
},
{
"id" : "minecraft:cracked_nether_bricks",
- "blockRuntimeId" : 3768
+ "blockRuntimeId" : 3769
},
{
"id" : "minecraft:quartz_bricks",
- "blockRuntimeId" : 6554
- },
- {
- "id" : "minecraft:stonebrick",
- "blockRuntimeId" : 7285
+ "blockRuntimeId" : 6560
},
{
"id" : "minecraft:stonebrick",
@@ -827,25 +823,29 @@
"id" : "minecraft:stonebrick",
"blockRuntimeId" : 7288
},
+ {
+ "id" : "minecraft:stonebrick",
+ "blockRuntimeId" : 7289
+ },
{
"id" : "minecraft:end_bricks",
- "blockRuntimeId" : 4727
+ "blockRuntimeId" : 4728
},
{
"id" : "minecraft:prismarine",
- "blockRuntimeId" : 6437
+ "blockRuntimeId" : 6443
},
{
"id" : "minecraft:polished_blackstone_bricks",
- "blockRuntimeId" : 5997
+ "blockRuntimeId" : 6003
},
{
"id" : "minecraft:cracked_polished_blackstone_bricks",
- "blockRuntimeId" : 3769
+ "blockRuntimeId" : 3770
},
{
"id" : "minecraft:gilded_blackstone",
- "blockRuntimeId" : 4881
+ "blockRuntimeId" : 4883
},
{
"id" : "minecraft:chiseled_polished_blackstone",
@@ -853,19 +853,19 @@
},
{
"id" : "minecraft:deepslate_tiles",
- "blockRuntimeId" : 4459
+ "blockRuntimeId" : 4460
},
{
"id" : "minecraft:cracked_deepslate_tiles",
- "blockRuntimeId" : 3767
+ "blockRuntimeId" : 3768
},
{
"id" : "minecraft:deepslate_bricks",
- "blockRuntimeId" : 4276
+ "blockRuntimeId" : 4277
},
{
"id" : "minecraft:cracked_deepslate_bricks",
- "blockRuntimeId" : 3766
+ "blockRuntimeId" : 3767
},
{
"id" : "minecraft:chiseled_deepslate",
@@ -873,195 +873,195 @@
},
{
"id" : "minecraft:cobblestone",
- "blockRuntimeId" : 1317
+ "blockRuntimeId" : 1318
},
{
"id" : "minecraft:mossy_cobblestone",
- "blockRuntimeId" : 5666
+ "blockRuntimeId" : 5668
},
{
"id" : "minecraft:cobbled_deepslate",
- "blockRuntimeId" : 1142
+ "blockRuntimeId" : 1143
},
{
"id" : "minecraft:smooth_stone",
- "blockRuntimeId" : 6907
+ "blockRuntimeId" : 6908
},
{
"id" : "minecraft:sandstone",
- "blockRuntimeId" : 6703
+ "blockRuntimeId" : 6709
},
{
"id" : "minecraft:sandstone",
- "blockRuntimeId" : 6704
+ "blockRuntimeId" : 6710
},
{
"id" : "minecraft:sandstone",
- "blockRuntimeId" : 6705
+ "blockRuntimeId" : 6711
},
{
"id" : "minecraft:sandstone",
- "blockRuntimeId" : 6706
+ "blockRuntimeId" : 6712
},
{
"id" : "minecraft:red_sandstone",
- "blockRuntimeId" : 6630
+ "blockRuntimeId" : 6636
},
{
"id" : "minecraft:red_sandstone",
- "blockRuntimeId" : 6631
+ "blockRuntimeId" : 6637
},
{
"id" : "minecraft:red_sandstone",
- "blockRuntimeId" : 6632
+ "blockRuntimeId" : 6638
},
{
"id" : "minecraft:red_sandstone",
- "blockRuntimeId" : 6633
+ "blockRuntimeId" : 6639
},
{
"id" : "minecraft:coal_block",
- "blockRuntimeId" : 1140
+ "blockRuntimeId" : 1141
},
{
"id" : "minecraft:dried_kelp_block",
- "blockRuntimeId" : 4583
+ "blockRuntimeId" : 4584
},
{
"id" : "minecraft:gold_block",
- "blockRuntimeId" : 4974
+ "blockRuntimeId" : 4976
},
{
"id" : "minecraft:iron_block",
- "blockRuntimeId" : 5133
+ "blockRuntimeId" : 5135
},
{
"id" : "minecraft:copper_block",
- "blockRuntimeId" : 3676
+ "blockRuntimeId" : 3677
},
{
"id" : "minecraft:exposed_copper",
- "blockRuntimeId" : 4751
- },
- {
- "id" : "minecraft:weathered_copper",
- "blockRuntimeId" : 7737
- },
- {
- "id" : "minecraft:oxidized_copper",
- "blockRuntimeId" : 5751
- },
- {
- "id" : "minecraft:waxed_copper",
- "blockRuntimeId" : 7681
- },
- {
- "id" : "minecraft:waxed_exposed_copper",
- "blockRuntimeId" : 7695
- },
- {
- "id" : "minecraft:waxed_weathered_copper",
- "blockRuntimeId" : 7723
- },
- {
- "id" : "minecraft:waxed_oxidized_copper",
- "blockRuntimeId" : 7709
- },
- {
- "id" : "minecraft:cut_copper",
- "blockRuntimeId" : 3909
- },
- {
- "id" : "minecraft:exposed_cut_copper",
"blockRuntimeId" : 4752
},
+ {
+ "id" : "minecraft:weathered_copper",
+ "blockRuntimeId" : 7739
+ },
+ {
+ "id" : "minecraft:oxidized_copper",
+ "blockRuntimeId" : 5756
+ },
+ {
+ "id" : "minecraft:waxed_copper",
+ "blockRuntimeId" : 7683
+ },
+ {
+ "id" : "minecraft:waxed_exposed_copper",
+ "blockRuntimeId" : 7697
+ },
+ {
+ "id" : "minecraft:waxed_weathered_copper",
+ "blockRuntimeId" : 7725
+ },
+ {
+ "id" : "minecraft:waxed_oxidized_copper",
+ "blockRuntimeId" : 7711
+ },
+ {
+ "id" : "minecraft:cut_copper",
+ "blockRuntimeId" : 3910
+ },
+ {
+ "id" : "minecraft:exposed_cut_copper",
+ "blockRuntimeId" : 4753
+ },
{
"id" : "minecraft:weathered_cut_copper",
- "blockRuntimeId" : 7738
+ "blockRuntimeId" : 7740
},
{
"id" : "minecraft:oxidized_cut_copper",
- "blockRuntimeId" : 5752
+ "blockRuntimeId" : 5757
},
{
"id" : "minecraft:waxed_cut_copper",
- "blockRuntimeId" : 7682
+ "blockRuntimeId" : 7684
},
{
"id" : "minecraft:waxed_exposed_cut_copper",
- "blockRuntimeId" : 7696
+ "blockRuntimeId" : 7698
},
{
"id" : "minecraft:waxed_weathered_cut_copper",
- "blockRuntimeId" : 7724
+ "blockRuntimeId" : 7726
},
{
"id" : "minecraft:waxed_oxidized_cut_copper",
- "blockRuntimeId" : 7710
+ "blockRuntimeId" : 7712
},
{
"id" : "minecraft:emerald_block",
- "blockRuntimeId" : 4716
+ "blockRuntimeId" : 4717
},
{
"id" : "minecraft:diamond_block",
- "blockRuntimeId" : 4473
+ "blockRuntimeId" : 4474
},
{
"id" : "minecraft:lapis_block",
- "blockRuntimeId" : 5364
+ "blockRuntimeId" : 5366
},
{
"id" : "minecraft:raw_iron_block",
- "blockRuntimeId" : 6576
+ "blockRuntimeId" : 6582
},
{
"id" : "minecraft:raw_copper_block",
- "blockRuntimeId" : 6574
+ "blockRuntimeId" : 6580
},
{
"id" : "minecraft:raw_gold_block",
- "blockRuntimeId" : 6575
+ "blockRuntimeId" : 6581
},
{
"id" : "minecraft:quartz_block",
- "blockRuntimeId" : 6542
+ "blockRuntimeId" : 6548
},
{
"id" : "minecraft:quartz_block",
- "blockRuntimeId" : 6544
+ "blockRuntimeId" : 6550
},
{
"id" : "minecraft:quartz_block",
- "blockRuntimeId" : 6543
+ "blockRuntimeId" : 6549
},
{
"id" : "minecraft:quartz_block",
- "blockRuntimeId" : 6545
+ "blockRuntimeId" : 6551
},
{
"id" : "minecraft:prismarine",
- "blockRuntimeId" : 6435
+ "blockRuntimeId" : 6441
},
{
"id" : "minecraft:prismarine",
- "blockRuntimeId" : 6436
+ "blockRuntimeId" : 6442
},
{
"id" : "minecraft:slime",
- "blockRuntimeId" : 6860
+ "blockRuntimeId" : 6861
},
{
"id" : "minecraft:honey_block",
- "blockRuntimeId" : 5111
+ "blockRuntimeId" : 5113
},
{
"id" : "minecraft:honeycomb_block",
- "blockRuntimeId" : 5112
+ "blockRuntimeId" : 5114
},
{
"id" : "minecraft:hay_block",
- "blockRuntimeId" : 5083
+ "blockRuntimeId" : 5085
},
{
"id" : "minecraft:bone_block",
@@ -1069,27 +1069,51 @@
},
{
"id" : "minecraft:nether_brick",
- "blockRuntimeId" : 5685
+ "blockRuntimeId" : 5689
},
{
"id" : "minecraft:red_nether_brick",
- "blockRuntimeId" : 6621
+ "blockRuntimeId" : 6627
},
{
"id" : "minecraft:netherite_block",
- "blockRuntimeId" : 5702
+ "blockRuntimeId" : 5706
},
{
"id" : "minecraft:lodestone",
- "blockRuntimeId" : 5562
+ "blockRuntimeId" : 5564
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7911
+ "blockRuntimeId" : 7913
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7919
+ "blockRuntimeId" : 7921
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7920
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7928
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7925
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7927
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7914
+ },
+ {
+ "id" : "minecraft:wool",
+ "blockRuntimeId" : 7917
},
{
"id" : "minecraft:wool",
@@ -1101,19 +1125,7 @@
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7923
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7925
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7912
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7915
+ "blockRuntimeId" : 7922
},
{
"id" : "minecraft:wool",
@@ -1125,27 +1137,15 @@
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7920
+ "blockRuntimeId" : 7923
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7914
+ "blockRuntimeId" : 7915
},
{
"id" : "minecraft:wool",
- "blockRuntimeId" : 7922
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7921
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7913
- },
- {
- "id" : "minecraft:wool",
- "blockRuntimeId" : 7917
+ "blockRuntimeId" : 7919
},
{
"id" : "minecraft:carpet",
@@ -1211,93 +1211,69 @@
"id" : "minecraft:carpet",
"blockRuntimeId" : 969
},
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3659
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3667
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3666
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3674
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3671
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3673
- },
{
"id" : "minecraft:concrete_powder",
"blockRuntimeId" : 3660
},
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3663
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3664
- },
- {
- "id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3672
- },
{
"id" : "minecraft:concrete_powder",
"blockRuntimeId" : 3668
},
{
"id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3662
+ "blockRuntimeId" : 3667
},
{
"id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3670
+ "blockRuntimeId" : 3675
},
{
"id" : "minecraft:concrete_powder",
- "blockRuntimeId" : 3669
+ "blockRuntimeId" : 3672
+ },
+ {
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3674
},
{
"id" : "minecraft:concrete_powder",
"blockRuntimeId" : 3661
},
+ {
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3664
+ },
{
"id" : "minecraft:concrete_powder",
"blockRuntimeId" : 3665
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3643
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3673
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3651
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3669
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3650
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3663
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3658
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3671
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3655
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3670
},
{
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3657
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3662
+ },
+ {
+ "id" : "minecraft:concrete_powder",
+ "blockRuntimeId" : 3666
},
{
"id" : "minecraft:concrete",
@@ -1305,11 +1281,15 @@
},
{
"id" : "minecraft:concrete",
- "blockRuntimeId" : 3647
+ "blockRuntimeId" : 3652
},
{
"id" : "minecraft:concrete",
- "blockRuntimeId" : 3648
+ "blockRuntimeId" : 3651
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3659
},
{
"id" : "minecraft:concrete",
@@ -1317,59 +1297,55 @@
},
{
"id" : "minecraft:concrete",
- "blockRuntimeId" : 3652
- },
- {
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3646
- },
- {
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3654
- },
- {
- "id" : "minecraft:concrete",
- "blockRuntimeId" : 3653
+ "blockRuntimeId" : 3658
},
{
"id" : "minecraft:concrete",
"blockRuntimeId" : 3645
},
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3648
+ },
{
"id" : "minecraft:concrete",
"blockRuntimeId" : 3649
},
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3657
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3653
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3647
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3655
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3654
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3646
+ },
+ {
+ "id" : "minecraft:concrete",
+ "blockRuntimeId" : 3650
+ },
{
"id" : "minecraft:clay",
"blockRuntimeId" : 1139
},
{
"id" : "minecraft:hardened_clay",
- "blockRuntimeId" : 5082
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7116
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7124
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7123
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7131
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7128
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7130
+ "blockRuntimeId" : 5084
},
{
"id" : "minecraft:stained_hardened_clay",
@@ -1377,11 +1353,15 @@
},
{
"id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7120
+ "blockRuntimeId" : 7125
},
{
"id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7121
+ "blockRuntimeId" : 7124
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7132
},
{
"id" : "minecraft:stained_hardened_clay",
@@ -1389,39 +1369,59 @@
},
{
"id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7125
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7119
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7127
- },
- {
- "id" : "minecraft:stained_hardened_clay",
- "blockRuntimeId" : 7126
+ "blockRuntimeId" : 7131
},
{
"id" : "minecraft:stained_hardened_clay",
"blockRuntimeId" : 7118
},
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7121
+ },
{
"id" : "minecraft:stained_hardened_clay",
"blockRuntimeId" : 7122
},
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7130
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7126
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7120
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7128
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7127
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7119
+ },
+ {
+ "id" : "minecraft:stained_hardened_clay",
+ "blockRuntimeId" : 7123
+ },
{
"id" : "minecraft:white_glazed_terracotta",
- "blockRuntimeId" : 7796
+ "blockRuntimeId" : 7798
},
{
"id" : "minecraft:silver_glazed_terracotta",
- "blockRuntimeId" : 6842
+ "blockRuntimeId" : 6849
},
{
"id" : "minecraft:gray_glazed_terracotta",
- "blockRuntimeId" : 5009
+ "blockRuntimeId" : 5011
},
{
"id" : "minecraft:black_glazed_terracotta",
@@ -1433,31 +1433,31 @@
},
{
"id" : "minecraft:red_glazed_terracotta",
- "blockRuntimeId" : 6598
+ "blockRuntimeId" : 6604
},
{
"id" : "minecraft:orange_glazed_terracotta",
- "blockRuntimeId" : 5745
+ "blockRuntimeId" : 5750
},
{
"id" : "minecraft:yellow_glazed_terracotta",
- "blockRuntimeId" : 7938
+ "blockRuntimeId" : 7940
},
{
"id" : "minecraft:lime_glazed_terracotta",
- "blockRuntimeId" : 5531
+ "blockRuntimeId" : 5533
},
{
"id" : "minecraft:green_glazed_terracotta",
- "blockRuntimeId" : 5025
+ "blockRuntimeId" : 5027
},
{
"id" : "minecraft:cyan_glazed_terracotta",
- "blockRuntimeId" : 3930
+ "blockRuntimeId" : 3931
},
{
"id" : "minecraft:light_blue_glazed_terracotta",
- "blockRuntimeId" : 5483
+ "blockRuntimeId" : 5485
},
{
"id" : "minecraft:blue_glazed_terracotta",
@@ -1465,43 +1465,43 @@
},
{
"id" : "minecraft:purple_glazed_terracotta",
- "blockRuntimeId" : 6516
- },
- {
- "id" : "minecraft:magenta_glazed_terracotta",
- "blockRuntimeId" : 5595
- },
- {
- "id" : "minecraft:pink_glazed_terracotta",
- "blockRuntimeId" : 5776
- },
- {
- "id" : "minecraft:purpur_block",
"blockRuntimeId" : 6522
},
+ {
+ "id" : "minecraft:magenta_glazed_terracotta",
+ "blockRuntimeId" : 5597
+ },
+ {
+ "id" : "minecraft:pink_glazed_terracotta",
+ "blockRuntimeId" : 5782
+ },
{
"id" : "minecraft:purpur_block",
- "blockRuntimeId" : 6524
+ "blockRuntimeId" : 6528
+ },
+ {
+ "id" : "minecraft:purpur_block",
+ "blockRuntimeId" : 6530
},
{
"id" : "minecraft:nether_wart_block",
- "blockRuntimeId" : 5701
+ "blockRuntimeId" : 5705
},
{
"id" : "minecraft:warped_wart_block",
- "blockRuntimeId" : 7663
+ "blockRuntimeId" : 7665
},
{
"id" : "minecraft:shroomlight",
- "blockRuntimeId" : 6825
+ "blockRuntimeId" : 6832
},
{
"id" : "minecraft:crimson_nylium",
- "blockRuntimeId" : 3838
+ "blockRuntimeId" : 3839
},
{
"id" : "minecraft:warped_nylium",
- "blockRuntimeId" : 7593
+ "blockRuntimeId" : 7595
},
{
"id" : "minecraft:basalt",
@@ -1509,87 +1509,87 @@
},
{
"id" : "minecraft:polished_basalt",
- "blockRuntimeId" : 5819
+ "blockRuntimeId" : 5825
},
{
"id" : "minecraft:smooth_basalt",
- "blockRuntimeId" : 6882
+ "blockRuntimeId" : 6883
},
{
"id" : "minecraft:soul_soil",
- "blockRuntimeId" : 6952
- },
- {
- "id" : "minecraft:dirt",
- "blockRuntimeId" : 4483
+ "blockRuntimeId" : 6953
},
{
"id" : "minecraft:dirt",
"blockRuntimeId" : 4484
},
+ {
+ "id" : "minecraft:dirt",
+ "blockRuntimeId" : 4485
+ },
{
"id" : "minecraft:farmland",
- "blockRuntimeId" : 4765
+ "blockRuntimeId" : 4766
},
{
"id" : "minecraft:grass",
- "blockRuntimeId" : 4996
+ "blockRuntimeId" : 4998
},
{
"id" : "minecraft:grass_path",
- "blockRuntimeId" : 4997
+ "blockRuntimeId" : 4999
},
{
"id" : "minecraft:podzol",
- "blockRuntimeId" : 5800
+ "blockRuntimeId" : 5806
},
{
"id" : "minecraft:mycelium",
- "blockRuntimeId" : 5684
+ "blockRuntimeId" : 5686
},
{
"id" : "minecraft:stone",
- "blockRuntimeId" : 7176
+ "blockRuntimeId" : 7177
},
{
"id" : "minecraft:iron_ore",
- "blockRuntimeId" : 5166
+ "blockRuntimeId" : 5168
},
{
"id" : "minecraft:gold_ore",
- "blockRuntimeId" : 4975
+ "blockRuntimeId" : 4977
},
{
"id" : "minecraft:diamond_ore",
- "blockRuntimeId" : 4474
+ "blockRuntimeId" : 4475
},
{
"id" : "minecraft:lapis_ore",
- "blockRuntimeId" : 5365
+ "blockRuntimeId" : 5367
},
{
"id" : "minecraft:redstone_ore",
- "blockRuntimeId" : 6644
+ "blockRuntimeId" : 6650
},
{
"id" : "minecraft:coal_ore",
- "blockRuntimeId" : 1141
+ "blockRuntimeId" : 1142
},
{
"id" : "minecraft:copper_ore",
- "blockRuntimeId" : 3677
+ "blockRuntimeId" : 3678
},
{
"id" : "minecraft:emerald_ore",
- "blockRuntimeId" : 4717
+ "blockRuntimeId" : 4718
},
{
"id" : "minecraft:quartz_ore",
- "blockRuntimeId" : 6555
+ "blockRuntimeId" : 6561
},
{
"id" : "minecraft:nether_gold_ore",
- "blockRuntimeId" : 5695
+ "blockRuntimeId" : 5699
},
{
"id" : "minecraft:ancient_debris",
@@ -1597,59 +1597,39 @@
},
{
"id" : "minecraft:deepslate_iron_ore",
- "blockRuntimeId" : 4282
- },
- {
- "id" : "minecraft:deepslate_gold_ore",
- "blockRuntimeId" : 4281
- },
- {
- "id" : "minecraft:deepslate_diamond_ore",
- "blockRuntimeId" : 4279
- },
- {
- "id" : "minecraft:deepslate_lapis_ore",
"blockRuntimeId" : 4283
},
{
- "id" : "minecraft:deepslate_redstone_ore",
- "blockRuntimeId" : 4284
+ "id" : "minecraft:deepslate_gold_ore",
+ "blockRuntimeId" : 4282
},
{
- "id" : "minecraft:deepslate_emerald_ore",
+ "id" : "minecraft:deepslate_diamond_ore",
"blockRuntimeId" : 4280
},
{
- "id" : "minecraft:deepslate_coal_ore",
- "blockRuntimeId" : 4277
+ "id" : "minecraft:deepslate_lapis_ore",
+ "blockRuntimeId" : 4284
},
{
- "id" : "minecraft:deepslate_copper_ore",
+ "id" : "minecraft:deepslate_redstone_ore",
+ "blockRuntimeId" : 4285
+ },
+ {
+ "id" : "minecraft:deepslate_emerald_ore",
+ "blockRuntimeId" : 4281
+ },
+ {
+ "id" : "minecraft:deepslate_coal_ore",
"blockRuntimeId" : 4278
},
+ {
+ "id" : "minecraft:deepslate_copper_ore",
+ "blockRuntimeId" : 4279
+ },
{
"id" : "minecraft:gravel",
- "blockRuntimeId" : 4998
- },
- {
- "id" : "minecraft:stone",
- "blockRuntimeId" : 7177
- },
- {
- "id" : "minecraft:stone",
- "blockRuntimeId" : 7179
- },
- {
- "id" : "minecraft:stone",
- "blockRuntimeId" : 7181
- },
- {
- "id" : "minecraft:blackstone",
- "blockRuntimeId" : 494
- },
- {
- "id" : "minecraft:deepslate",
- "blockRuntimeId" : 4099
+ "blockRuntimeId" : 5000
},
{
"id" : "minecraft:stone",
@@ -1663,105 +1643,109 @@
"id" : "minecraft:stone",
"blockRuntimeId" : 7182
},
+ {
+ "id" : "minecraft:blackstone",
+ "blockRuntimeId" : 494
+ },
+ {
+ "id" : "minecraft:deepslate",
+ "blockRuntimeId" : 4100
+ },
+ {
+ "id" : "minecraft:stone",
+ "blockRuntimeId" : 7179
+ },
+ {
+ "id" : "minecraft:stone",
+ "blockRuntimeId" : 7181
+ },
+ {
+ "id" : "minecraft:stone",
+ "blockRuntimeId" : 7183
+ },
{
"id" : "minecraft:polished_blackstone",
- "blockRuntimeId" : 5822
+ "blockRuntimeId" : 5828
},
{
"id" : "minecraft:polished_deepslate",
- "blockRuntimeId" : 6200
+ "blockRuntimeId" : 6206
},
{
"id" : "minecraft:sand",
- "blockRuntimeId" : 6701
+ "blockRuntimeId" : 6707
},
{
"id" : "minecraft:sand",
- "blockRuntimeId" : 6702
+ "blockRuntimeId" : 6708
},
{
"id" : "minecraft:cactus",
"blockRuntimeId" : 920
},
- {
- "id" : "minecraft:log",
- "blockRuntimeId" : 5563
- },
- {
- "id" : "minecraft:stripped_oak_log",
- "blockRuntimeId" : 7315
- },
- {
- "id" : "minecraft:log",
- "blockRuntimeId" : 5564
- },
- {
- "id" : "minecraft:stripped_spruce_log",
- "blockRuntimeId" : 7318
- },
{
"id" : "minecraft:log",
"blockRuntimeId" : 5565
},
{
- "id" : "minecraft:stripped_birch_log",
- "blockRuntimeId" : 7300
+ "id" : "minecraft:stripped_oak_log",
+ "blockRuntimeId" : 7316
},
{
"id" : "minecraft:log",
"blockRuntimeId" : 5566
},
+ {
+ "id" : "minecraft:stripped_spruce_log",
+ "blockRuntimeId" : 7319
+ },
+ {
+ "id" : "minecraft:log",
+ "blockRuntimeId" : 5567
+ },
+ {
+ "id" : "minecraft:stripped_birch_log",
+ "blockRuntimeId" : 7301
+ },
+ {
+ "id" : "minecraft:log",
+ "blockRuntimeId" : 5568
+ },
{
"id" : "minecraft:stripped_jungle_log",
- "blockRuntimeId" : 7312
+ "blockRuntimeId" : 7313
},
{
"id" : "minecraft:log2",
- "blockRuntimeId" : 5575
+ "blockRuntimeId" : 5577
},
{
"id" : "minecraft:stripped_acacia_log",
- "blockRuntimeId" : 7297
+ "blockRuntimeId" : 7298
},
{
"id" : "minecraft:log2",
- "blockRuntimeId" : 5576
+ "blockRuntimeId" : 5578
},
{
"id" : "minecraft:stripped_dark_oak_log",
- "blockRuntimeId" : 7309
+ "blockRuntimeId" : 7310
},
{
"id" : "minecraft:crimson_stem",
- "blockRuntimeId" : 3883
+ "blockRuntimeId" : 3884
},
{
"id" : "minecraft:stripped_crimson_stem",
- "blockRuntimeId" : 7306
+ "blockRuntimeId" : 7307
},
{
"id" : "minecraft:warped_stem",
- "blockRuntimeId" : 7638
+ "blockRuntimeId" : 7640
},
{
"id" : "minecraft:stripped_warped_stem",
- "blockRuntimeId" : 7324
- },
- {
- "id" : "minecraft:wood",
- "blockRuntimeId" : 7803
- },
- {
- "id" : "minecraft:wood",
- "blockRuntimeId" : 7809
- },
- {
- "id" : "minecraft:wood",
- "blockRuntimeId" : 7804
- },
- {
- "id" : "minecraft:wood",
- "blockRuntimeId" : 7810
+ "blockRuntimeId" : 7325
},
{
"id" : "minecraft:wood",
@@ -1795,29 +1779,37 @@
"id" : "minecraft:wood",
"blockRuntimeId" : 7814
},
+ {
+ "id" : "minecraft:wood",
+ "blockRuntimeId" : 7809
+ },
+ {
+ "id" : "minecraft:wood",
+ "blockRuntimeId" : 7815
+ },
+ {
+ "id" : "minecraft:wood",
+ "blockRuntimeId" : 7810
+ },
+ {
+ "id" : "minecraft:wood",
+ "blockRuntimeId" : 7816
+ },
{
"id" : "minecraft:crimson_hyphae",
- "blockRuntimeId" : 3835
+ "blockRuntimeId" : 3836
},
{
"id" : "minecraft:stripped_crimson_hyphae",
- "blockRuntimeId" : 7303
+ "blockRuntimeId" : 7304
},
{
"id" : "minecraft:warped_hyphae",
- "blockRuntimeId" : 7590
+ "blockRuntimeId" : 7592
},
{
"id" : "minecraft:stripped_warped_hyphae",
- "blockRuntimeId" : 7321
- },
- {
- "id" : "minecraft:leaves",
- "blockRuntimeId" : 5409
- },
- {
- "id" : "minecraft:leaves",
- "blockRuntimeId" : 5410
+ "blockRuntimeId" : 7322
},
{
"id" : "minecraft:leaves",
@@ -1828,12 +1820,20 @@
"blockRuntimeId" : 5412
},
{
- "id" : "minecraft:leaves2",
- "blockRuntimeId" : 5425
+ "id" : "minecraft:leaves",
+ "blockRuntimeId" : 5413
+ },
+ {
+ "id" : "minecraft:leaves",
+ "blockRuntimeId" : 5414
},
{
"id" : "minecraft:leaves2",
- "blockRuntimeId" : 5426
+ "blockRuntimeId" : 5427
+ },
+ {
+ "id" : "minecraft:leaves2",
+ "blockRuntimeId" : 5428
},
{
"id" : "minecraft:azalea_leaves",
@@ -1845,27 +1845,27 @@
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6715
+ "blockRuntimeId" : 6721
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6716
+ "blockRuntimeId" : 6722
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6717
+ "blockRuntimeId" : 6723
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6718
+ "blockRuntimeId" : 6724
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6719
+ "blockRuntimeId" : 6725
},
{
"id" : "minecraft:sapling",
- "blockRuntimeId" : 6720
+ "blockRuntimeId" : 6726
},
{
"id" : "minecraft:bee_nest",
@@ -1912,7 +1912,7 @@
},
{
"id" : "minecraft:melon_block",
- "blockRuntimeId" : 5608
+ "blockRuntimeId" : 5610
},
{
"id" : "minecraft:melon_slice"
@@ -1928,7 +1928,7 @@
},
{
"id" : "minecraft:pumpkin",
- "blockRuntimeId" : 6454
+ "blockRuntimeId" : 6460
},
{
"id" : "minecraft:carved_pumpkin",
@@ -1936,11 +1936,19 @@
},
{
"id" : "minecraft:lit_pumpkin",
- "blockRuntimeId" : 5550
+ "blockRuntimeId" : 5552
},
{
"id" : "minecraft:honeycomb"
},
+ {
+ "id" : "minecraft:tallgrass",
+ "blockRuntimeId" : 7346
+ },
+ {
+ "id" : "minecraft:double_plant",
+ "blockRuntimeId" : 4504
+ },
{
"id" : "minecraft:tallgrass",
"blockRuntimeId" : 7345
@@ -1949,17 +1957,17 @@
"id" : "minecraft:double_plant",
"blockRuntimeId" : 4503
},
- {
- "id" : "minecraft:tallgrass",
- "blockRuntimeId" : 7344
- },
- {
- "id" : "minecraft:double_plant",
- "blockRuntimeId" : 4502
- },
{
"id" : "minecraft:nether_sprouts"
},
+ {
+ "id" : "minecraft:coral",
+ "blockRuntimeId" : 3682
+ },
+ {
+ "id" : "minecraft:coral",
+ "blockRuntimeId" : 3680
+ },
{
"id" : "minecraft:coral",
"blockRuntimeId" : 3681
@@ -1970,15 +1978,15 @@
},
{
"id" : "minecraft:coral",
- "blockRuntimeId" : 3680
+ "blockRuntimeId" : 3683
},
{
"id" : "minecraft:coral",
- "blockRuntimeId" : 3678
+ "blockRuntimeId" : 3687
},
{
"id" : "minecraft:coral",
- "blockRuntimeId" : 3682
+ "blockRuntimeId" : 3685
},
{
"id" : "minecraft:coral",
@@ -1990,15 +1998,15 @@
},
{
"id" : "minecraft:coral",
- "blockRuntimeId" : 3685
+ "blockRuntimeId" : 3688
},
{
- "id" : "minecraft:coral",
- "blockRuntimeId" : 3683
+ "id" : "minecraft:coral_fan",
+ "blockRuntimeId" : 3702
},
{
- "id" : "minecraft:coral",
- "blockRuntimeId" : 3687
+ "id" : "minecraft:coral_fan",
+ "blockRuntimeId" : 3700
},
{
"id" : "minecraft:coral_fan",
@@ -2010,15 +2018,15 @@
},
{
"id" : "minecraft:coral_fan",
- "blockRuntimeId" : 3700
+ "blockRuntimeId" : 3703
},
{
- "id" : "minecraft:coral_fan",
- "blockRuntimeId" : 3698
+ "id" : "minecraft:coral_fan_dead",
+ "blockRuntimeId" : 3712
},
{
- "id" : "minecraft:coral_fan",
- "blockRuntimeId" : 3702
+ "id" : "minecraft:coral_fan_dead",
+ "blockRuntimeId" : 3710
},
{
"id" : "minecraft:coral_fan_dead",
@@ -2030,58 +2038,26 @@
},
{
"id" : "minecraft:coral_fan_dead",
- "blockRuntimeId" : 3710
- },
- {
- "id" : "minecraft:coral_fan_dead",
- "blockRuntimeId" : 3708
- },
- {
- "id" : "minecraft:coral_fan_dead",
- "blockRuntimeId" : 3712
+ "blockRuntimeId" : 3713
},
{
"id" : "minecraft:kelp"
},
{
"id" : "minecraft:seagrass",
- "blockRuntimeId" : 6821
+ "blockRuntimeId" : 6828
},
{
"id" : "minecraft:crimson_roots",
- "blockRuntimeId" : 3856
+ "blockRuntimeId" : 3857
},
{
"id" : "minecraft:warped_roots",
- "blockRuntimeId" : 7611
+ "blockRuntimeId" : 7613
},
{
"id" : "minecraft:yellow_flower",
- "blockRuntimeId" : 7937
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6587
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6588
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6589
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6590
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6591
- },
- {
- "id" : "minecraft:red_flower",
- "blockRuntimeId" : 6592
+ "blockRuntimeId" : 7939
},
{
"id" : "minecraft:red_flower",
@@ -2104,8 +2080,28 @@
"blockRuntimeId" : 6597
},
{
- "id" : "minecraft:double_plant",
- "blockRuntimeId" : 4500
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6598
+ },
+ {
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6599
+ },
+ {
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6600
+ },
+ {
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6601
+ },
+ {
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6602
+ },
+ {
+ "id" : "minecraft:red_flower",
+ "blockRuntimeId" : 6603
},
{
"id" : "minecraft:double_plant",
@@ -2113,15 +2109,19 @@
},
{
"id" : "minecraft:double_plant",
- "blockRuntimeId" : 4504
+ "blockRuntimeId" : 4502
},
{
"id" : "minecraft:double_plant",
"blockRuntimeId" : 4505
},
+ {
+ "id" : "minecraft:double_plant",
+ "blockRuntimeId" : 4506
+ },
{
"id" : "minecraft:wither_rose",
- "blockRuntimeId" : 7802
+ "blockRuntimeId" : 7804
},
{
"id" : "minecraft:white_dye"
@@ -2188,23 +2188,23 @@
},
{
"id" : "minecraft:vine",
- "blockRuntimeId" : 7498
+ "blockRuntimeId" : 7500
},
{
"id" : "minecraft:weeping_vines",
- "blockRuntimeId" : 7752
+ "blockRuntimeId" : 7754
},
{
"id" : "minecraft:twisting_vines",
- "blockRuntimeId" : 7426
+ "blockRuntimeId" : 7427
},
{
"id" : "minecraft:waterlily",
- "blockRuntimeId" : 7680
+ "blockRuntimeId" : 7682
},
{
"id" : "minecraft:deadbush",
- "blockRuntimeId" : 4098
+ "blockRuntimeId" : 4099
},
{
"id" : "minecraft:bamboo",
@@ -2212,15 +2212,15 @@
},
{
"id" : "minecraft:snow",
- "blockRuntimeId" : 6908
+ "blockRuntimeId" : 6909
},
{
"id" : "minecraft:ice",
- "blockRuntimeId" : 5125
+ "blockRuntimeId" : 5127
},
{
"id" : "minecraft:packed_ice",
- "blockRuntimeId" : 5765
+ "blockRuntimeId" : 5770
},
{
"id" : "minecraft:blue_ice",
@@ -2228,35 +2228,31 @@
},
{
"id" : "minecraft:snow_layer",
- "blockRuntimeId" : 6909
+ "blockRuntimeId" : 6910
},
{
"id" : "minecraft:pointed_dripstone",
- "blockRuntimeId" : 5806
- },
- {
- "id" : "minecraft:sculk_sensor",
- "blockRuntimeId" : 6745
+ "blockRuntimeId" : 5812
},
{
"id" : "minecraft:dripstone_block",
- "blockRuntimeId" : 4584
+ "blockRuntimeId" : 4585
},
{
"id" : "minecraft:moss_carpet",
- "blockRuntimeId" : 5665
+ "blockRuntimeId" : 5667
},
{
"id" : "minecraft:moss_block",
- "blockRuntimeId" : 5664
+ "blockRuntimeId" : 5666
},
{
"id" : "minecraft:dirt_with_roots",
- "blockRuntimeId" : 4485
+ "blockRuntimeId" : 4486
},
{
"id" : "minecraft:hanging_roots",
- "blockRuntimeId" : 5047
+ "blockRuntimeId" : 5049
},
{
"id" : "minecraft:big_dripleaf",
@@ -2264,11 +2260,11 @@
},
{
"id" : "minecraft:small_dripleaf_block",
- "blockRuntimeId" : 6874
+ "blockRuntimeId" : 6875
},
{
"id" : "minecraft:spore_blossom",
- "blockRuntimeId" : 6961
+ "blockRuntimeId" : 6962
},
{
"id" : "minecraft:azalea",
@@ -2276,11 +2272,11 @@
},
{
"id" : "minecraft:flowering_azalea",
- "blockRuntimeId" : 4814
+ "blockRuntimeId" : 4815
},
{
"id" : "minecraft:glow_lichen",
- "blockRuntimeId" : 4971
+ "blockRuntimeId" : 4973
},
{
"id" : "minecraft:amethyst_block",
@@ -2292,23 +2288,23 @@
},
{
"id" : "minecraft:amethyst_cluster",
- "blockRuntimeId" : 137
+ "blockRuntimeId" : 138
},
{
"id" : "minecraft:large_amethyst_bud",
- "blockRuntimeId" : 5366
+ "blockRuntimeId" : 5369
},
{
"id" : "minecraft:medium_amethyst_bud",
- "blockRuntimeId" : 5602
+ "blockRuntimeId" : 5605
},
{
"id" : "minecraft:small_amethyst_bud",
- "blockRuntimeId" : 6861
+ "blockRuntimeId" : 6863
},
{
"id" : "minecraft:tuff",
- "blockRuntimeId" : 7413
+ "blockRuntimeId" : 7414
},
{
"id" : "minecraft:calcite",
@@ -2347,15 +2343,15 @@
},
{
"id" : "minecraft:red_mushroom",
- "blockRuntimeId" : 6604
+ "blockRuntimeId" : 6610
},
{
"id" : "minecraft:crimson_fungus",
- "blockRuntimeId" : 3834
+ "blockRuntimeId" : 3835
},
{
"id" : "minecraft:warped_fungus",
- "blockRuntimeId" : 7589
+ "blockRuntimeId" : 7591
},
{
"id" : "minecraft:brown_mushroom_block",
@@ -2363,7 +2359,7 @@
},
{
"id" : "minecraft:red_mushroom_block",
- "blockRuntimeId" : 6619
+ "blockRuntimeId" : 6625
},
{
"id" : "minecraft:brown_mushroom_block",
@@ -2390,21 +2386,13 @@
},
{
"id" : "minecraft:web",
- "blockRuntimeId" : 7751
+ "blockRuntimeId" : 7753
},
{
"id" : "minecraft:spider_eye"
},
{
"id" : "minecraft:mob_spawner",
- "blockRuntimeId" : 5657
- },
- {
- "id" : "minecraft:monster_egg",
- "blockRuntimeId" : 5658
- },
- {
- "id" : "minecraft:monster_egg",
"blockRuntimeId" : 5659
},
{
@@ -2423,17 +2411,25 @@
"id" : "minecraft:monster_egg",
"blockRuntimeId" : 5663
},
+ {
+ "id" : "minecraft:monster_egg",
+ "blockRuntimeId" : 5664
+ },
+ {
+ "id" : "minecraft:monster_egg",
+ "blockRuntimeId" : 5665
+ },
{
"id" : "minecraft:infested_deepslate",
- "blockRuntimeId" : 5126
+ "blockRuntimeId" : 5128
},
{
"id" : "minecraft:dragon_egg",
- "blockRuntimeId" : 4582
+ "blockRuntimeId" : 4583
},
{
"id" : "minecraft:turtle_egg",
- "blockRuntimeId" : 7414
+ "blockRuntimeId" : 7415
},
{
"id" : "minecraft:chicken_spawn_egg"
@@ -2635,11 +2631,11 @@
},
{
"id" : "minecraft:obsidian",
- "blockRuntimeId" : 5734
+ "blockRuntimeId" : 5738
},
{
"id" : "minecraft:crying_obsidian",
- "blockRuntimeId" : 3908
+ "blockRuntimeId" : 3909
},
{
"id" : "minecraft:bedrock",
@@ -2647,22 +2643,22 @@
},
{
"id" : "minecraft:soul_sand",
- "blockRuntimeId" : 6951
+ "blockRuntimeId" : 6952
},
{
"id" : "minecraft:netherrack",
- "blockRuntimeId" : 5703
+ "blockRuntimeId" : 5707
},
{
"id" : "minecraft:magma",
- "blockRuntimeId" : 5601
+ "blockRuntimeId" : 5603
},
{
"id" : "minecraft:nether_wart"
},
{
"id" : "minecraft:end_stone",
- "blockRuntimeId" : 4744
+ "blockRuntimeId" : 4745
},
{
"id" : "minecraft:chorus_flower",
@@ -2678,17 +2674,13 @@
{
"id" : "minecraft:popped_chorus_fruit"
},
- {
- "id" : "minecraft:sponge",
- "blockRuntimeId" : 6959
- },
{
"id" : "minecraft:sponge",
"blockRuntimeId" : 6960
},
{
- "id" : "minecraft:coral_block",
- "blockRuntimeId" : 3688
+ "id" : "minecraft:sponge",
+ "blockRuntimeId" : 6961
},
{
"id" : "minecraft:coral_block",
@@ -2726,6 +2718,10 @@
"id" : "minecraft:coral_block",
"blockRuntimeId" : 3697
},
+ {
+ "id" : "minecraft:coral_block",
+ "blockRuntimeId" : 3698
+ },
{
"id" : "minecraft:leather_helmet"
},
@@ -3751,23 +3747,23 @@
},
{
"id" : "minecraft:torch",
- "blockRuntimeId" : 7353
+ "blockRuntimeId" : 7354
},
{
"id" : "minecraft:soul_torch",
- "blockRuntimeId" : 6953
+ "blockRuntimeId" : 6954
},
{
"id" : "minecraft:sea_pickle",
- "blockRuntimeId" : 6813
+ "blockRuntimeId" : 6820
},
{
"id" : "minecraft:lantern",
- "blockRuntimeId" : 5362
+ "blockRuntimeId" : 5364
},
{
"id" : "minecraft:soul_lantern",
- "blockRuntimeId" : 6949
+ "blockRuntimeId" : 6950
},
{
"id" : "minecraft:candle",
@@ -3775,47 +3771,47 @@
},
{
"id" : "minecraft:white_candle",
- "blockRuntimeId" : 7786
+ "blockRuntimeId" : 7788
},
{
"id" : "minecraft:orange_candle",
- "blockRuntimeId" : 5735
+ "blockRuntimeId" : 5740
},
{
"id" : "minecraft:magenta_candle",
- "blockRuntimeId" : 5585
+ "blockRuntimeId" : 5587
},
{
"id" : "minecraft:light_blue_candle",
- "blockRuntimeId" : 5473
+ "blockRuntimeId" : 5475
},
{
"id" : "minecraft:yellow_candle",
- "blockRuntimeId" : 7927
+ "blockRuntimeId" : 7929
},
{
"id" : "minecraft:lime_candle",
- "blockRuntimeId" : 5521
+ "blockRuntimeId" : 5523
},
{
"id" : "minecraft:pink_candle",
- "blockRuntimeId" : 5766
+ "blockRuntimeId" : 5772
},
{
"id" : "minecraft:gray_candle",
- "blockRuntimeId" : 4999
+ "blockRuntimeId" : 5001
},
{
"id" : "minecraft:light_gray_candle",
- "blockRuntimeId" : 5489
+ "blockRuntimeId" : 5491
},
{
"id" : "minecraft:cyan_candle",
- "blockRuntimeId" : 3920
+ "blockRuntimeId" : 3921
},
{
"id" : "minecraft:purple_candle",
- "blockRuntimeId" : 6506
+ "blockRuntimeId" : 6512
},
{
"id" : "minecraft:blue_candle",
@@ -3827,11 +3823,11 @@
},
{
"id" : "minecraft:green_candle",
- "blockRuntimeId" : 5015
+ "blockRuntimeId" : 5017
},
{
"id" : "minecraft:red_candle",
- "blockRuntimeId" : 6577
+ "blockRuntimeId" : 6583
},
{
"id" : "minecraft:black_candle",
@@ -3839,7 +3835,7 @@
},
{
"id" : "minecraft:crafting_table",
- "blockRuntimeId" : 3770
+ "blockRuntimeId" : 3771
},
{
"id" : "minecraft:cartography_table",
@@ -3847,11 +3843,11 @@
},
{
"id" : "minecraft:fletching_table",
- "blockRuntimeId" : 4811
+ "blockRuntimeId" : 4812
},
{
"id" : "minecraft:smithing_table",
- "blockRuntimeId" : 6875
+ "blockRuntimeId" : 6876
},
{
"id" : "minecraft:beehive",
@@ -3865,7 +3861,7 @@
},
{
"id" : "minecraft:furnace",
- "blockRuntimeId" : 4875
+ "blockRuntimeId" : 4877
},
{
"id" : "minecraft:blast_furnace",
@@ -3873,11 +3869,11 @@
},
{
"id" : "minecraft:smoker",
- "blockRuntimeId" : 6876
+ "blockRuntimeId" : 6877
},
{
"id" : "minecraft:respawn_anchor",
- "blockRuntimeId" : 6696
+ "blockRuntimeId" : 6702
},
{
"id" : "minecraft:brewing_stand"
@@ -3896,11 +3892,11 @@
},
{
"id" : "minecraft:grindstone",
- "blockRuntimeId" : 5031
+ "blockRuntimeId" : 5033
},
{
"id" : "minecraft:enchanting_table",
- "blockRuntimeId" : 4718
+ "blockRuntimeId" : 4719
},
{
"id" : "minecraft:bookshelf",
@@ -3908,14 +3904,14 @@
},
{
"id" : "minecraft:lectern",
- "blockRuntimeId" : 5433
+ "blockRuntimeId" : 5435
},
{
"id" : "minecraft:cauldron"
},
{
"id" : "minecraft:composter",
- "blockRuntimeId" : 3634
+ "blockRuntimeId" : 3635
},
{
"id" : "minecraft:chest",
@@ -3923,11 +3919,11 @@
},
{
"id" : "minecraft:trapped_chest",
- "blockRuntimeId" : 7375
+ "blockRuntimeId" : 7376
},
{
"id" : "minecraft:ender_chest",
- "blockRuntimeId" : 4745
+ "blockRuntimeId" : 4746
},
{
"id" : "minecraft:barrel",
@@ -3935,15 +3931,7 @@
},
{
"id" : "minecraft:undyed_shulker_box",
- "blockRuntimeId" : 7458
- },
- {
- "id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6826
- },
- {
- "id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6834
+ "blockRuntimeId" : 7459
},
{
"id" : "minecraft:shulker_box",
@@ -3953,64 +3941,72 @@
"id" : "minecraft:shulker_box",
"blockRuntimeId" : 6841
},
- {
- "id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6838
- },
{
"id" : "minecraft:shulker_box",
"blockRuntimeId" : 6840
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6827
+ "blockRuntimeId" : 6848
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6830
+ "blockRuntimeId" : 6845
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6831
+ "blockRuntimeId" : 6847
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6839
- },
- {
- "id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6835
- },
- {
- "id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6829
+ "blockRuntimeId" : 6834
},
{
"id" : "minecraft:shulker_box",
"blockRuntimeId" : 6837
},
+ {
+ "id" : "minecraft:shulker_box",
+ "blockRuntimeId" : 6838
+ },
+ {
+ "id" : "minecraft:shulker_box",
+ "blockRuntimeId" : 6846
+ },
+ {
+ "id" : "minecraft:shulker_box",
+ "blockRuntimeId" : 6842
+ },
{
"id" : "minecraft:shulker_box",
"blockRuntimeId" : 6836
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6828
+ "blockRuntimeId" : 6844
},
{
"id" : "minecraft:shulker_box",
- "blockRuntimeId" : 6832
+ "blockRuntimeId" : 6843
+ },
+ {
+ "id" : "minecraft:shulker_box",
+ "blockRuntimeId" : 6835
+ },
+ {
+ "id" : "minecraft:shulker_box",
+ "blockRuntimeId" : 6839
},
{
"id" : "minecraft:armor_stand"
},
{
"id" : "minecraft:noteblock",
- "blockRuntimeId" : 5713
+ "blockRuntimeId" : 5717
},
{
"id" : "minecraft:jukebox",
- "blockRuntimeId" : 5207
+ "blockRuntimeId" : 5209
},
{
"id" : "minecraft:music_disc_13"
@@ -4048,6 +4044,9 @@
{
"id" : "minecraft:music_disc_wait"
},
+ {
+ "id" : "minecraft:music_disc_otherside"
+ },
{
"id" : "minecraft:music_disc_pigstep"
},
@@ -4056,15 +4055,15 @@
},
{
"id" : "minecraft:glowstone",
- "blockRuntimeId" : 4973
+ "blockRuntimeId" : 4975
},
{
"id" : "minecraft:redstone_lamp",
- "blockRuntimeId" : 6643
+ "blockRuntimeId" : 6649
},
{
"id" : "minecraft:sealantern",
- "blockRuntimeId" : 6824
+ "blockRuntimeId" : 6831
},
{
"id" : "minecraft:oak_sign"
@@ -4171,15 +4170,15 @@
},
{
"id" : "minecraft:conduit",
- "blockRuntimeId" : 3675
+ "blockRuntimeId" : 3676
},
{
"id" : "minecraft:stonecutter_block",
- "blockRuntimeId" : 7291
+ "blockRuntimeId" : 7292
},
{
"id" : "minecraft:end_portal_frame",
- "blockRuntimeId" : 4730
+ "blockRuntimeId" : 4731
},
{
"id" : "minecraft:coal"
@@ -4315,11 +4314,11 @@
},
{
"id" : "minecraft:end_rod",
- "blockRuntimeId" : 4738
+ "blockRuntimeId" : 4739
},
{
"id" : "minecraft:lightning_rod",
- "blockRuntimeId" : 5515
+ "blockRuntimeId" : 5517
},
{
"id" : "minecraft:end_crystal"
@@ -4781,15 +4780,15 @@
},
{
"id" : "minecraft:rail",
- "blockRuntimeId" : 6564
+ "blockRuntimeId" : 6570
},
{
"id" : "minecraft:golden_rail",
- "blockRuntimeId" : 4976
+ "blockRuntimeId" : 4978
},
{
"id" : "minecraft:detector_rail",
- "blockRuntimeId" : 4461
+ "blockRuntimeId" : 4462
},
{
"id" : "minecraft:activator_rail",
@@ -4812,23 +4811,23 @@
},
{
"id" : "minecraft:redstone_block",
- "blockRuntimeId" : 6642
+ "blockRuntimeId" : 6648
},
{
"id" : "minecraft:redstone_torch",
- "blockRuntimeId" : 6645
+ "blockRuntimeId" : 6651
},
{
"id" : "minecraft:lever",
- "blockRuntimeId" : 5441
+ "blockRuntimeId" : 5443
},
{
"id" : "minecraft:wooden_button",
- "blockRuntimeId" : 7839
+ "blockRuntimeId" : 7841
},
{
"id" : "minecraft:spruce_button",
- "blockRuntimeId" : 6962
+ "blockRuntimeId" : 6963
},
{
"id" : "minecraft:birch_button",
@@ -4836,42 +4835,42 @@
},
{
"id" : "minecraft:jungle_button",
- "blockRuntimeId" : 5208
+ "blockRuntimeId" : 5210
},
{
"id" : "minecraft:acacia_button"
},
{
"id" : "minecraft:dark_oak_button",
- "blockRuntimeId" : 3936
+ "blockRuntimeId" : 3937
},
{
"id" : "minecraft:stone_button",
- "blockRuntimeId" : 7191
+ "blockRuntimeId" : 7192
},
{
"id" : "minecraft:crimson_button",
- "blockRuntimeId" : 3771
+ "blockRuntimeId" : 3772
},
{
"id" : "minecraft:warped_button",
- "blockRuntimeId" : 7526
+ "blockRuntimeId" : 7528
},
{
"id" : "minecraft:polished_blackstone_button",
- "blockRuntimeId" : 5998
+ "blockRuntimeId" : 6004
},
{
"id" : "minecraft:tripwire_hook",
- "blockRuntimeId" : 7397
+ "blockRuntimeId" : 7398
},
{
"id" : "minecraft:wooden_pressure_plate",
- "blockRuntimeId" : 7883
+ "blockRuntimeId" : 7885
},
{
"id" : "minecraft:spruce_pressure_plate",
- "blockRuntimeId" : 7022
+ "blockRuntimeId" : 7023
},
{
"id" : "minecraft:birch_pressure_plate",
@@ -4879,7 +4878,7 @@
},
{
"id" : "minecraft:jungle_pressure_plate",
- "blockRuntimeId" : 5268
+ "blockRuntimeId" : 5270
},
{
"id" : "minecraft:acacia_pressure_plate",
@@ -4887,39 +4886,39 @@
},
{
"id" : "minecraft:dark_oak_pressure_plate",
- "blockRuntimeId" : 3996
+ "blockRuntimeId" : 3997
},
{
"id" : "minecraft:crimson_pressure_plate",
- "blockRuntimeId" : 3840
+ "blockRuntimeId" : 3841
},
{
"id" : "minecraft:warped_pressure_plate",
- "blockRuntimeId" : 7595
+ "blockRuntimeId" : 7597
},
{
"id" : "minecraft:stone_pressure_plate",
- "blockRuntimeId" : 7203
+ "blockRuntimeId" : 7204
},
{
"id" : "minecraft:light_weighted_pressure_plate",
- "blockRuntimeId" : 5499
+ "blockRuntimeId" : 5501
},
{
"id" : "minecraft:heavy_weighted_pressure_plate",
- "blockRuntimeId" : 5095
+ "blockRuntimeId" : 5097
},
{
"id" : "minecraft:polished_blackstone_pressure_plate",
- "blockRuntimeId" : 6012
+ "blockRuntimeId" : 6018
},
{
"id" : "minecraft:observer",
- "blockRuntimeId" : 5722
+ "blockRuntimeId" : 5726
},
{
"id" : "minecraft:daylight_detector",
- "blockRuntimeId" : 4066
+ "blockRuntimeId" : 4067
},
{
"id" : "minecraft:repeater"
@@ -4932,30 +4931,30 @@
},
{
"id" : "minecraft:dropper",
- "blockRuntimeId" : 4588
+ "blockRuntimeId" : 4589
},
{
"id" : "minecraft:dispenser",
- "blockRuntimeId" : 4489
+ "blockRuntimeId" : 4490
},
{
"id" : "minecraft:piston",
- "blockRuntimeId" : 5783
+ "blockRuntimeId" : 5789
},
{
"id" : "minecraft:sticky_piston",
- "blockRuntimeId" : 7165
+ "blockRuntimeId" : 7166
},
{
"id" : "minecraft:tnt",
- "blockRuntimeId" : 7349
+ "blockRuntimeId" : 7350
},
{
"id" : "minecraft:name_tag"
},
{
"id" : "minecraft:loom",
- "blockRuntimeId" : 5581
+ "blockRuntimeId" : 5583
},
{
"id" : "minecraft:banner"
@@ -5046,6 +5045,9 @@
{
"id" : "minecraft:piglin_banner_pattern"
},
+ {
+ "id" : "minecraft:globe_banner_pattern"
+ },
{
"id" : "minecraft:firework_rocket",
"nbt_b64" : "CgAACgkARmlyZXdvcmtzCQoARXhwbG9zaW9ucwAAAAAAAQYARmxpZ2h0AQAA"
@@ -5198,7 +5200,7 @@
},
{
"id" : "minecraft:target",
- "blockRuntimeId" : 7347
+ "blockRuntimeId" : 7348
},
{
"id" : "minecraft:lodestone_compass"
diff --git a/core/src/main/resources/bedrock/runtime_item_states.1_17_30.json b/core/src/main/resources/bedrock/runtime_item_states.1_18_10.json
similarity index 98%
rename from core/src/main/resources/bedrock/runtime_item_states.1_17_30.json
rename to core/src/main/resources/bedrock/runtime_item_states.1_18_10.json
index 79690e3da..5bebcaf99 100644
--- a/core/src/main/resources/bedrock/runtime_item_states.1_17_30.json
+++ b/core/src/main/resources/bedrock/runtime_item_states.1_18_10.json
@@ -51,6 +51,10 @@
"name" : "minecraft:air",
"id" : -158
},
+ {
+ "name" : "minecraft:allay_spawn_egg",
+ "id" : 631
+ },
{
"name" : "minecraft:allow",
"id" : 210
@@ -65,7 +69,7 @@
},
{
"name" : "minecraft:amethyst_shard",
- "id" : 623
+ "id" : 625
},
{
"name" : "minecraft:ancient_debris",
@@ -117,7 +121,7 @@
},
{
"name" : "minecraft:balloon",
- "id" : 597
+ "id" : 598
},
{
"name" : "minecraft:bamboo",
@@ -133,7 +137,7 @@
},
{
"name" : "minecraft:banner_pattern",
- "id" : 627
+ "id" : 635
},
{
"name" : "minecraft:barrel",
@@ -293,7 +297,7 @@
},
{
"name" : "minecraft:bleach",
- "id" : 595
+ "id" : 596
},
{
"name" : "minecraft:blue_candle",
@@ -317,7 +321,7 @@
},
{
"name" : "minecraft:boat",
- "id" : 625
+ "id" : 633
},
{
"name" : "minecraft:bone",
@@ -429,11 +433,11 @@
},
{
"name" : "minecraft:camera",
- "id" : 592
+ "id" : 593
},
{
"name" : "minecraft:campfire",
- "id" : 588
+ "id" : 589
},
{
"name" : "minecraft:candle",
@@ -493,7 +497,7 @@
},
{
"name" : "minecraft:chain",
- "id" : 617
+ "id" : 619
},
{
"name" : "minecraft:chain_command_block",
@@ -575,6 +579,10 @@
"name" : "minecraft:clay_ball",
"id" : 384
},
+ {
+ "name" : "minecraft:client_request_placeholder_block",
+ "id" : -465
+ },
{
"name" : "minecraft:clock",
"id" : 393
@@ -669,7 +677,7 @@
},
{
"name" : "minecraft:compound",
- "id" : 593
+ "id" : 594
},
{
"name" : "minecraft:concrete",
@@ -793,7 +801,7 @@
},
{
"name" : "minecraft:crimson_door",
- "id" : 614
+ "id" : 616
},
{
"name" : "minecraft:crimson_double_slab",
@@ -833,7 +841,7 @@
},
{
"name" : "minecraft:crimson_sign",
- "id" : 612
+ "id" : 614
},
{
"name" : "minecraft:crimson_slab",
@@ -1169,7 +1177,7 @@
},
{
"name" : "minecraft:dye",
- "id" : 626
+ "id" : 634
},
{
"name" : "minecraft:egg",
@@ -1697,7 +1705,7 @@
},
{
"name" : "minecraft:end_crystal",
- "id" : 629
+ "id" : 637
},
{
"name" : "minecraft:end_gateway",
@@ -1803,6 +1811,10 @@
"name" : "minecraft:fire_charge",
"id" : 509
},
+ {
+ "name" : "minecraft:firefly_spawn_egg",
+ "id" : 632
+ },
{
"name" : "minecraft:firework_rocket",
"id" : 519
@@ -1855,6 +1867,14 @@
"name" : "minecraft:frame",
"id" : 513
},
+ {
+ "name" : "minecraft:frog_egg",
+ "id" : -468
+ },
+ {
+ "name" : "minecraft:frog_spawn_egg",
+ "id" : 628
+ },
{
"name" : "minecraft:frosted_ice",
"id" : 207
@@ -1891,13 +1911,17 @@
"name" : "minecraft:glistering_melon_slice",
"id" : 434
},
+ {
+ "name" : "minecraft:globe_banner_pattern",
+ "id" : 588
+ },
{
"name" : "minecraft:glow_berries",
- "id" : 630
+ "id" : 638
},
{
"name" : "minecraft:glow_frame",
- "id" : 621
+ "id" : 623
},
{
"name" : "minecraft:glow_ink_sac",
@@ -1913,7 +1937,7 @@
},
{
"name" : "minecraft:glow_stick",
- "id" : 166
+ "id" : 601
},
{
"name" : "minecraft:glowingobsidian",
@@ -1929,7 +1953,7 @@
},
{
"name" : "minecraft:goat_horn",
- "id" : 622
+ "id" : 624
},
{
"name" : "minecraft:goat_spawn_egg",
@@ -2109,11 +2133,11 @@
},
{
"name" : "minecraft:honey_bottle",
- "id" : 591
+ "id" : 592
},
{
"name" : "minecraft:honeycomb",
- "id" : 590
+ "id" : 591
},
{
"name" : "minecraft:honeycomb_block",
@@ -2141,7 +2165,7 @@
},
{
"name" : "minecraft:ice_bomb",
- "id" : 594
+ "id" : 595
},
{
"name" : "minecraft:infested_deepslate",
@@ -2569,7 +2593,7 @@
},
{
"name" : "minecraft:lodestone_compass",
- "id" : 600
+ "id" : 602
},
{
"name" : "minecraft:log",
@@ -2613,7 +2637,7 @@
},
{
"name" : "minecraft:medicine",
- "id" : 598
+ "id" : 599
},
{
"name" : "minecraft:medium_amethyst_bud",
@@ -2723,9 +2747,13 @@
"name" : "minecraft:music_disc_mellohi",
"id" : 540
},
+ {
+ "name" : "minecraft:music_disc_otherside",
+ "id" : 627
+ },
{
"name" : "minecraft:music_disc_pigstep",
- "id" : 618
+ "id" : 620
},
{
"name" : "minecraft:music_disc_stal",
@@ -2751,6 +2779,14 @@
"name" : "minecraft:mycelium",
"id" : 110
},
+ {
+ "name" : "minecraft:mysterious_frame",
+ "id" : -466
+ },
+ {
+ "name" : "minecraft:mysterious_frame_slot",
+ "id" : -467
+ },
{
"name" : "minecraft:name_tag",
"id" : 548
@@ -2777,7 +2813,7 @@
},
{
"name" : "minecraft:nether_sprouts",
- "id" : 619
+ "id" : 621
},
{
"name" : "minecraft:nether_star",
@@ -2797,7 +2833,7 @@
},
{
"name" : "minecraft:netherite_axe",
- "id" : 605
+ "id" : 607
},
{
"name" : "minecraft:netherite_block",
@@ -2805,43 +2841,43 @@
},
{
"name" : "minecraft:netherite_boots",
- "id" : 610
+ "id" : 612
},
{
"name" : "minecraft:netherite_chestplate",
- "id" : 608
+ "id" : 610
},
{
"name" : "minecraft:netherite_helmet",
- "id" : 607
- },
- {
- "name" : "minecraft:netherite_hoe",
- "id" : 606
- },
- {
- "name" : "minecraft:netherite_ingot",
- "id" : 601
- },
- {
- "name" : "minecraft:netherite_leggings",
"id" : 609
},
{
- "name" : "minecraft:netherite_pickaxe",
- "id" : 604
+ "name" : "minecraft:netherite_hoe",
+ "id" : 608
},
{
- "name" : "minecraft:netherite_scrap",
- "id" : 611
- },
- {
- "name" : "minecraft:netherite_shovel",
+ "name" : "minecraft:netherite_ingot",
"id" : 603
},
+ {
+ "name" : "minecraft:netherite_leggings",
+ "id" : 611
+ },
+ {
+ "name" : "minecraft:netherite_pickaxe",
+ "id" : 606
+ },
+ {
+ "name" : "minecraft:netherite_scrap",
+ "id" : 613
+ },
+ {
+ "name" : "minecraft:netherite_shovel",
+ "id" : 605
+ },
{
"name" : "minecraft:netherite_sword",
- "id" : 602
+ "id" : 604
},
{
"name" : "minecraft:netherrack",
@@ -2887,6 +2923,10 @@
"name" : "minecraft:ocelot_spawn_egg",
"id" : 451
},
+ {
+ "name" : "minecraft:ochre_froglight",
+ "id" : -471
+ },
{
"name" : "minecraft:orange_candle",
"id" : -414
@@ -2943,6 +2983,10 @@
"name" : "minecraft:parrot_spawn_egg",
"id" : 478
},
+ {
+ "name" : "minecraft:pearlescent_froglight",
+ "id" : -469
+ },
{
"name" : "minecraft:phantom_membrane",
"id" : 574
@@ -3257,7 +3301,7 @@
},
{
"name" : "minecraft:rapid_fertilizer",
- "id" : 596
+ "id" : 597
},
{
"name" : "minecraft:ravager_spawn_egg",
@@ -3577,7 +3621,7 @@
},
{
"name" : "minecraft:soul_campfire",
- "id" : 620
+ "id" : 622
},
{
"name" : "minecraft:soul_fire",
@@ -3601,11 +3645,11 @@
},
{
"name" : "minecraft:sparkler",
- "id" : 599
+ "id" : 600
},
{
"name" : "minecraft:spawn_egg",
- "id" : 628
+ "id" : 636
},
{
"name" : "minecraft:spider_eye",
@@ -3669,7 +3713,7 @@
},
{
"name" : "minecraft:spyglass",
- "id" : 624
+ "id" : 626
},
{
"name" : "minecraft:squid_spawn_egg",
@@ -3829,7 +3873,7 @@
},
{
"name" : "minecraft:suspicious_stew",
- "id" : 589
+ "id" : 590
},
{
"name" : "minecraft:sweet_berries",
@@ -3839,6 +3883,14 @@
"name" : "minecraft:sweet_berry_bush",
"id" : -207
},
+ {
+ "name" : "minecraft:tadpole_bucket",
+ "id" : 630
+ },
+ {
+ "name" : "minecraft:tadpole_spawn_egg",
+ "id" : 629
+ },
{
"name" : "minecraft:tallgrass",
"id" : 31
@@ -3943,6 +3995,10 @@
"name" : "minecraft:unpowered_repeater",
"id" : 93
},
+ {
+ "name" : "minecraft:verdant_froglight",
+ "id" : -470
+ },
{
"name" : "minecraft:vex_spawn_egg",
"id" : 476
@@ -3977,7 +4033,7 @@
},
{
"name" : "minecraft:warped_door",
- "id" : 615
+ "id" : 617
},
{
"name" : "minecraft:warped_double_slab",
@@ -3997,7 +4053,7 @@
},
{
"name" : "minecraft:warped_fungus_on_a_stick",
- "id" : 616
+ "id" : 618
},
{
"name" : "minecraft:warped_hyphae",
@@ -4021,7 +4077,7 @@
},
{
"name" : "minecraft:warped_sign",
- "id" : 613
+ "id" : 615
},
{
"name" : "minecraft:warped_slab",
diff --git a/core/src/main/resources/config.yml b/core/src/main/resources/config.yml
index 8c5737a39..00e2521f3 100644
--- a/core/src/main/resources/config.yml
+++ b/core/src/main/resources/config.yml
@@ -125,6 +125,13 @@ show-cooldown: title
# Controls if coordinates are shown to players.
show-coordinates: true
+# Whether Bedrock players are blocked from performing their scaffolding-style bridging.
+disable-bedrock-scaffolding: false
+
+# Whether Bedrock players can right-click outside of their inventory to replace armor in their inventory, even if the
+# armor slot is already occupied (which Java Edition doesn't allow)
+always-quick-change-armor: false
+
# If set, when a Bedrock player performs any emote, it will swap the offhand and mainhand items, just like the Java Edition keybind
# There are three options this can be set to:
# disabled - the default/fallback, which doesn't apply this workaround
diff --git a/pom.xml b/pom.xml
index db512e477..191a40704 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.geysermc
geyser-parent
- 2.0.0-SNAPSHOT
+ 2.0.1-SNAPSHOT
pom
Geyser
Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.