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:
Commit
a9577a946e
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren