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

Merge remote-tracking branch 'refs/remotes/upstream/master' into feature/1.21.4

# Conflicts:
#	core/src/main/java/org/geysermc/geyser/translator/inventory/LecternInventoryTranslator.java
Dieser Commit ist enthalten in:
onebeastchris 2024-12-02 02:46:34 +08:00
Commit a9577a946e
6 geänderte Dateien mit 28 neuen und 36 gelöschten Zeilen

Datei anzeigen

@ -31,9 +31,9 @@ import org.geysermc.geyser.api.entity.type.GeyserEntity;
public interface GeyserPlayerEntity extends GeyserEntity { public interface GeyserPlayerEntity extends GeyserEntity {
/** /**
* Gets the position of the player. * Gets the position of the player, as it is known to the Java server.
* *
* @return the position of the player. * @return the player's position
*/ */
Vector3f position(); Vector3f position();
} }

Datei anzeigen

@ -97,11 +97,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
/** /**
* Saves the parrot currently on the player's left shoulder; otherwise null * Saves the parrot currently on the player's left shoulder; otherwise null
*/ */
private ParrotEntity leftParrot; private @Nullable ParrotEntity leftParrot;
/** /**
* Saves the parrot currently on the player's right shoulder; otherwise null * Saves the parrot currently on the player's right shoulder; otherwise null
*/ */
private ParrotEntity rightParrot; private @Nullable ParrotEntity rightParrot;
public PlayerEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, public PlayerEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position,
Vector3f motion, float yaw, float pitch, float headYaw, String username, @Nullable String texturesProperty) { Vector3f motion, float yaw, float pitch, float headYaw, String username, @Nullable String texturesProperty) {
@ -450,6 +450,6 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
@Override @Override
public Vector3f position() { public Vector3f position() {
return this.position.clone(); return this.position.down(definition.offset());
} }
} }

Datei anzeigen

@ -34,17 +34,15 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator; import org.geysermc.geyser.translator.protocol.java.inventory.JavaOpenBookTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
@Getter
public class LecternContainer extends Container { public class LecternContainer extends Container {
@Getter @Setter @Setter
private int currentBedrockPage = 0; private int currentBedrockPage = 0;
@Getter @Setter @Setter
private NbtMap blockEntityTag; private NbtMap blockEntityTag;
@Getter @Setter @Setter
private Vector3i position; private Vector3i position;
// Sigh. When the lectern container is created, we don't know (yet) if it's fake or not.
// So... time for a manual check :/
@Getter
private boolean isFakeLectern = false; private boolean isFakeLectern = false;
public LecternContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) { public LecternContainer(String title, int id, int size, ContainerType containerType, PlayerInventory playerInventory) {
@ -52,8 +50,8 @@ public class LecternContainer extends Container {
} }
/** /**
* When we are using a fake lectern, the Java server expects us to still be in a player inventory. * When the Java server asks the client to open a book in their hotbar, we create a fake lectern to show it to the client.
* We can't use {@link #isUsingRealBlock()} as that may not be determined yet. * We can't use the {@link #isUsingRealBlock()} check as we may also be dealing with a real virtual lectern (with its own inventory).
*/ */
@Override @Override
public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {

Datei anzeigen

@ -157,7 +157,7 @@ public class BlockInventoryHolder extends InventoryHolder {
@Override @Override
public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) {
if (inventory instanceof Container container) { if (inventory instanceof Container container) {
if (container.isUsingRealBlock() && !(inventory instanceof LecternContainer)) { if (container.isUsingRealBlock() && !(container instanceof LecternContainer)) {
// No need to reset a block since we didn't change any blocks // No need to reset a block since we didn't change any blocks
// But send a container close packet because we aren't destroying the original. // But send a container close packet because we aren't destroying the original.
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();

Datei anzeigen

@ -30,7 +30,6 @@ import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.erosion.util.LecternUtils; import org.geysermc.erosion.util.LecternUtils;
import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.inventory.LecternContainer; import org.geysermc.geyser.inventory.LecternContainer;
@ -54,7 +53,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
* Hack: Java opens a lectern first, and then follows it up with a ClientboundContainerSetContentPacket * Hack: Java opens a lectern first, and then follows it up with a ClientboundContainerSetContentPacket
* to actually send the book's contents. We delay opening the inventory until the book was sent. * to actually send the book's contents. We delay opening the inventory until the book was sent.
*/ */
private boolean initialized = false; private boolean receivedBook = false;
public LecternInventoryTranslator() { public LecternInventoryTranslator() {
super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE); super(1, Blocks.LECTERN, org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.LECTERN , ContainerInventoryUpdater.INSTANCE);
@ -63,11 +62,12 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
@Override @Override
public boolean prepareInventory(GeyserSession session, Inventory inventory) { public boolean prepareInventory(GeyserSession session, Inventory inventory) {
super.prepareInventory(session, inventory); super.prepareInventory(session, inventory);
if (((Container) inventory).isUsingRealBlock()) { if (((LecternContainer) inventory).isFakeLectern()) {
initialized = false; // We have to wait until we get the book to show to the client // See JavaOpenBookTranslator; this isn't a lectern but a book in the player inventory
updateBook(session, inventory, inventory.getItem(0));
receivedBook = true;
} else { } else {
updateBook(session, inventory, inventory.getItem(0)); // See JavaOpenBookTranslator; placed here manually receivedBook = false; // We have to wait until we get the book
initialized = true;
} }
return true; return true;
} }
@ -78,7 +78,7 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
// "initialized" indicates whether we've received the book from the Java server yet. // "initialized" indicates whether we've received the book from the Java server yet.
// dropping lectern book is the fun workaround when we have to enter the gui to drop the book. // dropping lectern book is the fun workaround when we have to enter the gui to drop the book.
// Since we leave it immediately... don't open it! // Since we leave it immediately... don't open it!
if (initialized && !session.isDroppingLecternBook()) { if (receivedBook && !session.isDroppingLecternBook()) {
super.openInventory(session, inventory); super.openInventory(session, inventory);
} }
} }
@ -121,8 +121,8 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
boolean isDropping = session.isDroppingLecternBook(); boolean isDropping = session.isDroppingLecternBook();
updateBook(session, inventory, itemStack); updateBook(session, inventory, itemStack);
if (!initialized && !isDropping) { if (!receivedBook && !isDropping) {
initialized = true; receivedBook = true;
openInventory(session, inventory); openInventory(session, inventory);
} }
} }

Datei anzeigen

@ -43,7 +43,6 @@ 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.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.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.item.ItemTranslator;
@ -58,7 +57,6 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.Clientbound
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ -117,7 +115,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
session.getGeyser().getLogger().debug("Using old smithing table workaround? " + oldSmithingTable); session.getGeyser().getLogger().debug("Using old smithing table workaround? " + oldSmithingTable);
session.setOldSmithingTable(oldSmithingTable); session.setOldSmithingTable(oldSmithingTable);
Int2ObjectMap<List<SelectableRecipe>> unsortedStonecutterData = new Int2ObjectOpenHashMap<>(); Int2ObjectMap<List<SelectableRecipe>> rawStonecutterData = new Int2ObjectOpenHashMap<>();
List<SelectableRecipe> stonecutterRecipes = packet.getStonecutterRecipes(); List<SelectableRecipe> stonecutterRecipes = packet.getStonecutterRecipes();
for (SelectableRecipe recipe : stonecutterRecipes) { for (SelectableRecipe recipe : stonecutterRecipes) {
@ -131,19 +129,15 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
session.getGeyser().getLogger().debug("Ignoring stonecutter recipe for weird output: " + recipe); session.getGeyser().getLogger().debug("Ignoring stonecutter recipe for weird output: " + recipe);
continue; continue;
} }
unsortedStonecutterData.computeIfAbsent(ingredient.getHolders()[0], $ -> new ArrayList<>()).add(recipe); rawStonecutterData.computeIfAbsent(ingredient.getHolders()[0], $ -> new ArrayList<>()).add(recipe);
} }
Int2ObjectMap<GeyserStonecutterData> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>(); Int2ObjectMap<GeyserStonecutterData> stonecutterRecipeMap = new Int2ObjectOpenHashMap<>();
for (Int2ObjectMap.Entry<List<SelectableRecipe>> data : unsortedStonecutterData.int2ObjectEntrySet()) { for (Int2ObjectMap.Entry<List<SelectableRecipe>> data : rawStonecutterData.int2ObjectEntrySet()) {
// Sort the list by each output item's Java identifier - this is how it's sorted on Java, and therefore // Implementation note: data used to have to be sorted according to the item translation key.
// We can get the correct order for button pressing // This is no longer necessary as of 1.21.2, and is instead presented in the order the server sends us.
data.getValue().sort(Comparator.comparing((stoneCuttingRecipeData -> // (Recipes are ordered differently between Paper and vanilla)
Registries.JAVA_ITEMS.get().get(((ItemStackSlotDisplay) stoneCuttingRecipeData.recipe()).itemStack().getId()) // See #5150.
// See RecipeManager#getRecipesFor as of 1.21
.translationKey())));
// Now that it's sorted, let's translate these recipes
int buttonId = 0; int buttonId = 0;
for (SelectableRecipe recipe : data.getValue()) { for (SelectableRecipe recipe : data.getValue()) {
// As of 1.16.4, all stonecutter recipes have one ingredient option // As of 1.16.4, all stonecutter recipes have one ingredient option