3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-10-03 08:21:06 +02:00

Address requests

Dieser Commit ist enthalten in:
Camotoy 2021-03-08 16:57:31 -05:00
Ursprung d19bf07b7a
Commit da11cd298c
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
10 geänderte Dateien mit 41 neuen und 17 gelöschten Zeilen

Datei anzeigen

@ -205,7 +205,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
if (isPre1_12) { if (isPre1_12) {
// Register events needed to send all recipes to the client // Register events needed to send all recipes to the client
Bukkit.getServer().getPluginManager().registerEvents(new GeyserSpigot1_11CraftingListener(this, connector), this); Bukkit.getServer().getPluginManager().registerEvents(new GeyserSpigot1_11CraftingListener(connector), this);
} }
this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector)); this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector));

Datei anzeigen

@ -45,7 +45,6 @@ import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.item.RecipeRegistry; import org.geysermc.connector.network.translators.item.RecipeRegistry;
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.MappingData; import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.protocol.Protocol;
@ -70,14 +69,12 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
* The list of all protocols from the client's version to 1.13. * The list of all protocols from the client's version to 1.13.
*/ */
private final List<Pair<Integer, Protocol>> protocolList; private final List<Pair<Integer, Protocol>> protocolList;
private final ProtocolVersion version;
public GeyserSpigot1_11CraftingListener(GeyserSpigotPlugin plugin, GeyserConnector connector) { public GeyserSpigot1_11CraftingListener(GeyserConnector connector) {
this.connector = connector; this.connector = connector;
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData(); this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
this.protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION, this.protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
ProtocolVersion.v1_13.getVersion()); ProtocolVersion.v1_13.getVersion());
this.version = plugin.getServerProtocolVersion();
} }
@EventHandler @EventHandler
@ -101,13 +98,16 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
craftingDataPacket.setCleanRecipes(true); craftingDataPacket.setCleanRecipes(true);
Iterator<Recipe> recipeIterator = Bukkit.getServer().recipeIterator(); Iterator<Recipe> recipeIterator = Bukkit.getServer().recipeIterator();
while (recipeIterator.hasNext()) { while (recipeIterator.hasNext()) {
Recipe recipe = recipeIterator.next(); Recipe recipe = recipeIterator.next();
Pair<ItemStack, ItemData> outputs = translateToBedrock(session, recipe.getResult()); Pair<ItemStack, ItemData> outputs = translateToBedrock(session, recipe.getResult());
ItemStack javaOutput = outputs.getKey(); ItemStack javaOutput = outputs.getKey();
ItemData output = outputs.getValue(); ItemData output = outputs.getValue();
if (output.getId() == 0) continue; // If items make air we don't want that if (output.getId() == 0) continue; // If items make air we don't want that
boolean isNotAllAir = false; // Check for all-air recipes boolean isNotAllAir = false; // Check for all-air recipes
if (recipe instanceof ShapedRecipe) { if (recipe instanceof ShapedRecipe) {
ShapedRecipe shapedRecipe = (ShapedRecipe) recipe; ShapedRecipe shapedRecipe = (ShapedRecipe) recipe;
@ -119,8 +119,9 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
Pair<ItemStack, ItemData> result = translateToBedrock(session, shapedRecipe.getIngredientMap().get((char) ('a' + i))); Pair<ItemStack, ItemData> result = translateToBedrock(session, shapedRecipe.getIngredientMap().get((char) ('a' + i)));
ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()}); ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()});
input[i] = result.getValue(); input[i] = result.getValue();
isNotAllAir = isNotAllAir || input[i].getId() != 0; isNotAllAir |= input[i].getId() != 0;
} }
if (!isNotAllAir) continue; if (!isNotAllAir) continue;
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
// Add recipe to our internal cache // Add recipe to our internal cache
@ -128,6 +129,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
"", ingredients, javaOutput); "", ingredients, javaOutput);
session.getCraftingRecipes().put(netId, session.getCraftingRecipes().put(netId,
new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPED, uuid.toString(), data)); new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPED, uuid.toString(), data));
// Add recipe for Bedrock // Add recipe for Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(), craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(),
shapedRecipe.getShape()[0].length(), shapedRecipe.getShape().length, Arrays.asList(input), shapedRecipe.getShape()[0].length(), shapedRecipe.getShape().length, Arrays.asList(input),
@ -136,18 +138,21 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe; ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe;
Ingredient[] ingredients = new Ingredient[shapelessRecipe.getIngredientList().size()]; Ingredient[] ingredients = new Ingredient[shapelessRecipe.getIngredientList().size()];
ItemData[] input = new ItemData[shapelessRecipe.getIngredientList().size()]; ItemData[] input = new ItemData[shapelessRecipe.getIngredientList().size()];
for (int i = 0; i < input.length; i++) { for (int i = 0; i < input.length; i++) {
Pair<ItemStack, ItemData> result = translateToBedrock(session, shapelessRecipe.getIngredientList().get(i)); Pair<ItemStack, ItemData> result = translateToBedrock(session, shapelessRecipe.getIngredientList().get(i));
ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()}); ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()});
input[i] = result.getValue(); input[i] = result.getValue();
isNotAllAir = isNotAllAir || input[i].getId() != 0; isNotAllAir |= input[i].getId() != 0;
} }
if (!isNotAllAir) continue; if (!isNotAllAir) continue;
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
// Add recipe to our internal cache // Add recipe to our internal cache
ShapelessRecipeData data = new ShapelessRecipeData("", ingredients, javaOutput); ShapelessRecipeData data = new ShapelessRecipeData("", ingredients, javaOutput);
session.getCraftingRecipes().put(netId, session.getCraftingRecipes().put(netId,
new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPELESS, uuid.toString(), data)); new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPELESS, uuid.toString(), data));
// Add recipe for Bedrock // Add recipe for Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(), craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
Arrays.asList(input), Collections.singletonList(output), uuid, "crafting_table", 0, netId++)); Arrays.asList(input), Collections.singletonList(output), uuid, "crafting_table", 0, netId++));
@ -163,10 +168,13 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
if (itemStack.getType().getId() == 0) { if (itemStack.getType().getId() == 0) {
return new Pair<>(null, ItemData.AIR); return new Pair<>(null, ItemData.AIR);
} }
int legacyId = (itemStack.getType().getId() << 4) | (itemStack.getData().getData() & 0xFFFF); int legacyId = (itemStack.getType().getId() << 4) | (itemStack.getData().getData() & 0xFFFF);
if (itemStack.getType().getId() == 355 && itemStack.getData().getData() == (byte) 0) { // Handle bed color since the server will always be pre-1.12 if (itemStack.getType().getId() == 355 && itemStack.getData().getData() == (byte) 0) { // Handle bed color since the server will always be pre-1.12
legacyId = (itemStack.getType().getId() << 4) | ((byte) 14 & 0xFFFF); legacyId = (itemStack.getType().getId() << 4) | ((byte) 14 & 0xFFFF);
} }
// old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 and so on // old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 and so on
int itemId; int itemId;
if (mappingData1_12to1_13.getItemMappings().containsKey(legacyId)) { if (mappingData1_12to1_13.getItemMappings().containsKey(legacyId)) {
@ -189,6 +197,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
ItemData finalData = ItemTranslator.translateToBedrock(session, mcItemStack); ItemData finalData = ItemTranslator.translateToBedrock(session, mcItemStack);
return new Pair<>(mcItemStack, finalData); return new Pair<>(mcItemStack, finalData);
} }
// Empty slot, most likely // Empty slot, most likely
return new Pair<>(null, ItemData.AIR); return new Pair<>(null, ItemData.AIR);
} }

Datei anzeigen

@ -48,7 +48,6 @@ import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.entity.CommandBlockMinecartEntity; import org.geysermc.connector.entity.CommandBlockMinecartEntity;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.ItemFrameEntity; import org.geysermc.connector.entity.ItemFrameEntity;
import org.geysermc.connector.entity.living.merchant.AbstractMerchantEntity;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.inventory.GeyserItemStack; import org.geysermc.connector.inventory.GeyserItemStack;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -87,10 +86,10 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
if (worldAction.getSource().getType() == InventorySource.Type.WORLD_INTERACTION if (worldAction.getSource().getType() == InventorySource.Type.WORLD_INTERACTION
&& worldAction.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) { && worldAction.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) {
session.addInventoryTask(() -> { session.addInventoryTask(() -> {
if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot()) if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot() ||
return; session.getPlayerInventory().getItemInHand().isEmpty()) {
if (session.getPlayerInventory().getItemInHand().isEmpty())
return; return;
}
boolean dropAll = worldAction.getToItem().getCount() > 1; boolean dropAll = worldAction.getToItem().getCount() > 1;
ClientPlayerActionPacket dropAllPacket = new ClientPlayerActionPacket( ClientPlayerActionPacket dropAllPacket = new ClientPlayerActionPacket(

Datei anzeigen

@ -103,6 +103,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator {
Vector3i position = session.getLastInteractionBlockPosition(); Vector3i position = session.getLastInteractionBlockPosition();
// shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet // shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet
boolean shouldRefresh = !session.getConnector().getWorldManager().shouldExpectLecternHandled() && !session.getLecternCache().contains(position); boolean shouldRefresh = !session.getConnector().getWorldManager().shouldExpectLecternHandled() && !session.getLecternCache().contains(position);
NbtMap blockEntityTag; NbtMap blockEntityTag;
if (tag != null) { if (tag != null) {
int pagesSize = ((ListTag) tag.get("pages")).size(); int pagesSize = ((ListTag) tag.get("pages")).size();
@ -132,6 +133,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator {
blockEntityTag = lecternTag.putCompound("book", bookTag.build()).build(); blockEntityTag = lecternTag.putCompound("book", bookTag.build()).build();
} }
// Even with serverside access to lecterns, we don't easily know which lectern this is, so we need to rebuild // Even with serverside access to lecterns, we don't easily know which lectern this is, so we need to rebuild
// the block entity tag // the block entity tag
lecternContainer.setBlockEntityTag(blockEntityTag); lecternContainer.setBlockEntityTag(blockEntityTag);

Datei anzeigen

@ -128,6 +128,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
return rejectRequest(request); return rejectRequest(request);
} }
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data; CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
// Get the patterns compound tag // Get the patterns compound tag
List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND); List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list // Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
@ -151,6 +152,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
} }
CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag"); CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag");
CompoundTag javaBannerPattern = BannerTranslator.getJavaBannerPattern(pattern); CompoundTag javaBannerPattern = BannerTranslator.getJavaBannerPattern(pattern);
if (blockEntityTag != null) { if (blockEntityTag != null) {
ListTag patternsList = blockEntityTag.get("Patterns"); ListTag patternsList = blockEntityTag.get("Patterns");
if (patternsList != null) { if (patternsList != null) {
@ -165,6 +167,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
blockEntityTag.put(patternsList); blockEntityTag.put(patternsList);
inputCopy.getNbt().put(blockEntityTag); inputCopy.getNbt().put(blockEntityTag);
} }
// Set the new item as the output // Set the new item as the output
inventory.setItem(3, inputCopy, session); inventory.setItem(3, inputCopy, session);

Datei anzeigen

@ -107,7 +107,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
if (session.getGameMode() == GameMode.CREATIVE) { if (session.getGameMode() == GameMode.CREATIVE) {
slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK); slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK);
}else{ } else {
slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(i).getItemStack())); slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(i).getItemStack()));
} }

Datei anzeigen

@ -65,6 +65,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
return rejectRequest(request); return rejectRequest(request);
} }
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data; CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
StonecutterContainer container = (StonecutterContainer) inventory; StonecutterContainer container = (StonecutterContainer) inventory;
// Get the ID of the item we are cutting // Get the ID of the item we are cutting
int id = inventory.getItem(0).getJavaId(); int id = inventory.getItem(0).getJavaId();
@ -73,6 +74,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
if (results == null) { if (results == null) {
return rejectRequest(request); return rejectRequest(request);
} }
ItemStack javaOutput = ItemTranslator.translateToJava(craftData.getResultItems()[0]); ItemStack javaOutput = ItemTranslator.translateToJava(craftData.getResultItems()[0]);
int button = results.indexOf(javaOutput.getId()); int button = results.indexOf(javaOutput.getId());
// If we've already pressed the button with this item, no need to press it again! // If we've already pressed the button with this item, no need to press it again!
@ -86,6 +88,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
inventory.setItem(1, GeyserItemStack.from(javaOutput), session); inventory.setItem(1, GeyserItemStack.from(javaOutput), session);
} }
} }
return translateRequest(session, inventory, request); return translateRequest(session, inventory, request);
} }

Datei anzeigen

@ -163,10 +163,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
Int2ObjectMap<IntList> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>(); Int2ObjectMap<IntList> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
for (Int2ObjectMap.Entry<List<StoneCuttingRecipeData>> data : unsortedStonecutterData.int2ObjectEntrySet()) { for (Int2ObjectMap.Entry<List<StoneCuttingRecipeData>> data : unsortedStonecutterData.int2ObjectEntrySet()) {
data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData ->
// Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore // Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore
// We can get the correct order for button pressing // We can get the correct order for button pressing
data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData ->
ItemRegistry.getItem(stoneCuttingRecipeData.getResult()).getJavaIdentifier()))); ItemRegistry.getItem(stoneCuttingRecipeData.getResult()).getJavaIdentifier())));
// Now that it's sorted, let's translate these recipes // Now that it's sorted, let's translate these recipes
for (StoneCuttingRecipeData stoneCuttingData : data.getValue()) { for (StoneCuttingRecipeData stoneCuttingData : data.getValue()) {
// As of 1.16.4, all stonecutter recipes have one ingredient option // As of 1.16.4, all stonecutter recipes have one ingredient option
@ -174,9 +175,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
ItemData input = ItemTranslator.translateToBedrock(session, ingredient); ItemData input = ItemTranslator.translateToBedrock(session, ingredient);
ItemData output = ItemTranslator.translateToBedrock(session, stoneCuttingData.getResult()); ItemData output = ItemTranslator.translateToBedrock(session, stoneCuttingData.getResult());
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
// We need to register stonecutting recipes so they show up on Bedrock // We need to register stonecutting recipes so they show up on Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(), craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
Collections.singletonList(input), Collections.singletonList(output), uuid, "stonecutter", 0, netId++)); Collections.singletonList(input), Collections.singletonList(output), uuid, "stonecutter", 0, netId++));
// Save the recipe list for reference when crafting // Save the recipe list for reference when crafting
IntList outputs = stonecutterRecipeMap.get(ingredient.getId()); IntList outputs = stonecutterRecipeMap.get(ingredient.getId());
if (outputs == null) { if (outputs == null) {

Datei anzeigen

@ -155,9 +155,8 @@ public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket>
} }
} }
if (Arrays.equals(ingredients, mirroredIngredients)) { if (Arrays.equals(ingredients, mirroredIngredients) ||
continue; !testShapedRecipe(mirroredIngredients, inventory, gridDimensions, firstRow, height, firstCol, width)) {
} else if (!testShapedRecipe(mirroredIngredients, inventory, gridDimensions, firstRow, height, firstCol, width)) {
continue; continue;
} }
} }

Datei anzeigen

@ -77,6 +77,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
updateTradePacket.setUsingEconomyTrade(true); updateTradePacket.setUsingEconomyTrade(true);
updateTradePacket.setPlayerUniqueEntityId(session.getPlayerEntity().getGeyserId()); updateTradePacket.setPlayerUniqueEntityId(session.getPlayerEntity().getGeyserId());
updateTradePacket.setTraderUniqueEntityId(villager.getGeyserId()); updateTradePacket.setTraderUniqueEntityId(villager.getGeyserId());
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
boolean addExtraTrade = packet.isRegularVillager() && packet.getVillagerLevel() < 5; boolean addExtraTrade = packet.isRegularVillager() && packet.getVillagerLevel() < 5;
List<NbtMap> tags = new ArrayList<>(addExtraTrade ? packet.getTrades().length + 1 : packet.getTrades().length); List<NbtMap> tags = new ArrayList<>(addExtraTrade ? packet.getTrades().length + 1 : packet.getTrades().length);
@ -119,6 +120,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
} }
builder.putList("Recipes", NbtType.COMPOUND, tags); builder.putList("Recipes", NbtType.COMPOUND, tags);
List<NbtMap> expTags = new ArrayList<>(5); List<NbtMap> expTags = new ArrayList<>(5);
expTags.add(NbtMap.builder().putInt("0", 0).build()); expTags.add(NbtMap.builder().putInt("0", 0).build());
expTags.add(NbtMap.builder().putInt("1", 10).build()); expTags.add(NbtMap.builder().putInt("1", 10).build());
@ -126,6 +128,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
expTags.add(NbtMap.builder().putInt("3", 150).build()); expTags.add(NbtMap.builder().putInt("3", 150).build());
expTags.add(NbtMap.builder().putInt("4", 250).build()); expTags.add(NbtMap.builder().putInt("4", 250).build());
builder.putList("TierExpRequirements", NbtType.COMPOUND, expTags); builder.putList("TierExpRequirements", NbtType.COMPOUND, expTags);
updateTradePacket.setOffers(builder.build()); updateTradePacket.setOffers(builder.build());
session.sendUpstreamPacket(updateTradePacket); session.sendUpstreamPacket(updateTradePacket);
} }
@ -133,6 +136,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
private NbtMap getItemTag(GeyserSession session, ItemStack stack, int specialPrice) { private NbtMap getItemTag(GeyserSession session, ItemStack stack, int specialPrice) {
ItemData itemData = ItemTranslator.translateToBedrock(session, stack); ItemData itemData = ItemTranslator.translateToBedrock(session, stack);
ItemEntry itemEntry = ItemRegistry.getItem(stack); ItemEntry itemEntry = ItemRegistry.getItem(stack);
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", itemData.getDamage());
@ -141,12 +145,14 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
NbtMap tag = itemData.getTag().toBuilder().build(); NbtMap tag = itemData.getTag().toBuilder().build();
builder.put("tag", tag); builder.put("tag", tag);
} }
NbtMap blockTag = BlockTranslator.getBedrockBlockNbt(itemEntry.getJavaIdentifier()); NbtMap blockTag = BlockTranslator.getBedrockBlockNbt(itemEntry.getJavaIdentifier());
if (blockTag != null) { if (blockTag != null) {
// This fixes certain blocks being unable to stack after grabbing one // This fixes certain blocks being unable to stack after grabbing one
builder.putCompound("Block", blockTag); builder.putCompound("Block", blockTag);
builder.putShort("Damage", (short) 0); builder.putShort("Damage", (short) 0);
} }
return builder.build(); return builder.build();
} }
} }