3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-16 13:00:12 +01:00

Start working on recipe rewriting

Dieser Commit ist enthalten in:
Nassim Jahnke 2024-10-03 20:52:56 +02:00
Ursprung 354a5f1b75
Commit aabe47f8bc
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: EF6771C01F6EF02F
8 geänderte Dateien mit 367 neuen und 184 gelöschten Zeilen

Datei anzeigen

@ -36,7 +36,7 @@ public interface HolderSet {
* @return a new holder set * @return a new holder set
*/ */
static HolderSet of(final String tagKey) { static HolderSet of(final String tagKey) {
return new HolderSetImpl(tagKey); return new HolderSetImpl.Tag(tagKey);
} }
/** /**
@ -46,7 +46,7 @@ public interface HolderSet {
* @return a new holder set * @return a new holder set
*/ */
static HolderSet of(final int[] ids) { static HolderSet of(final int[] ids) {
return new HolderSetImpl(ids); return new HolderSetImpl.Ids(ids);
} }
/** /**

Datei anzeigen

@ -22,50 +22,63 @@
*/ */
package com.viaversion.viaversion.api.minecraft; package com.viaversion.viaversion.api.minecraft;
import com.viaversion.viaversion.util.EitherImpl;
import it.unimi.dsi.fastutil.ints.Int2IntFunction; import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import java.util.Arrays;
final class HolderSetImpl extends EitherImpl<String, int[]> implements HolderSet { final class HolderSetImpl {
HolderSetImpl(final String tagKey) { record Tag(String tagKey) implements HolderSet {
super(tagKey, null); @Override
} public boolean hasTagKey() {
return true;
}
HolderSetImpl(final int[] ids) { @Override
super(null, ids); public int[] ids() {
} throw new IllegalArgumentException("This holder set has a tag key");
}
@Override @Override
public String tagKey() { public boolean hasIds() {
return left(); return false;
} }
@Override @Override
public boolean hasTagKey() { public HolderSet rewrite(final Int2IntFunction idRewriter) {
return isLeft();
}
@Override
public int[] ids() {
return right();
}
@Override
public boolean hasIds() {
return isRight();
}
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
if (hasTagKey()) {
return this; return this;
} }
}
final int[] ids = ids(); record Ids(int[] ids) implements HolderSet {
final int[] mappedIds = new int[ids.length]; @Override
for (int i = 0; i < mappedIds.length; i++) { public boolean hasTagKey() {
mappedIds[i] = idRewriter.applyAsInt(ids[i]); return false;
}
@Override
public String tagKey() {
throw new IllegalArgumentException("This holder set has direct ids");
}
@Override
public boolean hasIds() {
return true;
}
@Override
public HolderSet rewrite(final Int2IntFunction idRewriter) {
final int[] mappedIds = new int[ids.length];
for (int i = 0; i < mappedIds.length; i++) {
mappedIds[i] = idRewriter.applyAsInt(ids[i]);
}
return new Ids(mappedIds);
}
@Override
public String toString() {
return "Ids{" +
"ids=" + Arrays.toString(ids) +
'}';
} }
return new HolderSetImpl(mappedIds);
} }
} }

Datei anzeigen

@ -23,7 +23,7 @@ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21; import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter.RecipeRewriter1_21_2; import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter; import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
@ -70,9 +70,11 @@ final class BlockItemPacketRewriter1_99 extends StructuredItemRewriter<Clientbou
registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES); registerLevelParticles1_20_5(ClientboundPackets1_21.LEVEL_PARTICLES);
registerExplosion1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles registerExplosion1_21_2(ClientboundPackets1_21.EXPLODE); // Rewrites the included sound and particles
new RecipeRewriter1_21_2<>(protocol).register1_20_5(ClientboundPackets1_21.UPDATE_RECIPES); final RecipeDisplayRewriter<ClientboundPacket1_21> recipeRewriter = new RecipeDisplayRewriter<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21.UPDATE_RECIPES);
//recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21.PLACE_GHOST_RECIPE);
// OR do this if serialization of recipes changed and override the relevant method // OR do this if serialization of recipes changed and override the relevant method
// Add new serializers to RecipeRewriter, or extend the last one for changes // Add new serializers to RecipeDisplayRewriter, or extend the last one for changes
// new RecipeRewriter1_21_2<ClientboundPacket1_21>(this) {}.register1_20_5(ClientboundPackets1_21.DECLARE_RECIPES);
} }
} }

Datei anzeigen

@ -193,7 +193,7 @@ public final class BlockItemPacketRewriter1_21_2 extends StructuredItemRewriter<
}); });
protocol.registerClientbound(ClientboundPackets1_21.UPDATE_RECIPES, wrapper -> { protocol.registerClientbound(ClientboundPackets1_21.UPDATE_RECIPES, wrapper -> {
final RecipeRewriter rewriter = new RecipeRewriter(protocol); final RecipeRewriter1_21_2 rewriter = new RecipeRewriter1_21_2(protocol); // Holds state, create a new one for each packet
wrapper.cancel(); // TODO wrapper.cancel(); // TODO
final int size = wrapper.passthrough(Types.VAR_INT); final int size = wrapper.passthrough(Types.VAR_INT);

Datei anzeigen

@ -1,94 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
final class RecipeRewriter extends RecipeRewriter1_20_3<ClientboundPacket1_21> {
RecipeRewriter(final Protocol<ClientboundPacket1_21, ?, ?, ?> protocol) {
super(protocol);
}
@Override
protected void handleIngredient(final PacketWrapper wrapper) {
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
}
@Override
public void handleCraftingShaped(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
final int width = wrapper.passthrough(Types.VAR_INT);
final int height = wrapper.passthrough(Types.VAR_INT);
final int ingredients = width * height;
wrapper.write(Types.VAR_INT, ingredients);
for (int i = 0; i < ingredients; i++) {
wrapper.write(Types.HOLDER_SET, ingredient(wrapper));
}
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result
wrapper.passthrough(Types.BOOLEAN); // Show notification
}
@Override
public void handleCraftingShapeless(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
final int ingredients = wrapper.read(Types.VAR_INT);
final HolderSet[] ingredient = new HolderSet[ingredients];
for (int i = 0; i < ingredients; i++) {
ingredient[i] = ingredient(wrapper);
}
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType())));
// Also moved below here
wrapper.write(Types.VAR_INT, ingredients);
for (final HolderSet item : ingredient) {
wrapper.write(Types.HOLDER_SET, item);
}
}
private HolderSet ingredient(final PacketWrapper wrapper) {
final Item[] items = wrapper.read(itemArrayType());
final int[] ids = new int[items.length];
for (int i = 0; i < items.length; i++) {
final Item item = rewrite(wrapper.user(), items[i]);
ids[i] = item.identifier();
}
return HolderSet.of(ids);
}
@Override
public void handleRecipeType(final PacketWrapper wrapper, final String type) {
if (type.equals("crafting_special_suspiciousstew") || type.equals("crafting_special_shulkerboxcoloring")) {
wrapper.read(Types.VAR_INT); // Crafting book category
} else {
super.handleRecipeType(wrapper, type);
}
}
}

Datei anzeigen

@ -17,63 +17,161 @@
*/ */
package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter; package com.viaversion.viaversion.protocols.v1_21to1_21_2.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.minecraft.HolderSet; import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntCollection;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.ArrayList;
import java.util.List;
// Dead as of 1.21.2, the server only sends simple recipe display data instead of full results final class RecipeRewriter1_21_2 extends RecipeRewriter1_20_3<ClientboundPacket1_21> {
public class RecipeRewriter1_21_2<C extends ClientboundPacketType> extends RecipeRewriter1_20_3<C> {
public RecipeRewriter1_21_2(final Protocol<C, ?, ?, ?> protocol) { private final List<ShapelessRecipe> shapelessRecipes = new ArrayList<>();
private final List<ShapedRecipe> shapedRecipes = new ArrayList<>();
private final List<SmithingRecipe> smithingRecipes = new ArrayList<>();
private final List<StoneCutterRecipe> stoneCutterRecipes = new ArrayList<>();
private final List<SimpleRecipe> simpleRecipes = new ArrayList<>();
private final Object2IntMap<String> recipeGroups = new Object2IntOpenHashMap<>();
// TODO
private final IntList smithingAddition = new IntArrayList();
private final IntList smithingTemplate = new IntArrayList();
private final IntList smithingBase = new IntArrayList();
private final IntList furnaceInput = new IntArrayList();
private final IntList smokerInput = new IntArrayList();
private final IntList blastFurnaceInput = new IntArrayList();
private final IntList campfireInput = new IntArrayList();
record SimpleRecipe(int category) {
}
record ShapelessRecipe(int group, int category, HolderSet[] ingredients, Item result) {
}
record ShapedRecipe(int group, int category, int width, int height, HolderSet[] ingredients, Item result) {
}
record StoneCutterRecipe(int group, HolderSet ingredient, Item result) {
}
record SmithingRecipe(HolderSet ingredient, Item result) {
}
RecipeRewriter1_21_2(final Protocol<ClientboundPacket1_21, ?, ?, ?> protocol) {
super(protocol); super(protocol);
// TODO ?
recipeHandlers.put("smelting", wrapper -> handleSmelting(wrapper, furnaceInput));
recipeHandlers.put("blasting", wrapper -> handleSmelting(wrapper, blastFurnaceInput));
recipeHandlers.put("smoking", wrapper -> handleSmelting(wrapper, smokerInput));
recipeHandlers.put("campfire_cooking", wrapper -> handleSmelting(wrapper, campfireInput));
recipeGroups.defaultReturnValue(-1);
}
private HolderSet readIngredient(final PacketWrapper wrapper) {
// Ingredients are no longer full items, already store them as just holder sets
final Item[] items = wrapper.read(itemArrayType());
final int[] ids = new int[items.length];
final MappingData mappings = protocol.getMappingData();
for (int i = 0; i < items.length; i++) {
final Item item = items[i];
ids[i] = mappings.getNewItemId(item.identifier());
}
return HolderSet.of(ids);
}
private void readIngredientToList(final PacketWrapper wrapper, final IntCollection list) {
final Item[] items = wrapper.read(itemArrayType());
final MappingData mappings = protocol.getMappingData();
for (final Item item : items) {
final int mappedId = mappings.getNewItemId(item.identifier());
list.add(mappedId);
}
}
@Override
public void handleSimpleRecipe(final PacketWrapper wrapper) {
final int category = wrapper.read(Types.VAR_INT);
simpleRecipes.add(new SimpleRecipe(category));
}
@Override
public void handleStonecutting(final PacketWrapper wrapper) {
final int group = recipeGroupId(wrapper.read(Types.STRING));
final HolderSet ingredient = readIngredient(wrapper);
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
stoneCutterRecipes.add(new StoneCutterRecipe(group, ingredient, result));
}
private int recipeGroupId(final String recipeGroup) {
final int size = recipeGroups.size();
final int value = recipeGroups.putIfAbsent(recipeGroup, size);
return value != -1 ? value : size;
}
@Override
public void handleSmithingTransform(final PacketWrapper wrapper) {
final IntList template = new IntArrayList();
readIngredientToList(wrapper, template);
smithingTemplate.addAll(template);
readIngredientToList(wrapper, smithingBase);
readIngredientToList(wrapper, smithingAddition);
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
smithingRecipes.add(new SmithingRecipe(HolderSet.of(template.toIntArray()), result)); // TODO ?
}
@Override
public void handleSmithingTrim(final PacketWrapper wrapper) {
readIngredientToList(wrapper, smithingTemplate);
readIngredientToList(wrapper, smithingBase);
readIngredientToList(wrapper, smithingAddition);
} }
@Override @Override
public void handleCraftingShaped(final PacketWrapper wrapper) { public void handleCraftingShaped(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group final int group = recipeGroupId(wrapper.read(Types.STRING));
wrapper.passthrough(Types.VAR_INT); // Crafting book category final int category = wrapper.read(Types.VAR_INT);
wrapper.passthrough(Types.VAR_INT); // Width final int width = wrapper.read(Types.VAR_INT);
wrapper.passthrough(Types.VAR_INT); // Height final int height = wrapper.read(Types.VAR_INT);
final int ingredientsSize = width * height;
final int ingredients = wrapper.passthrough(Types.VAR_INT); final HolderSet[] ingredients = new HolderSet[ingredientsSize];
for (int i = 0; i < ingredients; i++) { for (int i = 0; i < ingredientsSize; i++) {
handleIngredient(wrapper); ingredients[i] = readIngredient(wrapper);
} }
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
shapedRecipes.add(new ShapedRecipe(group, category, width, height, ingredients, result));
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result wrapper.read(Types.BOOLEAN); // Show notification
wrapper.passthrough(Types.BOOLEAN); // Show notification
} }
@Override @Override
public void handleCraftingShapeless(final PacketWrapper wrapper) { public void handleCraftingShapeless(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group final int group = recipeGroupId(wrapper.read(Types.STRING));
wrapper.passthrough(Types.VAR_INT); // Crafting book category final int category = wrapper.read(Types.VAR_INT);
wrapper.write(mappedItemType(), rewrite(wrapper.user(), wrapper.read(itemType()))); // Result final int ingredientsSize = wrapper.read(Types.VAR_INT);
handleIngredients(wrapper); final HolderSet[] ingredients = new HolderSet[ingredientsSize];
for (int i = 0; i < ingredientsSize; i++) {
ingredients[i] = readIngredient(wrapper);
}
final Item result = rewrite(wrapper.user(), wrapper.read(itemType()));
shapelessRecipes.add(new ShapelessRecipe(group, category, ingredients, result));
} }
@Override private void handleSmelting(final PacketWrapper wrapper, final IntCollection list) {
protected void handleIngredient(final PacketWrapper wrapper) { final int group = recipeGroupId(wrapper.read(Types.STRING));
final HolderSet items = wrapper.passthrough(Types.HOLDER_SET); final int category = wrapper.read(Types.VAR_INT);
if (items.hasTagKey()) { readIngredientToList(wrapper, list);
return; wrapper.read(itemType()); // Result
}
final int[] ids = items.ids(); wrapper.read(Types.FLOAT); // EXP
for (int i = 0; i < ids.length; i++) { wrapper.read(Types.VAR_INT); // Cooking time
ids[i] = rewriteItemId(wrapper.user(), ids[i]);
}
}
protected int rewriteItemId(final UserConnection connection, final int id) {
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
return protocol.getMappingData().getItemMappings().getNewIdOrDefault(id, id);
}
return id;
} }
} }

Datei anzeigen

@ -0,0 +1,175 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.rewriter;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
import com.viaversion.viaversion.api.type.Types;
// Base for 1.21.2 and onwards
public class RecipeDisplayRewriter<C extends ClientboundPacketType> {
protected final Protocol<C, ?, ?, ?> protocol;
public RecipeDisplayRewriter(final Protocol<C, ?, ?, ?> protocol) {
this.protocol = protocol;
}
public void registerUpdateRecipes(final C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
final int size = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < size; i++) {
wrapper.passthrough(Types.STRING); // Recipe group
rewriteItemIds(wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE));
}
final int stonecutterRecipesSize = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < stonecutterRecipesSize; i++) {
handleIngredient(wrapper);
handleSlotDisplay(wrapper);
}
});
}
public void registerRecipeBookAdd(final C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
final int size = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < size; i++) {
wrapper.passthrough(Types.VAR_INT); // Display ID
handleRecipeDisplay(wrapper);
wrapper.passthrough(Types.OPTIONAL_VAR_INT); // Group
wrapper.passthrough(Types.VAR_INT); // Category
if (wrapper.passthrough(Types.BOOLEAN)) {
final int ingredientsSize = wrapper.passthrough(Types.VAR_INT);
for (int j = 0; j < ingredientsSize; j++) {
handleIngredient(wrapper); // Items
}
}
wrapper.passthrough(Types.BYTE); // Flags
}
});
}
public void registerPlaceGhostRecipe(final C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Container ID
handleRecipeDisplay(wrapper);
});
}
protected void handleShapeless(final PacketWrapper wrapper) {
handleSlotDisplayList(wrapper); // Ingredients
handleSlotDisplay(wrapper); // Result
handleSlotDisplay(wrapper); // Crafting station
}
protected void handleShaped(final PacketWrapper wrapper) {
wrapper.passthrough(Types.VAR_INT); // Width
wrapper.passthrough(Types.VAR_INT); // Height
handleSlotDisplayList(wrapper); // Ingredients
handleSlotDisplay(wrapper); // Result
handleSlotDisplay(wrapper); // Crafting station
}
protected void handleFurnace(final PacketWrapper wrapper) {
handleSlotDisplay(wrapper); // Ingredient
handleSlotDisplay(wrapper); // Fuel
handleSlotDisplay(wrapper); // Result
handleSlotDisplay(wrapper); // Crafting station
}
protected void handleStoneCutter(final PacketWrapper wrapper) {
handleSlotDisplay(wrapper); // Result
handleSlotDisplay(wrapper); // Crafting station
}
protected void handleSmithing(final PacketWrapper wrapper) {
handleSlotDisplay(wrapper); // Result
handleSlotDisplay(wrapper); // Crafting station
}
protected void handleSlotDisplayList(final PacketWrapper wrapper) {
final int size = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < size; i++) {
handleSlotDisplay(wrapper);
}
}
protected void handleRecipeDisplay(final PacketWrapper wrapper) {
final int type = wrapper.passthrough(Types.VAR_INT);
switch (type) {
case 0 -> handleShapeless(wrapper);
case 1 -> handleShaped(wrapper);
case 2 -> handleFurnace(wrapper);
case 3 -> handleStoneCutter(wrapper);
case 4 -> handleSmithing(wrapper);
}
}
protected void handleSlotDisplay(final PacketWrapper wrapper) {
// empty, any_fuel, smithing_trim are empty
final int type = wrapper.passthrough(Types.VAR_INT);
switch (type) {
case 2 -> handleItemId(wrapper); // Item type
case 3 -> handleItem(wrapper); // Item
case 4 -> wrapper.passthrough(Types.STRING); // Tag key
case 6 -> handleSlotDisplayList(wrapper); // Composite
}
}
protected void handleIngredient(final PacketWrapper wrapper) {
final HolderSet items = wrapper.passthrough(Types.HOLDER_SET);
if (items.hasTagKey()) {
return;
}
final int[] ids = items.ids();
for (int i = 0; i < ids.length; i++) {
ids[i] = rewriteItemId(ids[i]);
}
}
protected void handleItemId(final PacketWrapper wrapper) {
final int id = wrapper.passthrough(Types.VAR_INT);
wrapper.write(Types.VAR_INT, rewriteItemId(id));
}
protected void handleItem(final PacketWrapper wrapper) {
final ItemRewriter<?> itemRewriter = protocol.getItemRewriter();
final Item item = wrapper.read(itemRewriter.itemType());
itemRewriter.handleItemToClient(wrapper.user(), item);
wrapper.write(itemRewriter.mappedItemType(), item);
}
protected int rewriteItemId(final int id) {
if (protocol.getMappingData() != null && protocol.getMappingData().getItemMappings() != null) {
return protocol.getMappingData().getItemMappings().getNewIdOrDefault(id, id);
}
return id;
}
protected void rewriteItemIds(final int[] ids) {
for (int i = 0; i < ids.length; i++) {
final int id = ids[i];
ids[i] = rewriteItemId(id);
}
}
}

Datei anzeigen

@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
// Base up to and including 1.21.1
public class RecipeRewriter<C extends ClientboundPacketType> { public class RecipeRewriter<C extends ClientboundPacketType> {
protected final Protocol<C, ?, ?, ?> protocol; protected final Protocol<C, ?, ?, ?> protocol;
@ -54,9 +55,6 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
recipeHandlers.put("smithing_transform", this::handleSmithingTransform); recipeHandlers.put("smithing_transform", this::handleSmithingTransform);
recipeHandlers.put("smithing_trim", this::handleSmithingTrim); recipeHandlers.put("smithing_trim", this::handleSmithingTrim);
recipeHandlers.put("crafting_decorated_pot", this::handleSimpleRecipe); recipeHandlers.put("crafting_decorated_pot", this::handleSimpleRecipe);
// Added in 1.21.2
recipeHandlers.put("crafting_transmute", this::handleTransmute);
} }
public void handleRecipeType(PacketWrapper wrapper, String type) { public void handleRecipeType(PacketWrapper wrapper, String type) {
@ -163,15 +161,6 @@ public class RecipeRewriter<C extends ClientboundPacketType> {
handleIngredient(wrapper); // Additions handleIngredient(wrapper); // Additions
} }
private void handleTransmute(final PacketWrapper wrapper) {
wrapper.passthrough(Types.STRING); // Group
wrapper.passthrough(Types.VAR_INT); // Crafting book category
handleIngredient(wrapper); // Input
handleIngredient(wrapper); // Material
final int resultItemId = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, rewrite(resultItemId));
}
protected int rewrite(final int itemId) { protected int rewrite(final int itemId) {
if (protocol.getMappingData() != null && protocol.getItemRewriter() != null) { if (protocol.getMappingData() != null && protocol.getItemRewriter() != null) {
return protocol.getMappingData().getNewItemId(itemId); return protocol.getMappingData().getNewItemId(itemId);