Address requests

This commit is contained in:
Camotoy 2021-03-08 16:57:31 -05:00
parent d19bf07b7a
commit da11cd298c
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
10 changed files with 41 additions and 17 deletions

View file

@ -205,7 +205,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
if (isPre1_12) {
// 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));

View file

@ -45,7 +45,6 @@ import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemTranslator;
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.data.MappingData;
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.
*/
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.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
this.protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
ProtocolVersion.v1_13.getVersion());
this.version = plugin.getServerProtocolVersion();
}
@EventHandler
@ -101,13 +98,16 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
craftingDataPacket.setCleanRecipes(true);
Iterator<Recipe> recipeIterator = Bukkit.getServer().recipeIterator();
while (recipeIterator.hasNext()) {
Recipe recipe = recipeIterator.next();
Pair<ItemStack, ItemData> outputs = translateToBedrock(session, recipe.getResult());
ItemStack javaOutput = outputs.getKey();
ItemData output = outputs.getValue();
if (output.getId() == 0) continue; // If items make air we don't want that
boolean isNotAllAir = false; // Check for all-air recipes
if (recipe instanceof ShapedRecipe) {
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)));
ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()});
input[i] = result.getValue();
isNotAllAir = isNotAllAir || input[i].getId() != 0;
isNotAllAir |= input[i].getId() != 0;
}
if (!isNotAllAir) continue;
UUID uuid = UUID.randomUUID();
// Add recipe to our internal cache
@ -128,6 +129,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
"", ingredients, javaOutput);
session.getCraftingRecipes().put(netId,
new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPED, uuid.toString(), data));
// Add recipe for Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShaped(uuid.toString(),
shapedRecipe.getShape()[0].length(), shapedRecipe.getShape().length, Arrays.asList(input),
@ -136,18 +138,21 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe;
Ingredient[] ingredients = new Ingredient[shapelessRecipe.getIngredientList().size()];
ItemData[] input = new ItemData[shapelessRecipe.getIngredientList().size()];
for (int i = 0; i < input.length; i++) {
Pair<ItemStack, ItemData> result = translateToBedrock(session, shapelessRecipe.getIngredientList().get(i));
ingredients[i] = new Ingredient(new ItemStack[]{result.getKey()});
input[i] = result.getValue();
isNotAllAir = isNotAllAir || input[i].getId() != 0;
isNotAllAir |= input[i].getId() != 0;
}
if (!isNotAllAir) continue;
UUID uuid = UUID.randomUUID();
// Add recipe to our internal cache
ShapelessRecipeData data = new ShapelessRecipeData("", ingredients, javaOutput);
session.getCraftingRecipes().put(netId,
new com.github.steveice10.mc.protocol.data.game.recipe.Recipe(RecipeType.CRAFTING_SHAPELESS, uuid.toString(), data));
// Add recipe for Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
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) {
return new Pair<>(null, ItemData.AIR);
}
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
legacyId = (itemStack.getType().getId() << 4) | ((byte) 14 & 0xFFFF);
}
// old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 and so on
int itemId;
if (mappingData1_12to1_13.getItemMappings().containsKey(legacyId)) {
@ -189,6 +197,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
ItemData finalData = ItemTranslator.translateToBedrock(session, mcItemStack);
return new Pair<>(mcItemStack, finalData);
}
// Empty slot, most likely
return new Pair<>(null, ItemData.AIR);
}

View file

@ -48,7 +48,6 @@ import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.entity.CommandBlockMinecartEntity;
import org.geysermc.connector.entity.Entity;
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.inventory.GeyserItemStack;
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
&& worldAction.getSource().getFlag() == InventorySource.Flag.DROP_ITEM) {
session.addInventoryTask(() -> {
if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot())
return;
if (session.getPlayerInventory().getItemInHand().isEmpty())
if (session.getPlayerInventory().getHeldItemSlot() != containerAction.getSlot() ||
session.getPlayerInventory().getItemInHand().isEmpty()) {
return;
}
boolean dropAll = worldAction.getToItem().getCount() > 1;
ClientPlayerActionPacket dropAllPacket = new ClientPlayerActionPacket(

View file

@ -103,6 +103,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator {
Vector3i position = session.getLastInteractionBlockPosition();
// 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);
NbtMap blockEntityTag;
if (tag != null) {
int pagesSize = ((ListTag) tag.get("pages")).size();
@ -132,6 +133,7 @@ public class LecternInventoryTranslator extends BaseInventoryTranslator {
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
// the block entity tag
lecternContainer.setBlockEntityTag(blockEntityTag);

View file

@ -128,6 +128,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
return rejectRequest(request);
}
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
// Get the patterns compound tag
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
@ -151,6 +152,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
}
CompoundTag blockEntityTag = inputCopy.getNbt().get("BlockEntityTag");
CompoundTag javaBannerPattern = BannerTranslator.getJavaBannerPattern(pattern);
if (blockEntityTag != null) {
ListTag patternsList = blockEntityTag.get("Patterns");
if (patternsList != null) {
@ -165,6 +167,7 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
blockEntityTag.put(patternsList);
inputCopy.getNbt().put(blockEntityTag);
}
// Set the new item as the output
inventory.setItem(3, inputCopy, session);

View file

@ -65,6 +65,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
return rejectRequest(request);
}
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
StonecutterContainer container = (StonecutterContainer) inventory;
// Get the ID of the item we are cutting
int id = inventory.getItem(0).getJavaId();
@ -73,6 +74,7 @@ public class StonecutterInventoryTranslator extends AbstractBlockInventoryTransl
if (results == null) {
return rejectRequest(request);
}
ItemStack javaOutput = ItemTranslator.translateToJava(craftData.getResultItems()[0]);
int button = results.indexOf(javaOutput.getId());
// 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);
}
}
return translateRequest(session, inventory, request);
}

View file

@ -163,10 +163,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
Int2ObjectMap<IntList> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
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
// We can get the correct order for button pressing
data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData ->
ItemRegistry.getItem(stoneCuttingRecipeData.getResult()).getJavaIdentifier())));
// Now that it's sorted, let's translate these recipes
for (StoneCuttingRecipeData stoneCuttingData : data.getValue()) {
// 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 output = ItemTranslator.translateToBedrock(session, stoneCuttingData.getResult());
UUID uuid = UUID.randomUUID();
// We need to register stonecutting recipes so they show up on Bedrock
craftingDataPacket.getCraftingData().add(CraftingData.fromShapeless(uuid.toString(),
Collections.singletonList(input), Collections.singletonList(output), uuid, "stonecutter", 0, netId++));
// Save the recipe list for reference when crafting
IntList outputs = stonecutterRecipeMap.get(ingredient.getId());
if (outputs == null) {

View file

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

View file

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