1.16.220 support (#2105)

This update does not break compatibility with any other currently supported version of Bedrock.

Co-authored-by: Redned <redned235@gmail.com>
This commit is contained in:
Camotoy 2021-04-06 00:14:06 -04:00 committed by GitHub
parent 8f6785e48f
commit 86b2901f02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 175 additions and 110 deletions

View File

@ -18,7 +18,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 now joined us here! Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.210 and Minecraft Java v1.16.4 - v1.16.5. ### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5.
## Setting Up ## Setting Up
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-bungeecord</artifactId> <artifactId>bootstrap-bungeecord</artifactId>
@ -14,7 +14,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId> <artifactId>geyser-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-spigot</artifactId> <artifactId>bootstrap-spigot</artifactId>
@ -14,7 +14,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-sponge</artifactId> <artifactId>bootstrap-sponge</artifactId>
@ -14,7 +14,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-standalone</artifactId> <artifactId>bootstrap-standalone</artifactId>
@ -14,7 +14,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>bootstrap-parent</artifactId> <artifactId>bootstrap-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>bootstrap-velocity</artifactId> <artifactId>bootstrap-velocity</artifactId>
@ -14,7 +14,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId> <artifactId>geyser-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>common</artifactId> <artifactId>common</artifactId>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId> <artifactId>geyser-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>connector</artifactId> <artifactId>connector</artifactId>
@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>common</artifactId> <artifactId>common</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -31,8 +31,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.CloudburstMC.Protocol</groupId> <groupId>com.github.CloudburstMC.Protocol</groupId>
<artifactId>bedrock-v428</artifactId> <artifactId>bedrock-v431</artifactId>
<version>42da92f</version> <version>f8ecf54</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View File

@ -107,7 +107,7 @@ public class ItemFrameEntity extends Entity {
if (itemData.getTag() != null) { if (itemData.getTag() != null) {
builder.put("tag", itemData.getTag().toBuilder().build()); builder.put("tag", itemData.getTag().toBuilder().build());
} }
builder.putShort("Damage", itemData.getDamage()); builder.putShort("Damage", (short) itemData.getDamage());
builder.putString("Name", itemEntry.getBedrockIdentifier()); builder.putString("Name", itemEntry.getBedrockIdentifier());
NbtMapBuilder tag = getDefaultTag().toBuilder(); NbtMapBuilder tag = getDefaultTag().toBuilder();
tag.put("Item", builder.build()); tag.put("Item", builder.build());

View File

@ -56,9 +56,12 @@ public class LlamaEntity extends ChestedHorseEntity {
// -1 means no armor // -1 means no armor
if ((int) entityMetadata.getValue() != -1) { if ((int) entityMetadata.getValue() != -1) {
// The damage value is the dye color that Java sends us // The damage value is the dye color that Java sends us
// Always going to be a carpet so we can hardcode 171 in BlockTranslator // The item is always going to be a carpet
// The int then short conversion is required or we get a ClassCastException equipmentPacket.setChestplate(ItemData.builder()
equipmentPacket.setChestplate(ItemData.of(BlockTranslator.CARPET, (short) ((int) entityMetadata.getValue()), 1)); .id(BlockTranslator.CARPET)
.damage((int) entityMetadata.getValue())
.count(1)
.build());
} else { } else {
equipmentPacket.setChestplate(ItemData.AIR); equipmentPacket.setChestplate(ItemData.AIR);
} }

View File

@ -101,6 +101,7 @@ public class GeyserItemStack {
public ItemData getItemData(GeyserSession session) { public ItemData getItemData(GeyserSession session) {
ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack()); ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack());
itemData.setNetId(getNetId()); itemData.setNetId(getNetId());
itemData.setUsingNetId(true); // Seems silly - this should probably be on the protocol level
return itemData; return itemData;
} }

View File

@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.v419.Bedrock_v419; import com.nukkitx.protocol.bedrock.v419.Bedrock_v419;
import com.nukkitx.protocol.bedrock.v422.Bedrock_v422; import com.nukkitx.protocol.bedrock.v422.Bedrock_v422;
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428; import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
import com.nukkitx.protocol.bedrock.v431.Bedrock_v431;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -55,6 +56,7 @@ public class BedrockProtocol {
.minecraftVersion("1.16.200/1.16.201") .minecraftVersion("1.16.200/1.16.201")
.build()); .build());
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC); SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC);
} }
/** /**

View File

@ -28,23 +28,32 @@ package org.geysermc.connector.network.translators.item;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
@ToString @ToString
public class ItemEntry { public class ItemEntry {
public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, false, 64); public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0,
BlockTranslator1_16_210.INSTANCE.getBedrockAirId(), 64);
private final String javaIdentifier; private final String javaIdentifier;
private final String bedrockIdentifier; private final String bedrockIdentifier;
private final int javaId; private final int javaId;
private final int bedrockId; private final int bedrockId;
private final int bedrockData; private final int bedrockData;
/**
private final boolean block; * The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered.
* Required since 1.16.220.
*/
private final int bedrockBlockId;
private final int stackSize; private final int stackSize;
public boolean isBlock() {
return bedrockBlockId != -1;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier())); return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier()));

View File

@ -42,6 +42,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.LanguageUtils;
@ -176,54 +177,64 @@ public class ItemRegistry {
} }
JsonNode stackSizeNode = entry.getValue().get("stack_size"); JsonNode stackSizeNode = entry.getValue().get("stack_size");
int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue(); int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue();
int bedrockBlockId = -1;
JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId");
if (blockRuntimeIdNode != null) {
bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue());
}
ItemEntry itemEntry;
if (entry.getValue().has("tool_type")) { if (entry.getValue().has("tool_type")) {
if (entry.getValue().has("tool_tier")) { if (entry.getValue().has("tool_tier")) {
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( itemEntry = new ToolItemEntry(
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("bedrock_data").intValue(),
entry.getValue().get("tool_type").textValue(), entry.getValue().get("tool_type").textValue(),
entry.getValue().get("tool_tier").textValue(), entry.getValue().get("tool_tier").textValue(),
entry.getValue().get("is_block").booleanValue(), bedrockBlockId,
stackSize)); stackSize);
} else { } else {
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( itemEntry = new ToolItemEntry(
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("bedrock_data").intValue(),
entry.getValue().get("tool_type").textValue(), entry.getValue().get("tool_type").textValue(),
"", entry.getValue().get("is_block").booleanValue(), "", bedrockBlockId,
stackSize)); stackSize);
} }
} else { } else {
ITEM_ENTRIES.put(itemIndex, new ItemEntry( itemEntry = new ItemEntry(
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("bedrock_data").intValue(),
entry.getValue().get("is_block").booleanValue(), bedrockBlockId,
stackSize)); stackSize);
} }
ITEM_ENTRIES.put(itemIndex, itemEntry);
switch (entry.getKey()) { switch (entry.getKey()) {
case "minecraft:barrier": case "minecraft:barrier":
BARRIER_INDEX = itemIndex; BARRIER_INDEX = itemIndex;
break; break;
case "minecraft:bamboo": case "minecraft:bamboo":
BAMBOO = ITEM_ENTRIES.get(itemIndex); BAMBOO = itemEntry;
break; break;
case "minecraft:egg": case "minecraft:egg":
EGG = ITEM_ENTRIES.get(itemIndex); EGG = itemEntry;
break; break;
case "minecraft:gold_ingot": case "minecraft:gold_ingot":
GOLD = ITEM_ENTRIES.get(itemIndex); GOLD = itemEntry;
break; break;
case "minecraft:shield": case "minecraft:shield":
SHIELD = ITEM_ENTRIES.get(itemIndex); SHIELD = itemEntry;
break; break;
case "minecraft:milk_bucket": case "minecraft:milk_bucket":
MILK_BUCKET = ITEM_ENTRIES.get(itemIndex); MILK_BUCKET = itemEntry;
break; break;
case "minecraft:wheat": case "minecraft:wheat":
WHEAT = ITEM_ENTRIES.get(itemIndex); WHEAT = itemEntry;
break; break;
case "minecraft:writable_book": case "minecraft:writable_book":
WRITABLE_BOOK = ITEM_ENTRIES.get(itemIndex); WRITABLE_BOOK = itemEntry;
break; break;
default: default:
break; break;
@ -249,7 +260,7 @@ public class ItemRegistry {
// Add the loadstone compass since it doesn't exist on java but we need it for item conversion // Add the loadstone compass since it doesn't exist on java but we need it for item conversion
ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex, ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex,
lodestoneCompassId, 0, false, 1)); lodestoneCompassId, 0, -1, 1));
/* Load creative items */ /* Load creative items */
stream = FileUtils.getResource("bedrock/creative_items.json"); stream = FileUtils.getResource("bedrock/creative_items.json");
@ -261,11 +272,24 @@ public class ItemRegistry {
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
} }
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
"minecraft:knowledge_book", "minecraft:tipped_arrow");
if (!usingFurnaceMinecart) {
javaOnlyItems.add("minecraft:furnace_minecart");
}
JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems);
int netId = 1; int netId = 1;
List<ItemData> creativeItems = new ArrayList<>(); List<ItemData> creativeItems = new ArrayList<>();
for (JsonNode itemNode : creativeItemEntries) { for (JsonNode itemNode : creativeItemEntries) {
ItemData item = getBedrockItemFromJson(itemNode); ItemData.Builder item = getBedrockItemFromJson(itemNode);
creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag())); int bedrockRuntimeId = 0;
ItemEntry itemEntry = getItem(item.build()); // please
if (itemEntry.isBlock()) {
bedrockRuntimeId = itemEntry.getBedrockBlockId();
}
creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build());
} }
if (usingFurnaceMinecart) { if (usingFurnaceMinecart) {
@ -274,8 +298,11 @@ public class ItemRegistry {
ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true)); ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true));
ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId, ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId,
furnaceMinecartId, 0, false, 1)); furnaceMinecartId, 0, -1, 1));
creativeItems.add(ItemData.fromNet(netId, furnaceMinecartId, (short) 0, 1, null)); creativeItems.add(ItemData.builder()
.netId(netId)
.id(furnaceMinecartId)
.count(1).build());
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.putString("name", "geysermc:furnace_minecart") builder.putString("name", "geysermc:furnace_minecart")
@ -312,14 +339,6 @@ public class ItemRegistry {
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]); CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
ITEM_NAMES = itemNames.toArray(new String[0]); ITEM_NAMES = itemNames.toArray(new String[0]);
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
"minecraft:knowledge_book", "minecraft:tipped_arrow");
if (!usingFurnaceMinecart) {
javaOnlyItems.add("minecraft:furnace_minecart");
}
JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems);
} }
/** /**
@ -376,11 +395,11 @@ public class ItemRegistry {
} }
/** /**
* Gets a Bedrock {@link ItemData} from a {@link JsonNode} * Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode}
* @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data * @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data
* @return * @return
*/ */
public static ItemData getBedrockItemFromJson(JsonNode itemNode) { public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) {
int count = 1; int count = 1;
short damage = 0; short damage = 0;
NbtMap tag = null; NbtMap tag = null;
@ -399,6 +418,10 @@ public class ItemRegistry {
e.printStackTrace(); e.printStackTrace();
} }
} }
return ItemData.of(itemNode.get("id").asInt(), damage, count, tag); return ItemData.builder()
.id(itemNode.get("id").asInt())
.damage(damage)
.count(count)
.tag(tag);
} }
} }

View File

@ -149,12 +149,15 @@ public abstract class ItemTranslator {
translateDisplayProperties(session, nbt); translateDisplayProperties(session, nbt);
ItemData itemData; ItemData.Builder builder;
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId()); ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
if (itemStackTranslator != null) { if (itemStackTranslator != null) {
itemData = itemStackTranslator.translateToBedrock(itemStack, bedrockItem); builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
} else { } else {
itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); builder = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem);
}
if (bedrockItem.isBlock()) {
builder.blockRuntimeId(bedrockItem.getBedrockBlockId());
} }
if (nbt != null) { if (nbt != null) {
@ -165,10 +168,11 @@ public abstract class ItemTranslator {
String[] canPlace = new String[0]; String[] canPlace = new String[0];
canBreak = getCanModify(session, canDestroy, canBreak); canBreak = getCanModify(session, canDestroy, canBreak);
canPlace = getCanModify(session, canPlaceOn, canPlace); canPlace = getCanModify(session, canPlaceOn, canPlace);
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak); builder.canBreak(canBreak);
builder.canPlace(canPlace);
} }
return itemData; return builder.build();
} }
/** /**
@ -202,14 +206,19 @@ public abstract class ItemTranslator {
} }
}; };
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack == null) { if (itemStack == null) {
return ItemData.AIR; // Return, essentially, air
return ItemData.builder();
} }
if (itemStack.getNbt() == null) { ItemData.Builder builder = ItemData.builder()
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount()); .id(itemEntry.getBedrockId())
.damage(itemEntry.getBedrockData())
.count(itemStack.getAmount());
if (itemStack.getNbt() != null) {
builder.tag(this.translateNbtToBedrock(itemStack.getNbt()));
} }
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt())); return builder;
} }
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {

View File

@ -91,7 +91,7 @@ public enum Potion {
return null; return null;
} }
public static Potion getByBedrockId(short bedrockId) { public static Potion getByBedrockId(int bedrockId) {
for (Potion potion : Potion.values()) { for (Potion potion : Potion.values()) {
if (potion.bedrockId == bedrockId) { if (potion.bedrockId == bedrockId) {
return potion; return potion;

View File

@ -272,7 +272,11 @@ public class RecipeRegistry {
e.printStackTrace(); e.printStackTrace();
} }
} }
return ItemData.of(itemEntry.getBedrockId(), damage, count, tag); return ItemData.builder()
.id(itemEntry.getBedrockId())
.damage(damage)
.count(count)
.tag(tag).build();
} }
public static void init() { public static void init() {

View File

@ -100,7 +100,7 @@ public enum TippedArrowPotion {
return null; return null;
} }
public static TippedArrowPotion getByBedrockId(short bedrockId) { public static TippedArrowPotion getByBedrockId(int bedrockId) {
for (TippedArrowPotion potion : TippedArrowPotion.values()) { for (TippedArrowPotion potion : TippedArrowPotion.values()) {
if (potion.bedrockId == bedrockId) { if (potion.bedrockId == bedrockId) {
return potion; return potion;

View File

@ -32,8 +32,9 @@ public class ToolItemEntry extends ItemEntry {
private final String toolType; private final String toolType;
private final String toolTier; private final String toolTier;
public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier, boolean isBlock, int stackSize) { public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData,
super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, isBlock, stackSize); String toolType, String toolTier, int bedrockBlockId, int stackSize) {
super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, bedrockBlockId, stackSize);
this.toolType = toolType; this.toolType = toolType;
this.toolTier = toolTier; this.toolTier = toolTier;
} }

View File

@ -153,30 +153,30 @@ public class BannerTranslator extends ItemTranslator {
} }
@Override @Override
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack.getNbt() == null) { if (itemStack.getNbt() == null) {
return super.translateToBedrock(itemStack, itemEntry); return super.translateToBedrock(itemStack, itemEntry);
} }
ItemData itemData = super.translateToBedrock(itemStack, itemEntry); ItemData.Builder builder = super.translateToBedrock(itemStack, itemEntry);
CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag"); CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag");
if (blockEntityTag != null && blockEntityTag.contains("Patterns")) { if (blockEntityTag != null && blockEntityTag.contains("Patterns")) {
ListTag patterns = blockEntityTag.get("Patterns"); ListTag patterns = blockEntityTag.get("Patterns");
NbtMapBuilder builder = itemData.getTag().toBuilder(); NbtMapBuilder nbtBuilder = builder.build().getTag().toBuilder(); //TODO fix ugly hack
if (patterns.equals(OMINOUS_BANNER_PATTERN)) { if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
// Remove the current patterns and set the ominous banner type // Remove the current patterns and set the ominous banner type
builder.remove("Patterns"); nbtBuilder.remove("Patterns");
builder.putInt("Type", 1); nbtBuilder.putInt("Type", 1);
} else { } else {
builder.put("Patterns", convertBannerPattern(patterns)); nbtBuilder.put("Patterns", convertBannerPattern(patterns));
} }
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); builder.tag(nbtBuilder.build());
} }
return itemData; return builder;
} }
@Override @Override

View File

@ -47,7 +47,7 @@ public class CompassTranslator extends ItemTranslator {
} }
@Override @Override
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked"); Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked");
@ -75,9 +75,7 @@ public class CompassTranslator extends ItemTranslator {
} }
} }
ItemData itemData = super.translateToBedrock(itemStack, itemEntry); return super.translateToBedrock(itemStack, itemEntry);
return itemData;
} }
@Override @Override

View File

@ -49,13 +49,17 @@ public class PotionTranslator extends ItemTranslator {
} }
@Override @Override
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
Tag potionTag = itemStack.getNbt().get("Potion"); Tag potionTag = itemStack.getNbt().get("Potion");
if (potionTag instanceof StringTag) { if (potionTag instanceof StringTag) {
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue()); Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
if (potion != null) { if (potion != null) {
return ItemData.of(itemEntry.getBedrockId(), potion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); return ItemData.builder()
.id(itemEntry.getBedrockId())
.damage(potion.getBedrockId())
.count(itemStack.getAmount())
.tag(translateNbtToBedrock(itemStack.getNbt()));
} }
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue()); GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue());
} }

View File

@ -52,7 +52,7 @@ public class TippedArrowTranslator extends ItemTranslator {
} }
@Override @Override
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) { if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) {
// We're only concerned about minecraft:arrow when translating Bedrock -> Java // We're only concerned about minecraft:arrow when translating Bedrock -> Java
return super.translateToBedrock(itemStack, itemEntry); return super.translateToBedrock(itemStack, itemEntry);
@ -61,7 +61,11 @@ public class TippedArrowTranslator extends ItemTranslator {
if (potionTag instanceof StringTag) { if (potionTag instanceof StringTag) {
TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue()); TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue());
if (tippedArrowPotion != null) { if (tippedArrowPotion != null) {
return ItemData.of(itemEntry.getBedrockId(), tippedArrowPotion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt())); return ItemData.builder()
.id(itemEntry.getBedrockId())
.damage(tippedArrowPotion.getBedrockId())
.count(itemStack.getAmount())
.tag(translateNbtToBedrock(itemStack.getNbt()));
} }
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue()); GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue());
} }

View File

@ -55,7 +55,7 @@ public class CrossbowTranslator extends NbtItemStackTranslator {
newProjectile.put(new ByteTag("Count", (byte) itemData.getCount())); newProjectile.put(new ByteTag("Count", (byte) itemData.getCount()));
newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier())); newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier()));
newProjectile.put(new ShortTag("Damage", itemData.getDamage())); newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage()));
itemTag.put(newProjectile); itemTag.put(newProjectile);
} }

View File

@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.command.CommandParser;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket;
import com.nukkitx.protocol.bedrock.data.command.CommandData; import com.nukkitx.protocol.bedrock.data.command.CommandData;
import com.nukkitx.protocol.bedrock.data.command.CommandEnumData; import com.nukkitx.protocol.bedrock.data.command.CommandEnumData;
import com.nukkitx.protocol.bedrock.data.command.CommandParam;
import com.nukkitx.protocol.bedrock.data.command.CommandParamData; import com.nukkitx.protocol.bedrock.data.command.CommandParamData;
import com.nukkitx.protocol.bedrock.data.command.CommandParamType;
import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket;
import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@ -200,47 +200,47 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
*/ */
private static Object mapCommandType(CommandParser parser) { private static Object mapCommandType(CommandParser parser) {
if (parser == null) { if (parser == null) {
return CommandParamType.STRING; return CommandParam.STRING;
} }
switch (parser) { switch (parser) {
case FLOAT: case FLOAT:
case ROTATION: case ROTATION:
case DOUBLE: case DOUBLE:
return CommandParamType.FLOAT; return CommandParam.FLOAT;
case INTEGER: case INTEGER:
return CommandParamType.INT; return CommandParam.INT;
case ENTITY: case ENTITY:
case GAME_PROFILE: case GAME_PROFILE:
return CommandParamType.TARGET; return CommandParam.TARGET;
case BLOCK_POS: case BLOCK_POS:
return CommandParamType.BLOCK_POSITION; return CommandParam.BLOCK_POSITION;
case COLUMN_POS: case COLUMN_POS:
case VEC3: case VEC3:
return CommandParamType.POSITION; return CommandParam.POSITION;
case MESSAGE: case MESSAGE:
return CommandParamType.MESSAGE; return CommandParam.MESSAGE;
case NBT: case NBT:
case NBT_COMPOUND_TAG: case NBT_COMPOUND_TAG:
case NBT_TAG: case NBT_TAG:
case NBT_PATH: case NBT_PATH:
return CommandParamType.JSON; return CommandParam.JSON;
case RESOURCE_LOCATION: case RESOURCE_LOCATION:
case FUNCTION: case FUNCTION:
return CommandParamType.FILE_PATH; return CommandParam.FILE_PATH;
case BOOL: case BOOL:
return ENUM_BOOLEAN; return ENUM_BOOLEAN;
case OPERATION: // ">=", "==", etc case OPERATION: // ">=", "==", etc
return CommandParamType.OPERATOR; return CommandParam.OPERATOR;
case BLOCK_STATE: case BLOCK_STATE:
return BlockTranslator.getAllBlockIdentifiers(); return BlockTranslator.getAllBlockIdentifiers();
@ -261,7 +261,7 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
return VALID_SCOREBOARD_SLOTS; return VALID_SCOREBOARD_SLOTS;
default: default:
return CommandParamType.STRING; return CommandParam.STRING;
} }
} }
@ -324,11 +324,11 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
// Put the non-enum param into the list // Put the non-enum param into the list
Object mappedType = mapCommandType(paramNode.getParser()); Object mappedType = mapCommandType(paramNode.getParser());
CommandEnumData enumData = null; CommandEnumData enumData = null;
CommandParamType type = null; CommandParam type = null;
if (mappedType instanceof String[]) { if (mappedType instanceof String[]) {
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false); enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false);
} else { } else {
type = (CommandParamType) mappedType; type = (CommandParam) mappedType;
} }
// IF enumData != null: // IF enumData != null:
// In game, this will show up like <paramNode.getName(): enumData.getName()> // In game, this will show up like <paramNode.getName(): enumData.getName()>

View File

@ -69,7 +69,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData(); ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData();
ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult()); ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult());
// Strip NBT - tools won't appear in the recipe book otherwise // Strip NBT - tools won't appear in the recipe book otherwise
output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); output = output.toBuilder().tag(null).build();
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients()); ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
for (ItemData[] inputs : inputCombinations) { for (ItemData[] inputs : inputCombinations) {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
@ -83,7 +83,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData();
ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult()); ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult());
// See above // See above
output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); output = output.toBuilder().tag(null).build();
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients()); ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
for (ItemData[] inputs : inputCombinations) { for (ItemData[] inputs : inputCombinations) {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
@ -230,7 +230,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
if (entry.getValue().size() < idCount) { if (entry.getValue().size() < idCount) {
optionSet.addAll(entry.getValue()); optionSet.addAll(entry.getValue());
} else { } else {
optionSet.add(ItemData.of(groupedItem.id, Short.MAX_VALUE, groupedItem.count, groupedItem.tag)); optionSet.add(ItemData.builder()
.id(groupedItem.id)
.damage(Short.MAX_VALUE)
.count(groupedItem.count)
.tag(groupedItem.tag).build());
} }
} else { } else {
ItemData item = entry.getValue().get(0); ItemData item = entry.getValue().get(0);

View File

@ -68,7 +68,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack(); ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack();
ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem); ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem);
int id = bedrockItem.getId(); int id = bedrockItem.getId();
short damage = bedrockItem.getDamage(); int damage = bedrockItem.getDamage();
particle.setType(LevelEventType.PARTICLE_ITEM_BREAK); particle.setType(LevelEventType.PARTICLE_ITEM_BREAK);
particle.setData(id << 16 | damage); particle.setData(id << 16 | damage);
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));

View File

@ -140,7 +140,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1))); builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1)));
builder.putShort("Damage", itemData.getDamage()); builder.putShort("Damage", (short) itemData.getDamage());
builder.putString("Name", itemEntry.getBedrockIdentifier()); builder.putString("Name", itemEntry.getBedrockIdentifier());
if (itemData.getTag() != null) { if (itemData.getTag() != null) {
NbtMap tag = itemData.getTag().toBuilder().build(); NbtMap tag = itemData.getTag().toBuilder().build();

View File

@ -164,7 +164,10 @@ public class InventoryUtils {
display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description)); display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description));
root.put("display", display.build()); root.put("display", display.build());
return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.build()); return ItemData.builder()
.id(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId())
.count(1)
.tag(root.build()).build();
} }
/** /**

@ -1 +1 @@
Subproject commit 2ce794e21a0212865059e7551db893c28843620a Subproject commit c846b8200eb8ebb37207666f7eddb83f2b636c37

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.geysermc</groupId> <groupId>org.geysermc</groupId>
<artifactId>geyser-parent</artifactId> <artifactId>geyser-parent</artifactId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.1-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Geyser</name> <name>Geyser</name>
<description>Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.</description> <description>Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.</description>