ViaVersion/common/src/main/java/com/viaversion/viaversion/rewriter/RecipeRewriter.java

196 lines
7.3 KiB
Java
Raw Normal View History

/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
2024-01-01 12:39:45 +01:00
* 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/>.
*/
2021-04-26 21:16:10 +02:00
package com.viaversion.viaversion.rewriter;
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.type.Type;
import com.viaversion.viaversion.util.Key;
import java.util.HashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
2023-02-16 12:27:31 +01:00
public class RecipeRewriter<C extends ClientboundPacketType> {
protected final Protocol<C, ?, ?, ?> protocol;
protected final Map<String, RecipeConsumer> recipeHandlers = new HashMap<>();
2023-02-16 13:03:01 +01:00
public RecipeRewriter(final Protocol<C, ?, ?, ?> protocol) {
this.protocol = protocol;
2023-02-16 12:27:31 +01:00
recipeHandlers.put("crafting_shapeless", this::handleCraftingShapeless);
recipeHandlers.put("crafting_shaped", this::handleCraftingShaped);
recipeHandlers.put("smelting", this::handleSmelting);
// Added in 1.14
recipeHandlers.put("blasting", this::handleSmelting);
recipeHandlers.put("smoking", this::handleSmelting);
recipeHandlers.put("campfire_cooking", this::handleSmelting);
2023-02-16 13:03:01 +01:00
recipeHandlers.put("stonecutting", this::handleStonecutting);
2023-02-16 12:27:31 +01:00
// Added in 1.16
recipeHandlers.put("smithing", this::handleSmithing);
// Added in 1.19.4
recipeHandlers.put("smithing_transform", this::handleSmithingTransform);
2023-02-18 10:00:57 +01:00
recipeHandlers.put("smithing_trim", this::handleSmithingTrim);
2023-02-16 12:27:31 +01:00
recipeHandlers.put("crafting_decorated_pot", this::handleSimpleRecipe);
}
public void handleRecipeType(PacketWrapper wrapper, String type) throws Exception {
RecipeConsumer handler = recipeHandlers.get(type);
if (handler != null) {
handler.accept(wrapper);
}
}
2023-02-16 12:27:31 +01:00
/**
* Registers a packet handler to rewrite recipe types, for 1.14+.
*
* @param packetType packet type
*/
public void register(C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
String type = wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.STRING); // Recipe Identifier
handleRecipeType(wrapper, Key.stripMinecraftNamespace(type));
}
});
}
2024-01-17 21:04:44 +01:00
public void register1_20_5(C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING);// Recipe Identifier
final int typeId = wrapper.passthrough(Type.VAR_INT);
final String type = protocol.getMappingData().getRecipeSerializerMappings().identifier(typeId);
handleRecipeType(wrapper, type);
}
});
}
2023-02-16 12:27:31 +01:00
public void handleCraftingShaped(PacketWrapper wrapper) throws Exception {
int ingredientsNo = wrapper.passthrough(Type.VAR_INT) * wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.STRING); // Group
for (int i = 0; i < ingredientsNo; i++) {
handleIngredient(wrapper);
}
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
}
public void handleCraftingShapeless(PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
handleIngredients(wrapper);
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
}
public void handleSmelting(PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
handleIngredient(wrapper);
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
}
public void handleStonecutting(PacketWrapper wrapper) throws Exception {
2023-02-16 13:03:01 +01:00
wrapper.passthrough(Type.STRING); // Group
2023-02-16 12:27:31 +01:00
handleIngredient(wrapper);
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
}
public void handleSmithing(PacketWrapper wrapper) throws Exception {
handleIngredient(wrapper); // Base
handleIngredient(wrapper); // Addition
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
}
public void handleSimpleRecipe(final PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.VAR_INT); // Crafting book category
}
public void handleSmithingTransform(final PacketWrapper wrapper) throws Exception {
handleIngredient(wrapper); // Template
handleIngredient(wrapper); // Base
handleIngredient(wrapper); // Additions
2024-02-28 22:15:31 +01:00
final Item result = rewrite(wrapper.read(itemType()));
wrapper.write(mappedItemType(), result);
2023-02-16 12:27:31 +01:00
}
2023-02-18 10:00:57 +01:00
public void handleSmithingTrim(final PacketWrapper wrapper) throws Exception {
handleIngredient(wrapper); // Template
handleIngredient(wrapper); // Base
handleIngredient(wrapper); // Additions
}
2024-02-28 22:15:31 +01:00
protected @Nullable Item rewrite(@Nullable Item item) {
if (protocol.getItemRewriter() != null) {
2024-02-28 22:15:31 +01:00
return protocol.getItemRewriter().handleItemToClient(item);
}
2024-02-28 22:15:31 +01:00
return item;
}
2023-02-16 12:27:31 +01:00
protected void handleIngredient(final PacketWrapper wrapper) throws Exception {
2024-02-28 22:15:31 +01:00
final Item[] items = wrapper.read(itemArrayType());
wrapper.write(mappedItemArrayType(), items);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
items[i] = rewrite(item);
2023-02-16 12:27:31 +01:00
}
}
protected void handleIngredients(final PacketWrapper wrapper) throws Exception {
final int ingredients = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
}
@FunctionalInterface
public interface RecipeConsumer {
void accept(PacketWrapper wrapper) throws Exception;
}
2023-08-03 13:58:23 +02:00
protected Type<Item> itemType() {
2023-10-19 01:28:12 +02:00
return Type.ITEM1_13_2;
2023-08-03 13:58:23 +02:00
}
protected Type<Item[]> itemArrayType() {
2023-10-19 01:28:12 +02:00
return Type.ITEM1_13_2_ARRAY;
2023-08-03 13:58:23 +02:00
}
2024-02-28 22:15:31 +01:00
protected Type<Item> mappedItemType() {
return itemType();
}
protected Type<Item[]> mappedItemArrayType() {
return itemArrayType();
}
}