mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-12-28 07:20:28 +01:00
Smithing recipes mostly work
This commit is contained in:
parent
6c0d3419fc
commit
344d40dd1f
7 changed files with 95 additions and 64 deletions
|
@ -27,6 +27,8 @@ package org.geysermc.geyser.session.cache;
|
|||
|
||||
import lombok.Getter;
|
||||
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.packet.PlayerAuthInputPacket;
|
||||
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
|
||||
Set<PlayerAuthInputData> bedrockInput = packet.getInputData();
|
||||
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?
|
||||
this.inputPacket = this.inputPacket
|
||||
.withForward(bedrockInput.contains(PlayerAuthInputData.UP))
|
||||
.withBackward(bedrockInput.contains(PlayerAuthInputData.DOWN))
|
||||
.withLeft(bedrockInput.contains(PlayerAuthInputData.LEFT))
|
||||
.withRight(bedrockInput.contains(PlayerAuthInputData.RIGHT))
|
||||
.withForward(up)
|
||||
.withBackward(down)
|
||||
.withLeft(left)
|
||||
.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?
|
||||
.withShift(bedrockInput.contains(PlayerAuthInputData.SNEAKING))
|
||||
.withSprint(bedrockInput.contains(PlayerAuthInputData.SPRINTING)); // SPRINTING will trigger even if the player isn't moving
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
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.Vector3f;
|
||||
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.bedrock.BedrockInventoryTransactionTranslator;
|
||||
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.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
|
||||
|
@ -71,7 +71,7 @@ public final class BedrockPlayerAuthInputTranslator extends PacketTranslator<Pla
|
|||
@Override
|
||||
public void translate(GeyserSession session, PlayerAuthInputPacket packet) {
|
||||
if (!data.equals(packet.getInputData())) {
|
||||
System.out.println(data);
|
||||
System.out.println(packet.getInputData());
|
||||
this.data = packet.getInputData();
|
||||
}
|
||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||
|
@ -267,7 +267,7 @@ public final class BedrockPlayerAuthInputTranslator extends PacketTranslator<Pla
|
|||
// Jump released
|
||||
// Yes, I'm fairly certain that entity ID is correct.
|
||||
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);
|
||||
} else if (!wasJumping && holdingJump) {
|
||||
session.getInputCache().setJumpingTicks(0);
|
||||
|
|
|
@ -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.ItemStackSlotDisplay;
|
||||
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.packet.ingame.clientbound.ClientboundRecipeBookAddPacket;
|
||||
|
||||
|
@ -78,7 +79,7 @@ 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();
|
||||
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||
|
@ -131,8 +132,8 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
|
|||
javaToBedrockRecipeIds.put(contents.id(), List.copyOf(bedrockRecipeIds));
|
||||
}
|
||||
case SMITHING -> {
|
||||
if (true) {
|
||||
System.out.println(display);
|
||||
if (display.result() instanceof SmithingTrimDemoSlotDisplay) {
|
||||
// Skip these - Bedrock already knows about them from the TrimDataPacket
|
||||
continue;
|
||||
}
|
||||
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(recipesPacket);
|
||||
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
|
||||
// (E.G. a chest with planks tags)
|
||||
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<>();
|
||||
for (int item : key) {
|
||||
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?
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,13 +28,20 @@ package org.geysermc.geyser.translator.protocol.java;
|
|||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
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.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.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.ItemDescriptorWithCount;
|
||||
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.TrimRecipe;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
CraftingDataPacket craftingDataPacket = new CraftingDataPacket();
|
||||
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<>();
|
||||
|
||||
List<SelectableRecipe> stonecutterRecipes = packet.getStonecutterRecipes();
|
||||
|
@ -433,30 +471,28 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
|
|||
// return combinations;
|
||||
// }
|
||||
//
|
||||
// private List<RecipeData> getSmithingTransformRecipes(GeyserSession session) {
|
||||
// List<RecipeData> recipes = new ArrayList<>();
|
||||
// ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate();
|
||||
//
|
||||
// for (String identifier : NETHERITE_UPGRADES) {
|
||||
// recipes.add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData.of(identifier + "_smithing",
|
||||
// getDescriptorFromId(session, template.getBedrockIdentifier()),
|
||||
// getDescriptorFromId(session, identifier.replace("netherite", "diamond")),
|
||||
// getDescriptorFromId(session, "minecraft:netherite_ingot"),
|
||||
// ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(),
|
||||
// "smithing_table",
|
||||
// session.getLastRecipeNetId().getAndIncrement()));
|
||||
// }
|
||||
// return recipes;
|
||||
// }
|
||||
//
|
||||
// private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) {
|
||||
// ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId);
|
||||
// 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;
|
||||
// }
|
||||
private void addSmithingTransformRecipes(GeyserSession session, List<RecipeData> recipes) {
|
||||
ItemMapping template = session.getItemMappings().getStoredItems().upgradeTemplate();
|
||||
|
||||
for (String identifier : NETHERITE_UPGRADES) {
|
||||
recipes.add(SmithingTransformRecipeData.of(identifier + "_smithing",
|
||||
getDescriptorFromId(session, template.getBedrockIdentifier()),
|
||||
getDescriptorFromId(session, identifier.replace("netherite", "diamond")),
|
||||
getDescriptorFromId(session, "minecraft:netherite_ingot"),
|
||||
ItemData.builder().definition(Objects.requireNonNull(session.getItemMappings().getDefinition(identifier))).count(1).build(),
|
||||
"smithing_table",
|
||||
session.getLastRecipeNetId().getAndIncrement()));
|
||||
}
|
||||
}
|
||||
|
||||
private ItemDescriptorWithCount getDescriptorFromId(GeyserSession session, String bedrockId) {
|
||||
ItemDefinition bedrockDefinition = session.getItemMappings().getDefinition(bedrockId);
|
||||
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;
|
||||
}
|
||||
//
|
||||
// @EqualsAndHashCode
|
||||
// @AllArgsConstructor
|
||||
|
|
|
@ -47,6 +47,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
|
|||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundPlayerPositionPacket packet) {
|
||||
System.out.println(packet);
|
||||
if (!session.isLoggedIn())
|
||||
return;
|
||||
|
||||
|
|
|
@ -52,8 +52,9 @@ public class JavaOpenScreenTranslator extends PacketTranslator<ClientboundOpenSc
|
|||
InventoryTranslator newTranslator;
|
||||
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.
|
||||
if (session.isOldSmithingTable() && packet.getType() == ContainerType.FURNACE && packet.getTitle().equals(SMITHING_TABLE_COMPONENT)) {
|
||||
// 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.
|
||||
// (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;
|
||||
} else {
|
||||
newTranslator = InventoryTranslator.inventoryTranslator(packet.getType());
|
||||
|
|
|
@ -105,17 +105,6 @@ public class MathUtils {
|
|||
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.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue