Update to latest MCProtocolLib

This commit is contained in:
Camotoy 2024-06-12 23:48:40 -04:00
parent 3528b1d692
commit be04ff2a13
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
29 changed files with 135 additions and 96 deletions

View file

@ -220,7 +220,7 @@ public class SessionPlayerEntity extends PlayerEntity {
public void setLastDeathPosition(@Nullable GlobalPos pos) {
if (pos != null) {
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_POS, pos.getPosition());
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension()));
dirtyMetadata.put(EntityDataTypes.PLAYER_LAST_DEATH_DIMENSION, DimensionUtils.javaToBedrock(pos.getDimension().asString()));
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, true);
} else {
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, false);

View file

@ -26,7 +26,9 @@
package org.geysermc.geyser.inventory.item;
import lombok.Getter;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.util.MinecraftKey;
import java.util.Locale;
@ -78,17 +80,17 @@ public enum BannerPattern {
private static final BannerPattern[] VALUES = values();
private final String javaIdentifier;
private final Key javaIdentifier;
private final String bedrockIdentifier;
BannerPattern(String bedrockIdentifier) {
this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT);
this.javaIdentifier = MinecraftKey.key(this.name().toLowerCase(Locale.ROOT));
this.bedrockIdentifier = bedrockIdentifier;
}
public static @Nullable BannerPattern getByJavaIdentifier(String javaIdentifier) {
public static @Nullable BannerPattern getByJavaIdentifier(Key key) {
for (BannerPattern bannerPattern : VALUES) {
if (bannerPattern.javaIdentifier.equals(javaIdentifier)) {
if (bannerPattern.javaIdentifier.equals(key)) {
return bannerPattern;
}
}

View file

@ -47,7 +47,7 @@ public final class TrimRecipe {
public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates");
public static TrimMaterial readTrimMaterial(GeyserSession session, RegistryEntry entry) {
String key = stripMinecraftNamespace(entry.getId());
String key = entry.getId().asMinimalString();
// Color is used when hovering over the item
// Find the nearest legacy color from the RGB Java gives us to work with
@ -67,7 +67,7 @@ public final class TrimRecipe {
}
public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) {
String key = stripMinecraftNamespace(entry.getId());
String key = entry.getId().asMinimalString();
String itemIdentifier = entry.getData().getString("template_item");
ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier);
@ -78,19 +78,6 @@ public final class TrimRecipe {
return new TrimPattern(itemMapping.getBedrockIdentifier(), key);
}
// TODO find a good place for a stripNamespace util method
private static String stripMinecraftNamespace(String identifier) {
int i = identifier.indexOf(':');
if (i >= 0) {
String namespace = identifier.substring(0, i);
// Only strip minecraft namespace
if (namespace.equals("minecraft")) {
return identifier.substring(i + 1);
}
}
return identifier;
}
private TrimRecipe() {
//no-op
}

View file

@ -31,6 +31,7 @@ import org.geysermc.geyser.inventory.item.BedrockEnchantment;
import org.geysermc.geyser.session.cache.tags.EnchantmentTag;
import org.geysermc.geyser.session.cache.tags.ItemTag;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import java.util.HashSet;
@ -59,11 +60,11 @@ public record Enchantment(String identifier,
int maxLevel = data.getInt("max_level");
int anvilCost = data.getInt("anvil_cost");
String exclusiveSet = data.getString("exclusive_set", null);
EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1));
BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId());
EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(MinecraftKey.key(exclusiveSet.substring(1)));
BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId().asString());
String description = bedrockEnchantment == null ? MessageTranslator.deserializeDescription(data) : null;
return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel,
return new Enchantment(entry.getId().asString(), effects, ItemTag.ALL_ITEM_TAGS.get(MinecraftKey.key(supportedItems)), maxLevel,
description, anvilCost, exclusiveSetTag, bedrockEnchantment);
}

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.item.type;
import it.unimi.dsi.fastutil.Pair;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
@ -40,8 +41,8 @@ import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistry;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
@ -106,7 +107,7 @@ public class BannerItem extends BlockItem {
if (color != pair.right()) {
return false;
}
String id = Identifier.formalize(patternLayer.getString("pattern")); // Ouch
Key id = MinecraftKey.key(patternLayer.getString("pattern")); // Ouch
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(id);
if (bannerPattern != pair.left()) {
return false;
@ -166,7 +167,7 @@ public class BannerItem extends BlockItem {
*/
private static NbtMap getBedrockBannerPattern(NbtMap pattern) {
// ViaVersion 1.20.4 -> 1.20.5 can send without the namespace
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(Identifier.formalize(pattern.getString("pattern")));
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(MinecraftKey.key(pattern.getString("pattern")));
DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color"));
if (bannerPattern == null || dyeColor == null) {
return null;

View file

@ -45,7 +45,7 @@ import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.ItemTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DyedItemColor;
@ -65,7 +65,7 @@ public class Item {
private final int maxDamage;
public Item(String javaIdentifier, Builder builder) {
this.javaIdentifier = Identifier.formalize(javaIdentifier).intern();
this.javaIdentifier = MinecraftKey.key(javaIdentifier).asString().intern();
this.stackSize = builder.stackSize;
this.maxDamage = builder.maxDamage;
this.attackDamage = builder.attackDamage;

View file

@ -28,6 +28,7 @@ package org.geysermc.geyser.level;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.kyori.adventure.key.Key;
import java.util.Locale;
@ -90,9 +91,12 @@ public enum PaintingType {
private final int width;
private final int height;
public static PaintingType getByName(String javaName) {
public static PaintingType getByName(Key key) {
if (!key.namespace().equals("minecraft")) {
return null;
}
for (PaintingType paintingName : VALUES) {
if (("minecraft:" + paintingName.name().toLowerCase(Locale.ROOT)).equals(javaName)) return paintingName;
if (paintingName.name().toLowerCase(Locale.ROOT).equals(key.value())) return paintingName;
}
return null;
}

View file

@ -27,7 +27,6 @@ package org.geysermc.geyser.registry.mappings.versions;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -35,14 +34,9 @@ import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.block.custom.CustomBlockData;
import org.geysermc.geyser.api.block.custom.CustomBlockPermutation;
import org.geysermc.geyser.api.block.custom.CustomBlockState;
import org.geysermc.geyser.api.block.custom.component.BoxComponent;
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents;
import org.geysermc.geyser.api.block.custom.component.GeometryComponent;
import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
import org.geysermc.geyser.api.block.custom.component.PlacementConditions;
import org.geysermc.geyser.api.block.custom.component.*;
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.BlockFilterType;
import org.geysermc.geyser.api.block.custom.component.PlacementConditions.Face;
import org.geysermc.geyser.api.block.custom.component.TransformationComponent;
import org.geysermc.geyser.api.item.custom.CustomItemData;
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
import org.geysermc.geyser.api.util.CreativeCategory;
@ -60,16 +54,10 @@ import org.geysermc.geyser.registry.mappings.util.CustomBlockStateMapping;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.util.BlockUtils;
import org.geysermc.geyser.util.MathUtils;
import org.geysermc.geyser.util.MinecraftKey;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
@ -131,7 +119,7 @@ public class MappingsReader_v1 extends MappingsReader {
blocksNode.fields().forEachRemaining(entry -> {
if (entry.getValue().isObject()) {
try {
String identifier = Identifier.formalize(entry.getKey());
String identifier = MinecraftKey.key(entry.getKey()).asString();
CustomBlockMapping customBlockMapping = this.readBlockMappingEntry(identifier, entry.getValue());
consumer.accept(identifier, customBlockMapping);
} catch (Exception e) {

View file

@ -40,6 +40,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -290,7 +291,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
* Keeps track of the world name for respawning.
*/
@Setter
private String worldName = null;
private Key worldName = null;
/**
* As of Java 1.19.3, the client only uses these for commands.
*/

View file

@ -27,6 +27,7 @@ package org.geysermc.geyser.session.cache;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
@ -64,7 +65,7 @@ public final class LodestoneCache {
int x = position.getX();
int y = position.getY();
int z = position.getZ();
String dim = position.getDimension();
Key dim = position.getDimension();
for (LodestonePos pos : this.activeLodestones.values()) {
if (pos.equals(x, y, z, dim)) {
@ -98,7 +99,7 @@ public final class LodestoneCache {
int x = position.getX();
int y = position.getY();
int z = position.getZ();
String dim = position.getDimension();
Key dim = position.getDimension();
for (LodestonePos pos : this.activeLodestones.values()) {
if (pos.equals(x, y, z, dim)) {
@ -138,8 +139,8 @@ public final class LodestoneCache {
this.lodestones.clear();
}
public record LodestonePos(int id, int x, int y, int z, String dimension) {
boolean equals(int x, int y, int z, String dimension) {
public record LodestonePos(int id, int x, int y, int z, Key dimension) {
boolean equals(int x, int y, int z, Key dimension) {
return this.x == x && this.y == y && this.z == z && this.dimension.equals(dimension);
}
}

View file

@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.kyori.adventure.key.Key;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
@ -47,6 +48,7 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistry;
import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry;
import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
@ -70,8 +72,8 @@ import java.util.function.ToIntFunction;
@Accessors(fluent = true)
@Getter
public final class RegistryCache {
private static final Map<String, Map<String, NbtMap>> DEFAULTS;
private static final Map<String, BiConsumer<RegistryCache, List<RegistryEntry>>> REGISTRIES = new HashMap<>();
private static final Map<Key, Map<String, NbtMap>> DEFAULTS;
private static final Map<Key, BiConsumer<RegistryCache, List<RegistryEntry>>> REGISTRIES = new HashMap<>();
static {
register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry));
@ -83,14 +85,14 @@ public final class RegistryCache {
register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern);
register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome);
register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId()));
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId()));
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId().asString()));
// Load from MCProtocolLib's classloader
NbtMap tag = MinecraftProtocol.loadNetworkCodec();
Map<String, Map<String, NbtMap>> defaults = new HashMap<>();
Map<Key, Map<String, NbtMap>> defaults = new HashMap<>();
// Don't create a keySet - no need to create the cached object in HashMap if we don't use it again
REGISTRIES.forEach((key, $) -> {
List<NbtMap> rawValues = tag.getCompound(key)
List<NbtMap> rawValues = tag.getCompound(key.asString())
.getList("value", NbtType.COMPOUND);
Map<String, NbtMap> values = new HashMap<>();
for (NbtMap value : rawValues) {
@ -148,7 +150,7 @@ public final class RegistryCache {
* @param <T> the class that represents these entries.
*/
private static <T> void register(String registry, Function<RegistryCache, JavaRegistry<T>> localCacheFunction, BiFunction<GeyserSession, RegistryEntry, T> reader) {
String key = "minecraft:" + registry;
Key key = MinecraftKey.key(registry);
REGISTRIES.put(key, (registryCache, entries) -> {
Map<String, NbtMap> localRegistry = null;
JavaRegistry<T> localCache = localCacheFunction.apply(registryCache);
@ -176,7 +178,7 @@ public final class RegistryCache {
* @param localCacheFunction the int array to set the final values to.
*/
private static void register(String registry, BiConsumer<RegistryCache, int[]> localCacheFunction, ToIntFunction<RegistryEntry> reader) {
REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> {
REGISTRIES.put(MinecraftKey.key(registry), (registryCache, entries) -> {
Int2IntMap temp = new Int2IntOpenHashMap();
int greatestId = 0;
for (int i = 0; i < entries.size(); i++) {

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.session.cache;
import it.unimi.dsi.fastutil.ints.IntArrays;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserLogger;
@ -36,6 +37,7 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.tags.BlockTag;
import org.geysermc.geyser.session.cache.tags.EnchantmentTag;
import org.geysermc.geyser.session.cache.tags.ItemTag;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.geyser.util.Ordered;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
@ -58,33 +60,33 @@ public final class TagCache {
private final int[][] enchantments = new int[ALL_ENCHANTMENT_TAGS.size()][];
public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) {
Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
Map<Key, int[]> blockTags = packet.getTags().get(MinecraftKey.key("block"));
loadTags("Block", blockTags, ALL_BLOCK_TAGS, this.blocks);
// Hack btw
GeyserLogger logger = session.getGeyser().getLogger();
int[] convertableToMud = blockTags.get("minecraft:convertable_to_mud");
int[] convertableToMud = blockTags.get(MinecraftKey.key("convertable_to_mud"));
boolean emulatePost1_18Logic = convertableToMud != null && convertableToMud.length != 0;
session.setEmulatePost1_18Logic(emulatePost1_18Logic);
if (logger.isDebug()) {
logger.debug("Emulating post 1.18 block predication logic for " + session.bedrockUsername() + "? " + emulatePost1_18Logic);
}
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
Map<Key, int[]> itemTags = packet.getTags().get(MinecraftKey.key("item"));
loadTags("Item", itemTags, ALL_ITEM_TAGS, this.items);
// Hack btw
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
boolean emulatePost1_13Logic = itemTags.get(MinecraftKey.key("signs")).length > 1;
session.setEmulatePost1_13Logic(emulatePost1_13Logic);
if (logger.isDebug()) {
logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic);
}
Map<String, int[]> enchantmentTags = packet.getTags().get("minecraft:enchantment");
Map<Key, int[]> enchantmentTags = packet.getTags().get(MinecraftKey.key("enchantment"));
loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments);
}
private <T extends Ordered> void loadTags(String type, @Nullable Map<String, int[]> packetTags, Map<String, T> allTags, int[][] localValues) {
private <T extends Ordered> void loadTags(String type, @Nullable Map<Key, int[]> packetTags, Map<Key, T> allTags, int[][] localValues) {
if (packetTags == null) {
Arrays.fill(localValues, IntArrays.EMPTY_ARRAY);
GeyserImpl.getInstance().getLogger().debug("Not loading " + type + " tags; they do not exist here.");

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.session.cache.tags;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.util.Ordered;
import java.util.HashMap;
@ -32,7 +33,7 @@ import java.util.Map;
@SuppressWarnings("unused")
public final class BlockTag implements Ordered {
public static final Map<String, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
public static final Map<Key, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
public static final BlockTag WOOL = new BlockTag("wool");
public static final BlockTag PLANKS = new BlockTag("planks");
@ -232,6 +233,6 @@ public final class BlockTag implements Ordered {
}
private static void register(String name, BlockTag tag) {
ALL_BLOCK_TAGS.put(("minecraft:" + name).intern(), tag);
ALL_BLOCK_TAGS.put(Key.key(name), tag);
}
}

View file

@ -25,6 +25,8 @@
package org.geysermc.geyser.session.cache.tags;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.geyser.util.Ordered;
import java.util.HashMap;
@ -32,7 +34,7 @@ import java.util.Map;
@SuppressWarnings("unused")
public final class EnchantmentTag implements Ordered {
public static final Map<String, EnchantmentTag> ALL_ENCHANTMENT_TAGS = new HashMap<>();
public static final Map<Key, EnchantmentTag> ALL_ENCHANTMENT_TAGS = new HashMap<>();
public static final EnchantmentTag TOOLTIP_ORDER = new EnchantmentTag("tooltip_order");
public static final EnchantmentTag EXCLUSIVE_SET_ARMOR = new EnchantmentTag("exclusive_set/armor");
@ -84,6 +86,6 @@ public final class EnchantmentTag implements Ordered {
}
private static void register(String name, EnchantmentTag tag) {
ALL_ENCHANTMENT_TAGS.put(("minecraft:" + name).intern(), tag);
ALL_ENCHANTMENT_TAGS.put(MinecraftKey.key(name), tag);
}
}

View file

@ -25,6 +25,8 @@
package org.geysermc.geyser.session.cache.tags;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.geyser.util.Ordered;
import java.util.HashMap;
@ -32,7 +34,7 @@ import java.util.Map;
@SuppressWarnings("unused")
public final class ItemTag implements Ordered {
public static final Map<String, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
public static final Map<Key, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
public static final ItemTag WOOL = new ItemTag("wool");
public static final ItemTag PLANKS = new ItemTag("planks");
@ -195,6 +197,6 @@ public final class ItemTag implements Ordered {
}
private static void register(String name, ItemTag tag) {
ALL_ITEM_TAGS.put(("minecraft:" + name).intern(), tag);
ALL_ITEM_TAGS.put(MinecraftKey.key(name), tag);
}
}

View file

@ -45,7 +45,7 @@ import org.geysermc.geyser.session.GeyserSession;
public class BiomeTranslator {
public static int loadServerBiome(RegistryEntry entry) {
String javaIdentifier = entry.getId();
String javaIdentifier = entry.getId().asString();
return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0);
}

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.translator.protocol.bedrock;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetJigsawBlockPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket;
import org.cloudburstmc.math.vector.Vector3i;
@ -119,7 +120,8 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator<BlockEnti
String finalState = tag.getString("final_state");
String joint = tag.getString("joint");
// last two parameters are priority values that Bedrock doesn't have (yet?)
ServerboundSetJigsawBlockPacket jigsawPacket = new ServerboundSetJigsawBlockPacket(pos, name, target, pool,
ServerboundSetJigsawBlockPacket jigsawPacket = new ServerboundSetJigsawBlockPacket(pos,
MinecraftKey.key(name), MinecraftKey.key(target), MinecraftKey.key(pool),
finalState, joint, 0, 0);
session.sendDownstreamGamePacket(jigsawPacket);
}

View file

@ -58,7 +58,7 @@ public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTran
// Build the NBT data for the update
NbtMapBuilder builder = NbtMap.builder();
builder.putInt("dim", DimensionUtils.javaToBedrock(pos.dimension()));
builder.putInt("dim", DimensionUtils.javaToBedrock(pos.dimension().asString()));
builder.putString("id", "0x" + String.format("%08X", packet.getTrackingId()));
builder.putByte("version", (byte) 1); // Not sure what this is for

View file

@ -39,6 +39,7 @@ public class JavaClientboundRecipesTranslator extends PacketTranslator<Clientbou
@Override
public void translate(GeyserSession session, ClientboundRecipePacket packet) {
System.out.println(packet);
UnlockedRecipesPacket recipesPacket = new UnlockedRecipesPacket();
switch (packet.getAction()) {
case INIT -> {

View file

@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import lombok.Getter;
import lombok.ToString;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.format.NamedTextColor;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.cloudburstmc.protocol.bedrock.data.command.*;
@ -66,7 +67,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
*/
private static final Supplier<String[]> ALL_BLOCK_NAMES = Suppliers.memoize(() -> BlockRegistries.JAVA_BLOCKS.get().stream().map(block -> block.javaIdentifier().toString()).toArray(String[]::new));
private static final String[] ALL_EFFECT_IDENTIFIERS = EntityUtils.getAllEffectIdentifiers();
private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(AttributeType::getIdentifier).toList().toArray(new String[0]);
private static final String[] ATTRIBUTES = AttributeType.Builtin.BUILTIN.values().stream().map(type -> type.getIdentifier().asString()).toList().toArray(new String[0]);
private static final String[] ENUM_BOOLEAN = {"true", "false"};
private static final String[] VALID_COLORS;
private static final String[] VALID_SCOREBOARD_SLOTS;
@ -264,8 +265,8 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
};
}
private static Object handleResource(CommandBuilderContext context, String resource, boolean tags) {
return switch (resource) {
private static Object handleResource(CommandBuilderContext context, Key resource, boolean tags) {
return switch (resource.asString()) {
case "minecraft:attribute" -> ATTRIBUTES;
case "minecraft:enchantment" -> context.getEnchantments();
case "minecraft:entity_type" -> context.getEntityTypes();
@ -476,12 +477,8 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
*/
private static String getEnumDataName(CommandNode node) {
if (node.getProperties() instanceof ResourceProperties properties) {
String registryKey = properties.getRegistryKey();
int identifierSplit = registryKey.indexOf(':');
if (identifierSplit != -1) {
return registryKey.substring(identifierSplit);
}
return registryKey;
Key registryKey = properties.getRegistryKey();
return registryKey.value();
}
return node.getParser().name();
}

View file

@ -54,7 +54,7 @@ public class JavaCustomPayloadTranslator extends PacketTranslator<ClientboundCus
@Override
public void translate(GeyserSession session, ClientboundCustomPayloadPacket packet) {
String channel = packet.getChannel();
String channel = packet.getChannel().asString();
if (channel.equals(Constants.PLUGIN_MESSAGE)) {
ByteBuf buf = Unpooled.wrappedBuffer(packet.getData());
@ -92,7 +92,7 @@ public class JavaCustomPayloadTranslator extends PacketTranslator<ClientboundCus
System.arraycopy(raw, 0, finalData, 2, raw.length);
}
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(channel, finalData));
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(packet.getChannel(), finalData));
});
session.sendForm(form);
});

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.protocol.java;
import com.github.steveice10.mc.auth.data.GameProfile;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
@ -72,7 +73,7 @@ public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameP
session.getClientData().setOriginalString(null);
// configuration phase stuff that the vanilla client replies with after receiving the GameProfilePacket
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:brand", PluginMessageUtils.getGeyserBrandData()));
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(Key.key("brand"), PluginMessageUtils.getGeyserBrandData()));
session.sendJavaClientSettings();
}
}

View file

@ -25,7 +25,9 @@
package org.geysermc.geyser.translator.protocol.java;
import net.kyori.adventure.key.Key;
import org.geysermc.erosion.Constants;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo;
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
@ -47,6 +49,7 @@ import org.geysermc.geyser.util.DimensionUtils;
import org.geysermc.geyser.util.EntityUtils;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@Translator(packet = ClientboundLoginPacket.class)
public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket> {
@ -98,7 +101,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
}
session.setWorldName(spawnInfo.getWorldName());
session.setLevels(packet.getWorldNames());
session.setLevels(Arrays.stream(packet.getWorldNames()).map(Key::asString).toArray(String[]::new));
session.setGameMode(spawnInfo.getGameMode());
int newDimension = spawnInfo.getDimension();
@ -134,10 +137,11 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
// as the bedrock client isn't required to send a render distance
session.sendJavaClientSettings();
Key register = MinecraftKey.key("register");
if (session.remoteServer().authType() == AuthType.FLOODGATE) {
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:register", PluginMessageChannels.getFloodgateRegisterData()));
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, PluginMessageChannels.getFloodgateRegisterData()));
}
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:register", Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
if (newDimension != session.getDimension()) {
DimensionUtils.switchDimension(session, newDimension);

View file

@ -119,14 +119,14 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData();
List<String> bedrockRecipeIDs = context.translateShapelessRecipe(new GeyserShapelessRecipe(shapelessRecipeData));
if (bedrockRecipeIDs != null) {
context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
context.addRecipeIdentifier(session, recipe.getIdentifier().asString(), bedrockRecipeIDs);
}
}
case CRAFTING_SHAPED -> {
ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData();
List<String> bedrockRecipeIDs = context.translateShapedRecipe(new GeyserShapedRecipe(shapedRecipeData));
if (bedrockRecipeIDs != null) {
context.addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
context.addRecipeIdentifier(session, recipe.getIdentifier().asString(), bedrockRecipeIDs);
}
}
case STONECUTTING -> {
@ -160,7 +160,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
for (ItemStack addition : data.getAddition().getOptions()) {
ItemDescriptorWithCount bedrockAddition = ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, addition));
String id = recipe.getIdentifier();
String id = recipe.getIdentifier().asString();
// Note: vanilla inputs use aux value of Short.MAX_VALUE
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData.of(id,
bedrockTemplate, bedrockBase, bedrockAddition, output, "smithing_table", context.getAndIncrementNetId()));
@ -501,7 +501,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
case CRAFTING_SPECIAL_TIPPEDARROW ->
// similar as above
"minecraft:arrow";
default -> recipe.getIdentifier();
default -> recipe.getIdentifier().asString();
};
addRecipeIdentifier(session, javaRecipeID, identifiers);

View file

@ -35,6 +35,6 @@ public class JavaStoreCookieTranslator extends PacketTranslator<ClientboundStore
@Override
public void translate(GeyserSession session, ClientboundStoreCookiePacket packet) {
session.getCookies().put(packet.getKey(), packet.getPayload());
session.getCookies().put(packet.getKey().asString(), packet.getPayload());
}
}

View file

@ -47,7 +47,7 @@ public class JavaStopSoundTranslator extends PacketTranslator<ClientboundStopSou
}
StopSoundPacket stopSoundPacket = new StopSoundPacket();
stopSoundPacket.setSoundName(SoundUtils.translatePlaySound(packet.getSound()));
stopSoundPacket.setSoundName(SoundUtils.translatePlaySound(packet.getSound().asString()));
stopSoundPacket.setStoppingAllSound(false);
session.sendUpstreamPacket(stopSoundPacket);

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.util;
import net.kyori.adventure.key.Key;
import org.intellij.lang.annotations.Subst;
public final class MinecraftKey {
/**
* To prevent constant warnings from invalid regex.
*/
public static Key key(@Subst("empty") String s) {
return Key.key(s);
}
}

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.util;
import com.google.common.base.Charsets;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
@ -54,7 +55,7 @@ public class PluginMessageUtils {
}
public static void sendMessage(GeyserSession session, String channel, byte[] data) {
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(channel, data));
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(Key.key(channel), data));
}
private static byte[] writeVarInt(int value) {

View file

@ -13,7 +13,7 @@ websocket = "1.5.1"
protocol = "3.0.0.Beta2-20240606.172607-7"
raknet = "1.0.0.CR3-20240416.144209-1"
mcauthlib = "e5b0bcc"
mcprotocollib = "784e91c"
mcprotocollib = "f9cc9ee6"
adventure = "4.14.0"
adventure-platform = "4.3.0"
junit = "5.9.2"