1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

Implement nautilus inventory translation.

This commit is contained in:
oryxel1
2025-12-11 22:51:55 +07:00
parent 238573536b
commit 5b16f26fc0
7 changed files with 57 additions and 41 deletions

View File

@@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.TrigMath;
import org.cloudburstmc.math.vector.Vector2f;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.living.animal.tameable.TameableEntity;
@@ -62,6 +63,8 @@ public abstract class AbstractNautilusEntity extends TameableEntity implements C
public AbstractNautilusEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw, float defSpeed) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
this.vehicleComponent = new NautilusVehicleComponent(this, 0.0f, defSpeed);
dirtyMetadata.put(EntityDataTypes.CONTAINER_SIZE, 2);
}
@Override

View File

@@ -34,8 +34,8 @@ import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import java.util.Arrays;
public class HorseInventoryUpdater extends InventoryUpdater {
public static final HorseInventoryUpdater INSTANCE = new HorseInventoryUpdater();
public class MountInventoryUpdater extends InventoryUpdater {
public static final MountInventoryUpdater INSTANCE = new MountInventoryUpdater();
@Override
public void updateInventory(InventoryTranslator<?> translator, GeyserSession session, Inventory inventory) {
@@ -58,10 +58,11 @@ public class HorseInventoryUpdater extends InventoryUpdater {
return true;
InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(4); // Horse GUI?
slotPacket.setContainerId(inventory.getBedrockId());
slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot));
slotPacket.setItem(inventory.getItem(javaSlot).getItemData(session));
session.sendUpstreamPacket(slotPacket);
return true;
}
}

View File

@@ -26,17 +26,17 @@
package org.geysermc.geyser.translator.inventory.horse;
import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.updater.HorseInventoryUpdater;
import org.geysermc.geyser.inventory.updater.MountInventoryUpdater;
import org.geysermc.geyser.inventory.updater.InventoryUpdater;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.BaseInventoryTranslator;
public abstract class AbstractHorseInventoryTranslator extends BaseInventoryTranslator<Container> {
public abstract class AbstractMountInventoryTranslator extends BaseInventoryTranslator<Container> {
private final InventoryUpdater updater;
public AbstractHorseInventoryTranslator(int size) {
public AbstractMountInventoryTranslator(int size) {
super(size);
this.updater = HorseInventoryUpdater.INSTANCE;
this.updater = MountInventoryUpdater.INSTANCE;
}
@Override

View File

@@ -36,7 +36,7 @@ import org.geysermc.geyser.session.GeyserSession;
import java.util.Arrays;
public abstract class ChestedHorseInventoryTranslator extends AbstractHorseInventoryTranslator {
public abstract class ChestedHorseInventoryTranslator extends AbstractMountInventoryTranslator {
private final int chestSize;
private final int equipSlot;

View File

@@ -30,8 +30,8 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.ItemSt
import org.geysermc.geyser.inventory.BedrockContainerSlot;
import org.geysermc.geyser.inventory.Container;
public class HorseInventoryTranslator extends AbstractHorseInventoryTranslator {
public HorseInventoryTranslator(int size) {
public class MountInventoryTranslator extends AbstractMountInventoryTranslator {
public MountInventoryTranslator(int size) {
super(size);
}

View File

@@ -32,6 +32,7 @@ import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
import org.geysermc.geyser.entity.type.ChestBoatEntity;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity;
import org.geysermc.geyser.entity.type.living.animal.nautilus.AbstractNautilusEntity;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
@@ -122,7 +123,7 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
case OPEN_INVENTORY:
if (session.getInventoryHolder() == null) {
Entity ridingEntity = session.getPlayerEntity().getVehicle();
if (ridingEntity instanceof AbstractHorseEntity || ridingEntity instanceof ChestBoatEntity) {
if (ridingEntity instanceof AbstractHorseEntity || ridingEntity instanceof AbstractNautilusEntity || ridingEntity instanceof ChestBoatEntity) {
// This mob has an inventory of its own that we should open instead.
ServerboundPlayerCommandPacket openVehicleWindowPacket = new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(), PlayerState.OPEN_VEHICLE_INVENTORY);
session.sendDownstreamGamePacket(openVehicleWindowPacket);

View File

@@ -37,12 +37,13 @@ import org.geysermc.geyser.entity.type.living.animal.horse.ChestedHorseEntity;
import org.geysermc.geyser.entity.type.living.animal.horse.LlamaEntity;
import org.geysermc.geyser.entity.type.living.animal.horse.SkeletonHorseEntity;
import org.geysermc.geyser.entity.type.living.animal.horse.ZombieHorseEntity;
import org.geysermc.geyser.entity.type.living.animal.nautilus.NautilusEntity;
import org.geysermc.geyser.inventory.Container;
import org.geysermc.geyser.inventory.InventoryHolder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.inventory.horse.DonkeyInventoryTranslator;
import org.geysermc.geyser.translator.inventory.horse.HorseInventoryTranslator;
import org.geysermc.geyser.translator.inventory.horse.MountInventoryTranslator;
import org.geysermc.geyser.translator.inventory.horse.LlamaInventoryTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@@ -54,36 +55,24 @@ import java.util.Collections;
import java.util.List;
@Translator(packet = ClientboundMountScreenOpenPacket.class)
public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundMountScreenOpenPacket> {
public class JavaMountScreenOpenTranslator extends PacketTranslator<ClientboundMountScreenOpenPacket> {
private static final String[] ACCEPTED_HORSE_ARMORS = new String[] {"minecraft:horsearmorleather", "minecraft:horsearmoriron",
"minecraft:horsearmorgold", "minecraft:horsearmordiamond", "minecraft:copper_horse_armor", "minecraft:netherite_horse_armor"};
private static final String[] ACCEPTED_NAUTILUS_ARMORS = new String[] {"minecraft:copper_nautilus_armor", "minecraft:iron_nautilus_armor",
"minecraft:golden_nautilus_armor", "minecraft:diamond_nautilus_armor", "minecraft:netherite_nautilus_armor"};
private static final NbtMap ARMOR_SLOT;
private static final NbtMap CARPET_SLOT;
private static final NbtMap SADDLE_SLOT;
private static final NbtMap SADDLE_SLOT, CARPET_SLOT;
private static final NbtMap HORSE_ARMOR_SLOT, NAUTILUS_ARMOR_SLOT;
static {
// Build the NBT mappings that Bedrock wants to lay out the GUI
String[] acceptedHorseArmorIdentifiers = new String[] {"minecraft:horsearmorleather", "minecraft:horsearmoriron",
"minecraft:horsearmorgold", "minecraft:horsearmordiamond"};
NbtMapBuilder armorBuilder = NbtMap.builder();
List<NbtMap> acceptedArmors = new ArrayList<>(4);
for (String identifier : acceptedHorseArmorIdentifiers) {
NbtMapBuilder acceptedItemBuilder = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", identifier);
acceptedArmors.add(NbtMap.builder().putCompound("slotItem", acceptedItemBuilder.build()).build());
}
armorBuilder.putList("acceptedItems", NbtType.COMPOUND, acceptedArmors);
NbtMapBuilder armorItem = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", "minecraft:horsearmoriron");
armorBuilder.putCompound("item", armorItem.build());
armorBuilder.putInt("slotNumber", 1);
ARMOR_SLOT = armorBuilder.build();
HORSE_ARMOR_SLOT = buildAcceptedArmorSlot(ACCEPTED_HORSE_ARMORS, "minecraft:horsearmoriron");
NAUTILUS_ARMOR_SLOT = buildAcceptedArmorSlot(ACCEPTED_NAUTILUS_ARMORS, "minecraft:nautilusarmor");
NbtMapBuilder carpetBuilder = NbtMap.builder();
NbtMapBuilder carpetItem = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", "minecraft:carpet");
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", "minecraft:carpet");
List<NbtMap> acceptedCarpet = Collections.singletonList(NbtMap.builder().putCompound("slotItem", carpetItem.build()).build());
carpetBuilder.putList("acceptedItems", NbtType.COMPOUND, acceptedCarpet);
carpetBuilder.putCompound("item", carpetItem.build());
@@ -92,8 +81,8 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundM
NbtMapBuilder saddleBuilder = NbtMap.builder();
NbtMapBuilder acceptedSaddle = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", "minecraft:saddle");
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", "minecraft:saddle");
List<NbtMap> acceptedItem = Collections.singletonList(NbtMap.builder().putCompound("slotItem", acceptedSaddle.build()).build());
saddleBuilder.putList("acceptedItems", NbtType.COMPOUND, acceptedItem);
saddleBuilder.putCompound("item", acceptedSaddle.build());
@@ -101,6 +90,26 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundM
SADDLE_SLOT = saddleBuilder.build();
}
private static NbtMap buildAcceptedArmorSlot(String[] accepted, String name) {
NbtMapBuilder armorBuilder = NbtMap.builder();
List<NbtMap> acceptedArmors = new ArrayList<>(4);
for (String identifier : accepted) {
NbtMapBuilder acceptedItemBuilder = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", identifier);
acceptedArmors.add(NbtMap.builder().putCompound("slotItem", acceptedItemBuilder.build()).build());
}
armorBuilder.putList("acceptedItems", NbtType.COMPOUND, acceptedArmors);
NbtMapBuilder armorItem = NbtMap.builder()
.putShort("Aux", Short.MAX_VALUE)
.putString("Name", name);
armorBuilder.putCompound("item", armorItem.build());
armorBuilder.putInt("slotNumber", 1);
return armorBuilder.build();
}
@Override
public void translate(GeyserSession session, ClientboundMountScreenOpenPacket packet) {
Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
@@ -141,10 +150,12 @@ public class JavaHorseScreenOpenTranslator extends PacketTranslator<ClientboundM
inventoryTranslator = new DonkeyInventoryTranslator(slotCount);
slots.add(SADDLE_SLOT);
} else {
inventoryTranslator = new HorseInventoryTranslator(slotCount);
inventoryTranslator = new MountInventoryTranslator(slotCount);
slots.add(SADDLE_SLOT);
if (!(entity instanceof SkeletonHorseEntity || entity instanceof ZombieHorseEntity)) {
slots.add(ARMOR_SLOT);
if (entity instanceof NautilusEntity) {
slots.add(NAUTILUS_ARMOR_SLOT);
} else if (!(entity instanceof SkeletonHorseEntity || entity instanceof ZombieHorseEntity)) {
slots.add(HORSE_ARMOR_SLOT);
}
}