3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-26 00:00:41 +01:00

Smithing recipes mostly work

Dieser Commit ist enthalten in:
Camotoy 2024-10-28 17:58:37 -04:00
Ursprung 6c0d3419fc
Commit 344d40dd1f
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7EEFB66FE798081F
7 geänderte Dateien mit 95 neuen und 64 gelöschten Zeilen

Datei anzeigen

@ -27,6 +27,8 @@ package org.geysermc.geyser.session.cache;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.cloudburstmc.math.vector.Vector2f;
import org.cloudburstmc.protocol.bedrock.data.InputMode;
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData; import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -52,12 +54,28 @@ public final class InputCache {
// Input is sent to the server before packet positions, as of 1.21.2 // Input is sent to the server before packet positions, as of 1.21.2
Set<PlayerAuthInputData> bedrockInput = packet.getInputData(); Set<PlayerAuthInputData> bedrockInput = packet.getInputData();
var oldInputPacket = this.inputPacket; var oldInputPacket = this.inputPacket;
boolean up, down, left, right;
if (packet.getInputMode() == InputMode.MOUSE) {
up = bedrockInput.contains(PlayerAuthInputData.UP);
down = bedrockInput.contains(PlayerAuthInputData.DOWN);
left = bedrockInput.contains(PlayerAuthInputData.LEFT);
right = bedrockInput.contains(PlayerAuthInputData.RIGHT);
} else {
// The above flags don't fire TODO test console
Vector2f analogMovement = packet.getAnalogMoveVector();
up = analogMovement.getY() > 0;
down = analogMovement.getY() < 0;
left = analogMovement.getX() > 0;
right = analogMovement.getX() < 0;
}
// TODO when is UP_LEFT, etc. used? // TODO when is UP_LEFT, etc. used?
this.inputPacket = this.inputPacket this.inputPacket = this.inputPacket
.withForward(bedrockInput.contains(PlayerAuthInputData.UP)) .withForward(up)
.withBackward(bedrockInput.contains(PlayerAuthInputData.DOWN)) .withBackward(down)
.withLeft(bedrockInput.contains(PlayerAuthInputData.LEFT)) .withLeft(left)
.withRight(bedrockInput.contains(PlayerAuthInputData.RIGHT)) .withRight(right)
.withJump(bedrockInput.contains(PlayerAuthInputData.JUMPING)) // Looks like this only triggers when the JUMP key input is being pressed. There's also JUMP_DOWN? .withJump(bedrockInput.contains(PlayerAuthInputData.JUMPING)) // Looks like this only triggers when the JUMP key input is being pressed. There's also JUMP_DOWN?
.withShift(bedrockInput.contains(PlayerAuthInputData.SNEAKING)) .withShift(bedrockInput.contains(PlayerAuthInputData.SNEAKING))
.withSprint(bedrockInput.contains(PlayerAuthInputData.SPRINTING)); // SPRINTING will trigger even if the player isn't moving .withSprint(bedrockInput.contains(PlayerAuthInputData.SPRINTING)); // SPRINTING will trigger even if the player isn't moving

Datei anzeigen

@ -25,6 +25,7 @@
package org.geysermc.geyser.translator.protocol.bedrock.entity.player; package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
import org.cloudburstmc.math.GenericMath;
import org.cloudburstmc.math.vector.Vector2f; import org.cloudburstmc.math.vector.Vector2f;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
@ -50,7 +51,6 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator; import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator;
import org.geysermc.geyser.util.CooldownUtils; import org.geysermc.geyser.util.CooldownUtils;
import org.geysermc.geyser.util.MathUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
@ -71,7 +71,7 @@ public final class BedrockPlayerAuthInputTranslator extends PacketTranslator<Pla
@Override @Override
public void translate(GeyserSession session, PlayerAuthInputPacket packet) { public void translate(GeyserSession session, PlayerAuthInputPacket packet) {
if (!data.equals(packet.getInputData())) { if (!data.equals(packet.getInputData())) {
System.out.println(data); System.out.println(packet.getInputData());
this.data = packet.getInputData(); this.data = packet.getInputData();
} }
SessionPlayerEntity entity = session.getPlayerEntity(); SessionPlayerEntity entity = session.getPlayerEntity();
@ -267,7 +267,7 @@ public final class BedrockPlayerAuthInputTranslator extends PacketTranslator<Pla
// Jump released // Jump released
// Yes, I'm fairly certain that entity ID is correct. // Yes, I'm fairly certain that entity ID is correct.
session.sendDownstreamGamePacket(new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(), session.sendDownstreamGamePacket(new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(),
PlayerState.START_HORSE_JUMP, MathUtils.floor(session.getInputCache().getJumpScale() * 100f))); PlayerState.START_HORSE_JUMP, GenericMath.floor(session.getInputCache().getJumpScale() * 100f)));
session.getInputCache().setJumpingTicks(-10); session.getInputCache().setJumpingTicks(-10);
} else if (!wasJumping && holdingJump) { } else if (!wasJumping && holdingJump) {
session.getInputCache().setJumpingTicks(0); session.getInputCache().setJumpingTicks(0);

Datei anzeigen

@ -61,6 +61,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.EmptySl
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.ItemSlotDisplay; 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.ItemStackSlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay; import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SmithingTrimDemoSlotDisplay;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.TagSlotDisplay; import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.TagSlotDisplay;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRecipeBookAddPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRecipeBookAddPacket;
@ -78,7 +79,7 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
@Override @Override
public void translate(GeyserSession session, ClientboundRecipeBookAddPacket packet) { public void translate(GeyserSession session, ClientboundRecipeBookAddPacket packet) {
System.out.println(packet); //System.out.println(packet);
int netId = session.getLastRecipeNetId().get(); int netId = session.getLastRecipeNetId().get();
Int2ObjectMap<List<String>> javaToBedrockRecipeIds = session.getJavaToBedrockRecipeIds(); Int2ObjectMap<List<String>> javaToBedrockRecipeIds = session.getJavaToBedrockRecipeIds();
CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
@ -131,8 +132,8 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
javaToBedrockRecipeIds.put(contents.id(), List.copyOf(bedrockRecipeIds)); javaToBedrockRecipeIds.put(contents.id(), List.copyOf(bedrockRecipeIds));
} }
case SMITHING -> { case SMITHING -> {
if (true) { if (display.result() instanceof SmithingTrimDemoSlotDisplay) {
System.out.println(display); // Skip these - Bedrock already knows about them from the TrimDataPacket
continue; continue;
} }
SmithingRecipeDisplay smithingRecipe = (SmithingRecipeDisplay) display; SmithingRecipeDisplay smithingRecipe = (SmithingRecipeDisplay) display;
@ -169,7 +170,7 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
} }
} }
System.out.println(craftingDataPacket); //System.out.println(craftingDataPacket);
session.sendUpstreamPacket(craftingDataPacket); session.sendUpstreamPacket(craftingDataPacket);
session.sendUpstreamPacket(recipesPacket); session.sendUpstreamPacket(recipesPacket);
session.getLastRecipeNetId().set(netId); session.getLastRecipeNetId().set(netId);
@ -212,26 +213,11 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
// Cache is implemented as, presumably, an item tag will be used multiple times in succession // Cache is implemented as, presumably, an item tag will be used multiple times in succession
// (E.G. a chest with planks tags) // (E.G. a chest with planks tags)
return TAG_TO_ITEM_DESCRIPTOR_CACHE.get().computeIfAbsent(items, key -> { return TAG_TO_ITEM_DESCRIPTOR_CACHE.get().computeIfAbsent(items, key -> {
// String molang = "q.is_item_name_any('', "
// + Arrays.stream(items).mapToObj(item -> {
// ItemMapping mapping = session.getItemMappings().getMapping(item);
// return "'" + mapping.getBedrockIdentifier() + "'";
// }).collect(Collectors.joining(", "))
// + ")";
// String molang = Arrays.stream(items).mapToObj(item -> {
// ItemMapping mapping = session.getItemMappings().getMapping(item);
// return "q.identifier == '" + mapping.getBedrockIdentifier() + "'";
// }).collect(Collectors.joining(" || "));
// if ("minecraft:planks".equals(tag.toString())) {
// String molang = "q.any_tag('minecraft:planks')";
// return Collections.singletonList(new ItemDescriptorWithCount(new MolangDescriptor(molang, 10), 1));
// }
Set<ItemDescriptorWithCount> itemDescriptors = new HashSet<>(); Set<ItemDescriptorWithCount> itemDescriptors = new HashSet<>();
for (int item : key) { for (int item : key) {
itemDescriptors.add(fromItem(session, item)); itemDescriptors.add(fromItem(session, item));
} }
return new ArrayList<>(itemDescriptors); // This, or a list from the start with contains -> add? return List.copyOf(itemDescriptors); // This, or a list from the start with contains -> add?
}); });
} }
} }

Datei anzeigen

@ -28,13 +28,20 @@ package org.geysermc.geyser.translator.protocol.java;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTrimRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.DefaultDescriptor;
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData; import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
import org.geysermc.geyser.inventory.recipe.TrimRecipe;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
@ -50,11 +57,14 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.Clientbound
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket.SelectableRecipe; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundUpdateRecipesPacket.SelectableRecipe;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
/** /**
* Used to send all valid recipes from Java to Bedrock. * Used to send all valid recipes from Java to Bedrock.
@ -94,6 +104,34 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
int netId = session.getLastRecipeNetId().get(); int netId = session.getLastRecipeNetId().get();
CraftingDataPacket craftingDataPacket = new CraftingDataPacket(); CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
System.out.println(packet); System.out.println(packet);
boolean oldSmithingTable;
int[] smithingBase = packet.getItemSets().get(SMITHING_BASE);
int[] smithingTemplate = packet.getItemSets().get(SMITHING_TEMPLATE);
int[] smithingAddition = packet.getItemSets().get(SMITHING_ADDITION);
if (smithingBase == null || smithingTemplate == null || smithingAddition == null) {
// We're probably on a version before the smithing table got expanded functionality.
oldSmithingTable = true;
addSmithingTransformRecipes(session, craftingDataPacket.getCraftingData());
netId = session.getLastRecipeNetId().get(); // Was updated in the above method.
} else {
System.out.println(Arrays.stream(smithingTemplate).mapToObj(i -> Registries.JAVA_ITEMS.get(i).javaIdentifier()).collect(Collectors.joining(" ")));
System.out.println(Arrays.stream(smithingAddition).mapToObj(i -> Registries.JAVA_ITEMS.get(i).javaIdentifier()).collect(Collectors.joining(" ")));
oldSmithingTable = false;
// BDS sends armor trim templates and materials before the CraftingDataPacket
TrimDataPacket trimDataPacket = new TrimDataPacket();
trimDataPacket.getPatterns().addAll(session.getRegistryCache().trimPatterns().values());
trimDataPacket.getMaterials().addAll(session.getRegistryCache().trimMaterials().values());
session.sendUpstreamPacket(trimDataPacket);
// Identical smithing_trim recipe sent by BDS that uses tag-descriptors, as the client seems to ignore the
// approach of using many default-descriptors (which we do for smithing_transform)
craftingDataPacket.getCraftingData().add(SmithingTrimRecipeData.of(TrimRecipe.ID,
TrimRecipe.BASE, TrimRecipe.ADDITION, TrimRecipe.TEMPLATE, "smithing_table", netId++));
}
session.getGeyser().getLogger().debug("Using old smithing table workaround? " + oldSmithingTable);
session.setOldSmithingTable(oldSmithingTable);
Int2ObjectMap<List<SelectableRecipe>> unsortedStonecutterData = new Int2ObjectOpenHashMap<>(); Int2ObjectMap<List<SelectableRecipe>> unsortedStonecutterData = new Int2ObjectOpenHashMap<>();
List<SelectableRecipe> stonecutterRecipes = packet.getStonecutterRecipes(); List<SelectableRecipe> stonecutterRecipes = packet.getStonecutterRecipes();
@ -433,30 +471,28 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
// return combinations; // return combinations;
// } // }
// //
// private List<RecipeData> getSmithingTransformRecipes(GeyserSession session) { private void addSmithingTransformRecipes(GeyserSession session, List<RecipeData> recipes) {
// List<RecipeData> recipes = new ArrayList<>(); ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate();
// ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate();
// for (String identifier : NETHERITE_UPGRADES) {
// for (String identifier : NETHERITE_UPGRADES) { recipes.add(SmithingTransformRecipeData.of(identifier + "_smithing",
// recipes.add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData.of(identifier + "_smithing", getDescriptorFromId(session, template.getBedrockIdentifier()),
// getDescriptorFromId(session, template.getBedrockIdentifier()), getDescriptorFromId(session, identifier.replace("netherite", "diamond")),
// getDescriptorFromId(session, identifier.replace("netherite", "diamond")), getDescriptorFromId(session, "minecraft:netherite_ingot"),
// getDescriptorFromId(session, "minecraft:netherite_ingot"), ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(),
// ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(), "smithing_table",
// "smithing_table", session.getLastRecipeNetId().getAndIncrement()));
// session.getLastRecipeNetId().getAndIncrement())); }
// } }
// return recipes;
// } private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) {
// ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId);
// private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) { if (bedrockDefinition != null) {
// ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId); return ItemDescriptorWithCount.fromItem(ItemData.builder().definition(bedrockDefinition).count(1).build());
// if (bedrockDefinition != null) { }
// return ItemDescriptorWithCount.fromItem(ItemData.builder().definition(bedrockDefinition).count(1).build()); GeyserImpl.getInstance().getLogger().debug("Unable to find item with identifier " + bedrockId);
// } return ItemDescriptorWithCount.EMPTY;
// GeyserImpl.getInstance().getLogger().debug("Unable to find item with identifier " + bedrockId); }
// return ItemDescriptorWithCount.EMPTY;
// }
// //
// @EqualsAndHashCode // @EqualsAndHashCode
// @AllArgsConstructor // @AllArgsConstructor

Datei anzeigen

@ -47,6 +47,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
@Override @Override
public void translate(GeyserSession session, ClientboundPlayerPositionPacket packet) { public void translate(GeyserSession session, ClientboundPlayerPositionPacket packet) {
System.out.println(packet);
if (!session.isLoggedIn()) if (!session.isLoggedIn())
return; return;

Datei anzeigen

@ -52,8 +52,9 @@ public class JavaOpenScreenTranslator extends PacketTranslator<ClientboundOpenSc
InventoryTranslator newTranslator; InventoryTranslator newTranslator;
Inventory openInventory = session.getOpenInventory(); Inventory openInventory = session.getOpenInventory();
// Hack: ViaVersion translates the old (pre 1.20) smithing table to a furnace (does not work for Bedrock). We can detect this and translate it back to a smithing table. // Hack: ViaVersion translates the old (pre 1.20) smithing table to a anvil (does not work for Bedrock). We can detect this and translate it back to a smithing table.
if (session.isOldSmithingTable() && packet.getType() == ContainerType.FURNACE && packet.getTitle().equals(SMITHING_TABLE_COMPONENT)) { // (Implementation note: used to be a furnace. Was changed sometime before 1.21.2)
if (session.isOldSmithingTable() && packet.getType() == ContainerType.ANVIL && packet.getTitle().equals(SMITHING_TABLE_COMPONENT)) {
newTranslator = OldSmithingTableTranslator.INSTANCE; newTranslator = OldSmithingTableTranslator.INSTANCE;
} else { } else {
newTranslator = InventoryTranslator.inventoryTranslator(packet.getType()); newTranslator = InventoryTranslator.inventoryTranslator(packet.getType());

Datei anzeigen

@ -105,17 +105,6 @@ public class MathUtils {
return floatNumber > truncated ? truncated + 1 : truncated; return floatNumber > truncated ? truncated + 1 : truncated;
} }
/**
* Round the given float to the previous whole number
*
* @param floatNumber Float to round
* @return Rounded number
*/
public static int floor(float floatNumber) {
int truncated = (int) floatNumber;
return floatNumber < truncated ? truncated - 1 : truncated;
}
/** /**
* If number is greater than the max, set it to max, and if number is lower than low, set it to low. * If number is greater than the max, set it to max, and if number is lower than low, set it to low.
* *