Skip to content

Commit

Permalink
Re-implement on-the-fly recipe sending
Browse files Browse the repository at this point in the history
  • Loading branch information
Camotoy committed Oct 28, 2024
1 parent 344d40d commit 05f153c
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.Registries;
Expand All @@ -38,6 +39,10 @@
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.EmptySlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.ItemSlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.ItemStackSlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

import java.util.HashMap;

Expand Down Expand Up @@ -77,6 +82,20 @@ private GeyserItemStack(int javaId, int amount, DataComponents components, int n
return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents());
}

public static @NonNull GeyserItemStack from(@NonNull SlotDisplay slotDisplay) {
if (slotDisplay instanceof EmptySlotDisplay) {
return GeyserItemStack.EMPTY;
}
if (slotDisplay instanceof ItemSlotDisplay itemSlotDisplay) {
return GeyserItemStack.of(itemSlotDisplay.item(), 1);
}
if (slotDisplay instanceof ItemStackSlotDisplay itemStackSlotDisplay) {
return GeyserItemStack.from(itemStackSlotDisplay.itemStack());
}
GeyserImpl.getInstance().getLogger().warning("Unsure how to convert to ItemStack: " + slotDisplay);
return GeyserItemStack.EMPTY;
}

public int getJavaId() {
return isEmpty() ? 0 : javaId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
package org.geysermc.geyser.inventory.recipe;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

/**
* A more compact version of {link org.geysermc.mcprotocollib.protocol.data.game.recipe.Recipe}.
Expand All @@ -38,5 +38,5 @@ public interface GeyserRecipe {
boolean isShaped();

@Nullable
ItemStack result();
SlotDisplay result();
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@
package org.geysermc.geyser.inventory.recipe;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.ShapedCraftingRecipeDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

public record GeyserShapedRecipe(int width, int height, Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe {
import java.util.List;

// public GeyserShapedRecipe(ShapedRecipeData data) {
// this(data.getWidth(), data.getHeight(), data.getIngredients(), data.getResult());
// }
public record GeyserShapedRecipe(int width, int height, List<SlotDisplay> ingredients, @Nullable SlotDisplay result) implements GeyserRecipe {

public GeyserShapedRecipe(ShapedCraftingRecipeDisplay data) {
this(data.width(), data.height(), data.ingredients(), data.result());
}

@Override
public boolean isShaped() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@
package org.geysermc.geyser.inventory.recipe;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.ShapelessCraftingRecipeDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

public record GeyserShapelessRecipe(Ingredient[] ingredients, @Nullable ItemStack result) implements GeyserRecipe {
import java.util.List;

// public GeyserShapelessRecipe(ShapelessRecipeData data) {
// this(data.getIngredients(), data.getResult());
// }
public record GeyserShapelessRecipe(List<SlotDisplay> ingredients, @Nullable SlotDisplay result) implements GeyserRecipe {

public GeyserShapelessRecipe(ShapelessCraftingRecipeDisplay data) {
this(data.ingredients(), data.result());
}

@Override
public boolean isShaped() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
Expand Down Expand Up @@ -92,7 +90,7 @@ private static List<GeyserRecipe> getShapelessRecipes(List<NbtMap> recipes, Mine
for (int i = 0; i < rawInputs.size(); i++) {
//javaInputs[i] = new Ingredient(new ItemStack[] {toItemStack(rawInputs.get(i), helper)});
}
deserializedRecipes.add(new GeyserShapelessRecipe(javaInputs, output));
//deserializedRecipes.add(new GeyserShapelessRecipe(javaInputs, output));
}
return deserializedRecipes;
}
Expand All @@ -118,7 +116,7 @@ private static List<GeyserRecipe> getShapedRecipes(List<NbtMap> recipes, Minecra
//inputs[i++] = new Ingredient(new ItemStack[] {stack});
}
}
deserializedRecipes.add(new GeyserShapedRecipe(shape.size(), shape.get(0).length, inputs, output));
//deserializedRecipes.add(new GeyserShapedRecipe(shape.size(), shape.get(0).length, inputs, output));
}
return deserializedRecipes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
*/
private final Int2ObjectMap<List<String>> javaToBedrockRecipeIds;

@Setter
private Int2ObjectMap<GeyserRecipe> craftingRecipes;
private final Int2ObjectMap<GeyserRecipe> craftingRecipes;
private final AtomicInteger lastRecipeNetId;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,40 @@

package org.geysermc.geyser.translator.inventory;

import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.IntSortedSet;
import lombok.AllArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType;
import org.cloudburstmc.protocol.bedrock.data.inventory.FullContainerName;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequest;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemStackRequestSlotData;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.*;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.AutoCraftRecipeAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ConsumeAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftResultsDeprecatedAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.DropAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.SwapAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.TransferItemStackRequestAction;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseContainer;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseSlot;
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponseStatus;
import org.cloudburstmc.protocol.bedrock.packet.ItemStackResponsePacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.*;
import org.geysermc.geyser.inventory.BedrockContainerSlot;
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.inventory.SlotType;
import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.inventory.click.ClickPlan;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
Expand All @@ -56,12 +75,17 @@
import org.geysermc.geyser.util.InventoryUtils;
import org.geysermc.geyser.util.ItemUtils;
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.EmptySlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;

import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@AllArgsConstructor
public abstract class InventoryTranslator {
Expand Down Expand Up @@ -642,8 +666,8 @@ public ItemStackResponse translateAutoCraftingRequest(GeyserSession session, Inv
}
int gridDimensions = gridSize == 4 ? 2 : 3;

Ingredient[] ingredients = new Ingredient[0];
ItemStack output = null;
List<SlotDisplay> ingredients = Collections.emptyList();
SlotDisplay output = null;
int recipeWidth = 0;
int ingRemaining = 0;
int ingredientIndex = -1;
Expand Down Expand Up @@ -697,7 +721,7 @@ public ItemStackResponse translateAutoCraftingRequest(GeyserSession session, Inv
ingredients = shapelessRecipe.ingredients();
recipeWidth = gridDimensions;
output = shapelessRecipe.result();
if (ingredients.length > gridSize) {
if (ingredients.size() > gridSize) {
return rejectRequest(request);
}
}
Expand Down Expand Up @@ -728,11 +752,11 @@ public ItemStackResponse translateAutoCraftingRequest(GeyserSession session, Inv
craftState = CraftState.INGREDIENTS;

if (ingRemaining == 0) {
while (++ingredientIndex < ingredients.length) {
// if (ingredients[ingredientIndex].getOptions().length != 0) {
// ingRemaining = timesCrafted;
// break;
// }
while (++ingredientIndex < ingredients.size()) {
if (!(ingredients.get(ingredientIndex) instanceof EmptySlotDisplay)) { // TODO I guess can technically other options be empty?
ingRemaining = timesCrafted;
break;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import static org.geysermc.geyser.util.InventoryUtils.LAST_RECIPE_NET_ID;

@Translator(packet = ClientboundFinishConfigurationPacket.class)
public class JavaFinishConfigurationPacketTranslator extends PacketTranslator<ClientboundFinishConfigurationPacket> {
public class JavaFinishConfigurationTranslator extends PacketTranslator<ClientboundFinishConfigurationPacket> {
/**
* Required to use the specified cartography table recipes
*/
Expand Down Expand Up @@ -72,6 +72,9 @@ public void translate(GeyserSession session, ClientboundFinishConfigurationPacke
craftingDataPacket.getPotionMixData().addAll(Registries.POTION_MIXES.forVersion(session.getUpstream().getProtocolVersion()));
if (session.isSentSpawnPacket()) {
session.getUpstream().sendPacket(craftingDataPacket);
session.getCraftingRecipes().clear();
session.getJavaToBedrockRecipeIds().clear();
session.getStonecutterRecipes().clear();
} else {
session.getUpstream().queuePostStartGamePacket(craftingDataPacket);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.UnlockedRecipesPacket;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.BedrockRequiresTagItem;
import org.geysermc.geyser.item.type.Item;
Expand Down Expand Up @@ -79,9 +82,10 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec

@Override
public void translate(GeyserSession session, ClientboundRecipeBookAddPacket packet) {
//System.out.println(packet);
System.out.println(packet);
int netId = session.getLastRecipeNetId().get();
Int2ObjectMap<List<String>> javaToBedrockRecipeIds = session.getJavaToBedrockRecipeIds();
Int2ObjectMap<GeyserRecipe> geyserRecipes = session.getCraftingRecipes();
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();

UnlockedRecipesPacket recipesPacket = new UnlockedRecipesPacket();
Expand All @@ -101,14 +105,17 @@ public void translate(GeyserSession session, ClientboundRecipeBookAddPacket pack
List<String> bedrockRecipeIds = new ArrayList<>();
ItemData output = bedrockRecipes.right();
List<List<ItemDescriptorWithCount>> left = bedrockRecipes.left();
GeyserRecipe geyserRecipe = new GeyserShapedRecipe(shapedRecipe);
for (int i = 0; i < left.size(); i++) {
List<ItemDescriptorWithCount> inputs = left.get(i);
String recipeId = contents.id() + "_" + i;
int recipeNetworkId = netId++;
craftingDataPacket.getCraftingData().add(ShapedRecipeData.shaped(recipeId,
shapedRecipe.width(), shapedRecipe.height(), inputs,
Collections.singletonList(output), UUID.randomUUID(), "crafting_table", 0, netId++, false, RecipeUnlockingRequirement.INVALID));
Collections.singletonList(output), UUID.randomUUID(), "crafting_table", 0, recipeNetworkId, false, RecipeUnlockingRequirement.INVALID));
recipesPacket.getUnlockedRecipes().add(recipeId);
bedrockRecipeIds.add(recipeId);
geyserRecipes.put(recipeNetworkId, geyserRecipe);
}
javaToBedrockRecipeIds.put(contents.id(), List.copyOf(bedrockRecipeIds));
}
Expand All @@ -121,13 +128,16 @@ public void translate(GeyserSession session, ClientboundRecipeBookAddPacket pack
List<String> bedrockRecipeIds = new ArrayList<>();
ItemData output = bedrockRecipes.right();
List<List<ItemDescriptorWithCount>> left = bedrockRecipes.left();
GeyserRecipe geyserRecipe = new GeyserShapelessRecipe(shapelessRecipe);
for (int i = 0; i < left.size(); i++) {
List<ItemDescriptorWithCount> inputs = left.get(i);
String recipeId = contents.id() + "_" + i;
int recipeNetworkId = netId++;
craftingDataPacket.getCraftingData().add(ShapelessRecipeData.shapeless(recipeId,
inputs, Collections.singletonList(output), UUID.randomUUID(), "crafting_table", 0, netId++, RecipeUnlockingRequirement.INVALID));
inputs, Collections.singletonList(output), UUID.randomUUID(), "crafting_table", 0, recipeNetworkId, RecipeUnlockingRequirement.INVALID));
recipesPacket.getUnlockedRecipes().add(recipeId);
bedrockRecipeIds.add(recipeId);
geyserRecipes.put(recipeNetworkId, geyserRecipe);
}
javaToBedrockRecipeIds.put(contents.id(), List.copyOf(bedrockRecipeIds));
}
Expand Down
Loading

0 comments on commit 05f153c

Please sign in to comment.