Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-09-17 00:33:47 +02:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into floodgate-2.0
Dieser Commit ist enthalten in:
Commit
34fa5475ff
@ -113,9 +113,28 @@ public class LivingEntity extends Entity {
|
|||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateEquipment(GeyserSession session) {
|
public void updateAllEquipment(GeyserSession session) {
|
||||||
if (!valid)
|
if (!valid) return;
|
||||||
return;
|
|
||||||
|
updateArmor(session);
|
||||||
|
updateMainHand(session);
|
||||||
|
updateOffHand(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateArmor(GeyserSession session) {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
ItemData helmet = this.helmet;
|
||||||
|
ItemData chestplate = this.chestplate;
|
||||||
|
// If an entity has a banner on them, it will be in the helmet slot in Java but the chestplate spot in Bedrock
|
||||||
|
// But don't overwrite the chestplate if it isn't empty
|
||||||
|
if (chestplate.getId() == ItemData.AIR.getId() && helmet.getId() == ItemRegistry.BANNER.getBedrockId()) {
|
||||||
|
chestplate = this.helmet;
|
||||||
|
helmet = ItemData.AIR;
|
||||||
|
} else if (chestplate.getId() == ItemRegistry.BANNER.getBedrockId()) {
|
||||||
|
// Prevent chestplate banners from showing erroneously
|
||||||
|
chestplate = ItemData.AIR;
|
||||||
|
}
|
||||||
|
|
||||||
MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket();
|
MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket();
|
||||||
armorEquipmentPacket.setRuntimeEntityId(geyserId);
|
armorEquipmentPacket.setRuntimeEntityId(geyserId);
|
||||||
@ -124,6 +143,12 @@ public class LivingEntity extends Entity {
|
|||||||
armorEquipmentPacket.setLeggings(leggings);
|
armorEquipmentPacket.setLeggings(leggings);
|
||||||
armorEquipmentPacket.setBoots(boots);
|
armorEquipmentPacket.setBoots(boots);
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(armorEquipmentPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMainHand(GeyserSession session) {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
MobEquipmentPacket handPacket = new MobEquipmentPacket();
|
MobEquipmentPacket handPacket = new MobEquipmentPacket();
|
||||||
handPacket.setRuntimeEntityId(geyserId);
|
handPacket.setRuntimeEntityId(geyserId);
|
||||||
handPacket.setItem(hand);
|
handPacket.setItem(hand);
|
||||||
@ -131,6 +156,12 @@ public class LivingEntity extends Entity {
|
|||||||
handPacket.setInventorySlot(0);
|
handPacket.setInventorySlot(0);
|
||||||
handPacket.setContainerId(ContainerId.INVENTORY);
|
handPacket.setContainerId(ContainerId.INVENTORY);
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(handPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateOffHand(GeyserSession session) {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
MobEquipmentPacket offHandPacket = new MobEquipmentPacket();
|
MobEquipmentPacket offHandPacket = new MobEquipmentPacket();
|
||||||
offHandPacket.setRuntimeEntityId(geyserId);
|
offHandPacket.setRuntimeEntityId(geyserId);
|
||||||
offHandPacket.setItem(offHand);
|
offHandPacket.setItem(offHand);
|
||||||
@ -138,8 +169,6 @@ public class LivingEntity extends Entity {
|
|||||||
offHandPacket.setInventorySlot(0);
|
offHandPacket.setInventorySlot(0);
|
||||||
offHandPacket.setContainerId(ContainerId.OFFHAND);
|
offHandPacket.setContainerId(ContainerId.OFFHAND);
|
||||||
|
|
||||||
session.sendUpstreamPacket(armorEquipmentPacket);
|
|
||||||
session.sendUpstreamPacket(handPacket);
|
|
||||||
session.sendUpstreamPacket(offHandPacket);
|
session.sendUpstreamPacket(offHandPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +59,13 @@ public class PiglinEntity extends BasePiglinEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateEquipment(GeyserSession session) {
|
public void updateOffHand(GeyserSession session) {
|
||||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly
|
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||||
metadata.getFlags().setFlag(EntityFlag.ADMIRING, offHand.getId() == ItemRegistry.GOLD.getBedrockId());
|
boolean changed = metadata.getFlags().setFlag(EntityFlag.ADMIRING, offHand.getId() == ItemRegistry.GOLD.getBedrockId());
|
||||||
super.updateBedrockMetadata(session);
|
if (changed) {
|
||||||
|
super.updateBedrockMetadata(session);
|
||||||
|
}
|
||||||
|
|
||||||
super.updateEquipment(session);
|
super.updateOffHand(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
|
|
||||||
package org.geysermc.connector.entity.living.monster.raid;
|
package org.geysermc.connector.entity.living.monster.raid;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
|
|
||||||
public class PillagerEntity extends AbstractIllagerEntity {
|
public class PillagerEntity extends AbstractIllagerEntity {
|
||||||
|
|
||||||
@ -38,12 +38,30 @@ public class PillagerEntity extends AbstractIllagerEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateMainHand(GeyserSession session) {
|
||||||
if (entityMetadata.getId() == 16) {
|
checkForCrossbow(session);
|
||||||
// Java Edition always has the Pillager entity as positioning the crossbow
|
|
||||||
metadata.getFlags().setFlag(EntityFlag.USING_ITEM, true);
|
super.updateMainHand(session);
|
||||||
metadata.getFlags().setFlag(EntityFlag.CHARGED, true);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateOffHand(GeyserSession session) {
|
||||||
|
checkForCrossbow(session);
|
||||||
|
|
||||||
|
super.updateOffHand(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for a crossbow in either the mainhand or offhand. If one exists, indicate that the pillager should be posing
|
||||||
|
*/
|
||||||
|
protected void checkForCrossbow(GeyserSession session) {
|
||||||
|
boolean hasCrossbow = this.hand.getId() == ItemRegistry.CROSSBOW.getBedrockId()
|
||||||
|
|| this.offHand.getId() == ItemRegistry.CROSSBOW.getBedrockId();
|
||||||
|
boolean usingItemChanged = metadata.getFlags().setFlag(EntityFlag.USING_ITEM, hasCrossbow);
|
||||||
|
boolean chargedChanged = metadata.getFlags().setFlag(EntityFlag.CHARGED, hasCrossbow);
|
||||||
|
|
||||||
|
if (usingItemChanged || chargedChanged) {
|
||||||
|
updateBedrockMetadata(session);
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public class PlayerEntity extends LivingEntity {
|
|||||||
valid = true;
|
valid = true;
|
||||||
session.sendUpstreamPacket(addPlayerPacket);
|
session.sendUpstreamPacket(addPlayerPacket);
|
||||||
|
|
||||||
updateEquipment(session);
|
updateAllEquipment(session);
|
||||||
updateBedrockAttributes(session);
|
updateBedrockAttributes(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public class SkullPlayerEntity extends PlayerEntity {
|
|||||||
valid = true;
|
valid = true;
|
||||||
session.sendUpstreamPacket(addPlayerPacket);
|
session.sendUpstreamPacket(addPlayerPacket);
|
||||||
|
|
||||||
updateEquipment(session);
|
updateAllEquipment(session);
|
||||||
updateBedrockAttributes(session);
|
updateBedrockAttributes(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class BedrockProtocol {
|
|||||||
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
||||||
* release of the game that Geyser supports.
|
* release of the game that Geyser supports.
|
||||||
*/
|
*/
|
||||||
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v428.V428_CODEC;
|
public static final BedrockPacketCodec DEFAULT_BEDROCK_CODEC = Bedrock_v431.V431_CODEC;
|
||||||
/**
|
/**
|
||||||
* A list of all supported Bedrock versions that can join Geyser
|
* A list of all supported Bedrock versions that can join Geyser
|
||||||
*/
|
*/
|
||||||
@ -55,8 +55,8 @@ public class BedrockProtocol {
|
|||||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v422.V422_CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v422.V422_CODEC.toBuilder()
|
||||||
.minecraftVersion("1.16.200/1.16.201")
|
.minecraftVersion("1.16.200/1.16.201")
|
||||||
.build());
|
.build());
|
||||||
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v428.V428_CODEC);
|
||||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
||||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +44,7 @@ public class ItemEntry {
|
|||||||
private final int bedrockId;
|
private final int bedrockId;
|
||||||
private final int bedrockData;
|
private final int bedrockData;
|
||||||
/**
|
/**
|
||||||
* The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered.
|
* The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered and used as a crafting ingredient.
|
||||||
* Required since 1.16.220.
|
* Required since 1.16.220.
|
||||||
*/
|
*/
|
||||||
private final int bedrockBlockId;
|
private final int bedrockBlockId;
|
||||||
|
@ -38,8 +38,10 @@ import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
|||||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||||
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 it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
|
||||||
@ -77,14 +79,22 @@ public class ItemRegistry {
|
|||||||
* Bamboo item entry, used in PandaEntity.java
|
* Bamboo item entry, used in PandaEntity.java
|
||||||
*/
|
*/
|
||||||
public static ItemEntry BAMBOO;
|
public static ItemEntry BAMBOO;
|
||||||
|
/**
|
||||||
|
* Banner item entry, used in LivingEntity.java
|
||||||
|
*/
|
||||||
|
public static ItemEntry BANNER;
|
||||||
/**
|
/**
|
||||||
* Boat item entries, used in BedrockInventoryTransactionTranslator.java
|
* Boat item entries, used in BedrockInventoryTransactionTranslator.java
|
||||||
*/
|
*/
|
||||||
public static IntList BOATS = new IntArrayList();
|
public static final IntSet BOATS = new IntArraySet();
|
||||||
/**
|
/**
|
||||||
* Bucket item entries (excluding the milk bucket), used in BedrockInventoryTransactionTranslator.java
|
* Bucket item entries (excluding the milk bucket), used in BedrockInventoryTransactionTranslator.java
|
||||||
*/
|
*/
|
||||||
public static IntList BUCKETS = new IntArrayList();
|
public static final IntSet BUCKETS = new IntArraySet();
|
||||||
|
/**
|
||||||
|
* Crossbow item entry, used in PillagerEntity.java
|
||||||
|
*/
|
||||||
|
public static ItemEntry CROSSBOW;
|
||||||
/**
|
/**
|
||||||
* Empty item bucket, used in BedrockInventoryTransactionTranslator.java
|
* Empty item bucket, used in BedrockInventoryTransactionTranslator.java
|
||||||
*/
|
*/
|
||||||
@ -150,6 +160,85 @@ public class ItemRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object2IntMap<String> bedrockBlockIdOverrides = new Object2IntOpenHashMap<>();
|
||||||
|
Set<String> blacklistedIdentifiers = new ObjectOpenHashSet<>();
|
||||||
|
|
||||||
|
// Load creative items
|
||||||
|
// We load this before item mappings to get overridden block runtime ID mappings
|
||||||
|
stream = FileUtils.getResource("bedrock/creative_items.json");
|
||||||
|
|
||||||
|
JsonNode creativeItemEntries;
|
||||||
|
try {
|
||||||
|
creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int netId = 1;
|
||||||
|
List<ItemData> creativeItems = new ArrayList<>();
|
||||||
|
for (JsonNode itemNode : creativeItemEntries) {
|
||||||
|
int count = 1;
|
||||||
|
int damage = 0;
|
||||||
|
int blockRuntimeId = 0;
|
||||||
|
NbtMap tag = null;
|
||||||
|
JsonNode damageNode = itemNode.get("damage");
|
||||||
|
if (damageNode != null) {
|
||||||
|
damage = damageNode.asInt();
|
||||||
|
}
|
||||||
|
JsonNode countNode = itemNode.get("count");
|
||||||
|
if (countNode != null) {
|
||||||
|
count = countNode.asInt();
|
||||||
|
}
|
||||||
|
JsonNode blockRuntimeIdNode = itemNode.get("blockRuntimeId");
|
||||||
|
if (blockRuntimeIdNode != null) {
|
||||||
|
blockRuntimeId = blockRuntimeIdNode.asInt();
|
||||||
|
}
|
||||||
|
JsonNode nbtNode = itemNode.get("nbt_b64");
|
||||||
|
if (nbtNode != null) {
|
||||||
|
byte[] bytes = Base64.getDecoder().decode(nbtNode.asText());
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
|
try {
|
||||||
|
tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String identifier = itemNode.get("id").textValue();
|
||||||
|
int id = -1;
|
||||||
|
for (StartGamePacket.ItemEntry itemEntry : ITEMS) {
|
||||||
|
if (itemEntry.getIdentifier().equals(identifier)) {
|
||||||
|
id = itemEntry.getId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id == -1) {
|
||||||
|
throw new RuntimeException("Unable to find matching Bedrock item for " + identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
creativeItems.add(ItemData.builder()
|
||||||
|
.id(id)
|
||||||
|
.damage(damage)
|
||||||
|
.count(count)
|
||||||
|
.blockRuntimeId(blockRuntimeId)
|
||||||
|
.tag(tag)
|
||||||
|
.netId(netId++).build());
|
||||||
|
|
||||||
|
if (blockRuntimeId != 0) {
|
||||||
|
// Add override for item mapping, unless it already exists... then we know multiple states can exist
|
||||||
|
if (!blacklistedIdentifiers.contains(identifier)) {
|
||||||
|
if (bedrockBlockIdOverrides.containsKey(identifier)) {
|
||||||
|
bedrockBlockIdOverrides.remove(identifier);
|
||||||
|
blacklistedIdentifiers.add(identifier);
|
||||||
|
} else {
|
||||||
|
// Unless there's multiple possibilities for this one state, let this be
|
||||||
|
bedrockBlockIdOverrides.put(identifier, blockRuntimeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load item mappings from Java Edition to Bedrock Edition
|
||||||
stream = FileUtils.getResource("mappings/items.json");
|
stream = FileUtils.getResource("mappings/items.json");
|
||||||
|
|
||||||
JsonNode items;
|
JsonNode items;
|
||||||
@ -181,7 +270,13 @@ public class ItemRegistry {
|
|||||||
int bedrockBlockId = -1;
|
int bedrockBlockId = -1;
|
||||||
JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId");
|
JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId");
|
||||||
if (blockRuntimeIdNode != null) {
|
if (blockRuntimeIdNode != null) {
|
||||||
bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue());
|
int blockIdOverride = bedrockBlockIdOverrides.getOrDefault(bedrockIdentifier, -1);
|
||||||
|
if (blockIdOverride != -1) {
|
||||||
|
// Straight from BDS is our best chance of getting an item that doesn't run into issues
|
||||||
|
bedrockBlockId = blockIdOverride;
|
||||||
|
} else {
|
||||||
|
bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemEntry itemEntry;
|
ItemEntry itemEntry;
|
||||||
@ -218,6 +313,9 @@ public class ItemRegistry {
|
|||||||
case "minecraft:bamboo":
|
case "minecraft:bamboo":
|
||||||
BAMBOO = itemEntry;
|
BAMBOO = itemEntry;
|
||||||
break;
|
break;
|
||||||
|
case "minecraft:crossbow":
|
||||||
|
CROSSBOW = itemEntry;
|
||||||
|
break;
|
||||||
case "minecraft:egg":
|
case "minecraft:egg":
|
||||||
EGG = itemEntry;
|
EGG = itemEntry;
|
||||||
break;
|
break;
|
||||||
@ -233,6 +331,9 @@ public class ItemRegistry {
|
|||||||
case "minecraft:wheat":
|
case "minecraft:wheat":
|
||||||
WHEAT = itemEntry;
|
WHEAT = itemEntry;
|
||||||
break;
|
break;
|
||||||
|
case "minecraft:white_banner": // As of 1.16.220, all banners share the same Bedrock ID and differ their colors through their damage value
|
||||||
|
BANNER = itemEntry;
|
||||||
|
break;
|
||||||
case "minecraft:writable_book":
|
case "minecraft:writable_book":
|
||||||
WRITABLE_BOOK = itemEntry;
|
WRITABLE_BOOK = itemEntry;
|
||||||
break;
|
break;
|
||||||
@ -262,38 +363,8 @@ public class ItemRegistry {
|
|||||||
ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex,
|
ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex,
|
||||||
lodestoneCompassId, 0, -1, 1));
|
lodestoneCompassId, 0, -1, 1));
|
||||||
|
|
||||||
/* Load creative items */
|
|
||||||
stream = FileUtils.getResource("bedrock/creative_items.json");
|
|
||||||
|
|
||||||
JsonNode creativeItemEntries;
|
|
||||||
try {
|
|
||||||
creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
|
|
||||||
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
|
|
||||||
"minecraft:knowledge_book", "minecraft:tipped_arrow");
|
|
||||||
if (!usingFurnaceMinecart) {
|
|
||||||
javaOnlyItems.add("minecraft:furnace_minecart");
|
|
||||||
}
|
|
||||||
JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems);
|
|
||||||
|
|
||||||
int netId = 1;
|
|
||||||
List<ItemData> creativeItems = new ArrayList<>();
|
|
||||||
for (JsonNode itemNode : creativeItemEntries) {
|
|
||||||
ItemData.Builder item = getBedrockItemFromJson(itemNode);
|
|
||||||
int bedrockRuntimeId = 0;
|
|
||||||
ItemEntry itemEntry = getItem(item.build()); // please
|
|
||||||
if (itemEntry.isBlock()) {
|
|
||||||
bedrockRuntimeId = itemEntry.getBedrockBlockId();
|
|
||||||
}
|
|
||||||
creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usingFurnaceMinecart) {
|
if (usingFurnaceMinecart) {
|
||||||
// Add the furnace minecart as an item
|
// Add the furnace minecart as a custom item
|
||||||
int furnaceMinecartId = ITEMS.size() + 1;
|
int furnaceMinecartId = ITEMS.size() + 1;
|
||||||
|
|
||||||
ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true));
|
ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true));
|
||||||
@ -339,6 +410,14 @@ public class ItemRegistry {
|
|||||||
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
|
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
|
||||||
|
|
||||||
ITEM_NAMES = itemNames.toArray(new String[0]);
|
ITEM_NAMES = itemNames.toArray(new String[0]);
|
||||||
|
|
||||||
|
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
|
||||||
|
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
|
||||||
|
"minecraft:knowledge_book", "minecraft:tipped_arrow");
|
||||||
|
if (!usingFurnaceMinecart) {
|
||||||
|
javaOnlyItems.add("minecraft:furnace_minecart");
|
||||||
|
}
|
||||||
|
JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,35 +472,4 @@ public class ItemRegistry {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode}
|
|
||||||
* @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) {
|
|
||||||
int count = 1;
|
|
||||||
short damage = 0;
|
|
||||||
NbtMap tag = null;
|
|
||||||
if (itemNode.has("damage")) {
|
|
||||||
damage = itemNode.get("damage").numberValue().shortValue();
|
|
||||||
}
|
|
||||||
if (itemNode.has("count")) {
|
|
||||||
count = itemNode.get("count").asInt();
|
|
||||||
}
|
|
||||||
if (itemNode.has("nbt_b64")) {
|
|
||||||
byte[] bytes = Base64.getDecoder().decode(itemNode.get("nbt_b64").asText());
|
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
|
||||||
try {
|
|
||||||
tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ItemData.builder()
|
|
||||||
.id(itemNode.get("id").asInt())
|
|
||||||
.damage(damage)
|
|
||||||
.count(count)
|
|
||||||
.tag(tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -276,6 +276,7 @@ public class RecipeRegistry {
|
|||||||
.id(itemEntry.getBedrockId())
|
.id(itemEntry.getBedrockId())
|
||||||
.damage(damage)
|
.damage(damage)
|
||||||
.count(count)
|
.count(count)
|
||||||
|
.blockRuntimeId(itemEntry.isBlock() ? itemEntry.getBedrockBlockId() : 0)
|
||||||
.tag(tag).build();
|
.tag(tag).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,11 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(ServerEntityEquipmentPacket packet, GeyserSession session) {
|
public void translate(ServerEntityEquipmentPacket packet, GeyserSession session) {
|
||||||
Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
Entity entity;
|
||||||
if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
|
if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
|
||||||
entity = session.getPlayerEntity();
|
entity = session.getPlayerEntity();
|
||||||
|
} else {
|
||||||
|
entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
@ -54,30 +56,48 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean armorUpdated = false;
|
||||||
|
boolean mainHandUpdated = false;
|
||||||
|
boolean offHandUpdated = false;
|
||||||
LivingEntity livingEntity = (LivingEntity) entity;
|
LivingEntity livingEntity = (LivingEntity) entity;
|
||||||
for (Equipment equipment : packet.getEquipment()) {
|
for (Equipment equipment : packet.getEquipment()) {
|
||||||
ItemData item = ItemTranslator.translateToBedrock(session, equipment.getItem());
|
ItemData item = ItemTranslator.translateToBedrock(session, equipment.getItem());
|
||||||
switch (equipment.getSlot()) {
|
switch (equipment.getSlot()) {
|
||||||
case HELMET:
|
case HELMET:
|
||||||
livingEntity.setHelmet(item);
|
livingEntity.setHelmet(item);
|
||||||
|
armorUpdated = true;
|
||||||
break;
|
break;
|
||||||
case CHESTPLATE:
|
case CHESTPLATE:
|
||||||
livingEntity.setChestplate(item);
|
livingEntity.setChestplate(item);
|
||||||
|
armorUpdated = true;
|
||||||
break;
|
break;
|
||||||
case LEGGINGS:
|
case LEGGINGS:
|
||||||
livingEntity.setLeggings(item);
|
livingEntity.setLeggings(item);
|
||||||
|
armorUpdated = true;
|
||||||
break;
|
break;
|
||||||
case BOOTS:
|
case BOOTS:
|
||||||
livingEntity.setBoots(item);
|
livingEntity.setBoots(item);
|
||||||
|
armorUpdated = true;
|
||||||
break;
|
break;
|
||||||
case MAIN_HAND:
|
case MAIN_HAND:
|
||||||
livingEntity.setHand(item);
|
livingEntity.setHand(item);
|
||||||
|
mainHandUpdated = true;
|
||||||
break;
|
break;
|
||||||
case OFF_HAND:
|
case OFF_HAND:
|
||||||
livingEntity.setOffHand(item);
|
livingEntity.setOffHand(item);
|
||||||
|
offHandUpdated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
livingEntity.updateEquipment(session);
|
|
||||||
|
if (armorUpdated) {
|
||||||
|
livingEntity.updateArmor(session);
|
||||||
|
}
|
||||||
|
if (mainHandUpdated) {
|
||||||
|
livingEntity.updateMainHand(session);
|
||||||
|
}
|
||||||
|
if (offHandUpdated) {
|
||||||
|
livingEntity.updateOffHand(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
|||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||||
|
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.living.ArmorStandEntity;
|
import org.geysermc.connector.entity.living.ArmorStandEntity;
|
||||||
@ -87,7 +88,13 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
|
|||||||
if (entity.getEntityType() == EntityType.BOAT) {
|
if (entity.getEntityType() == EntityType.BOAT) {
|
||||||
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 1);
|
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 1);
|
||||||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 90f);
|
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 90f);
|
||||||
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, !passengers.isEmpty() ? -90f : 0f);
|
// Can be removed once 1.16.200 to 1.16.201 support is dropped
|
||||||
|
if (session.getUpstream().getSession().getPacketCodec().getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion()) {
|
||||||
|
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 1f);
|
||||||
|
passenger.getMetadata().put(EntityData.RIDER_ROTATION_OFFSET, -90f);
|
||||||
|
} else {
|
||||||
|
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, -90f);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
||||||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
||||||
@ -116,6 +123,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
|
|||||||
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
||||||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
||||||
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
|
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
|
||||||
|
if (session.getUpstream().getSession().getPacketCodec().getProtocolVersion() >= Bedrock_v428.V428_CODEC.getProtocolVersion()) {
|
||||||
|
passenger.getMetadata().put(EntityData.RIDER_ROTATION_OFFSET, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
this.updateOffset(passenger, entity, session, false, false, (packet.getPassengerIds().length > 1));
|
this.updateOffset(passenger, entity, session, false, false, (packet.getPassengerIds().length > 1));
|
||||||
} else {
|
} else {
|
||||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren