mirror of https://github.com/GeyserMC/Geyser.git
Support for v588 client and mappings
This commit is contained in:
parent
f712d4dd81
commit
a9d64de070
|
@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
|
|||
import com.github.steveice10.mc.protocol.codec.PacketCodec;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v588.Bedrock_v588;
|
||||
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
|
@ -44,9 +45,8 @@ public final class GameProtocol {
|
|||
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
||||
* release of the game that Geyser supports.
|
||||
*/
|
||||
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v582.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.81")
|
||||
.build();
|
||||
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v588.CODEC;
|
||||
|
||||
/**
|
||||
* A list of all supported Bedrock versions that can join Geyser
|
||||
*/
|
||||
|
@ -59,9 +59,10 @@ public final class GameProtocol {
|
|||
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
|
||||
|
||||
static {
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v582.CODEC.toBuilder()
|
||||
.minecraftVersion("1.19.80/1.19.81")
|
||||
.build());
|
||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,7 +82,7 @@ public final class GameProtocol {
|
|||
/* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */
|
||||
|
||||
public static boolean isPre1_20(GeyserSession session) {
|
||||
return session.getUpstream().getProtocolVersion() >= Bedrock_v582.CODEC.getProtocolVersion();
|
||||
return session.getUpstream().getProtocolVersion() < Bedrock_v588.CODEC.getProtocolVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.google.common.collect.Interners;
|
|||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.cloudburstmc.nbt.*;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v588.Bedrock_v588;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
|
@ -67,8 +68,53 @@ public final class BlockRegistryPopulator {
|
|||
|
||||
private static void registerBedrockBlocks() {
|
||||
BiFunction<String, NbtMapBuilder, String> emptyMapper = (bedrockIdentifier, statesBuilder) -> null;
|
||||
|
||||
// We are using mappings that directly support 1.20, so this maps it back to 1.19.80
|
||||
BiFunction<String, NbtMapBuilder, String> legacyMapper = (bedrockIdentifier, statesBuilder) -> {
|
||||
if (bedrockIdentifier.endsWith("pumpkin")) {
|
||||
String direction = statesBuilder.remove("minecraft:cardinal_direction").toString();
|
||||
statesBuilder.putInt("direction", switch (direction) {
|
||||
case "north" -> 2;
|
||||
case "east" -> 3;
|
||||
case "west" -> 1;
|
||||
default -> 0; // south
|
||||
});
|
||||
} else if (bedrockIdentifier.endsWith("carpet") && !bedrockIdentifier.startsWith("minecraft:moss")) {
|
||||
String color = bedrockIdentifier.replace("minecraft:", "").replace("_carpet", "");
|
||||
if (color.equals("light_gray")) {
|
||||
color = "silver";
|
||||
}
|
||||
statesBuilder.putString("color", color);
|
||||
return "minecraft:carpet";
|
||||
} else if (bedrockIdentifier.equals("minecraft:sniffer_egg")) {
|
||||
statesBuilder.remove("cracked_state");
|
||||
return "minecraft:dragon_egg";
|
||||
} else if (bedrockIdentifier.endsWith("coral")) {
|
||||
statesBuilder.putString("coral_color", "blue"); // all blue
|
||||
statesBuilder.putBoolean("dead_bit", bedrockIdentifier.startsWith("minecraft:dead"));
|
||||
return "minecraft:coral";
|
||||
} else if (bedrockIdentifier.endsWith("sculk_sensor")) {
|
||||
int phase = (int) statesBuilder.remove("sculk_sensor_phase");
|
||||
statesBuilder.putBoolean("powered_bit", phase != 0);
|
||||
} else if (bedrockIdentifier.endsWith("pitcher_plant")) {
|
||||
statesBuilder.putString("double_plant_type", "sunflower");
|
||||
return "minecraft:double_plant";
|
||||
} else if (bedrockIdentifier.endsWith("pitcher_crop")) {
|
||||
statesBuilder.remove("growth");
|
||||
if (((byte) statesBuilder.remove("upper_block_bit")) == 1){
|
||||
statesBuilder.putString("flower_type", "orchid");
|
||||
return "minecraft:red_flower"; // top
|
||||
}
|
||||
statesBuilder.putBoolean("update_bit", false);
|
||||
return "minecraft:flower_pot"; // bottom
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
ImmutableMap<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>> blockMappers = ImmutableMap.<ObjectIntPair<String>, BiFunction<String, NbtMapBuilder, String>>builder()
|
||||
.put(ObjectIntPair.of("1_19_80", Bedrock_v582.CODEC.getProtocolVersion()), emptyMapper)
|
||||
.put(ObjectIntPair.of("1_19_80", Bedrock_v582.CODEC.getProtocolVersion()), legacyMapper)
|
||||
.put(ObjectIntPair.of("1_20_0", Bedrock_v588.CODEC.getProtocolVersion()), emptyMapper)
|
||||
.build();
|
||||
|
||||
// We can keep this strong as nothing should be garbage collected
|
||||
|
@ -131,8 +177,8 @@ public final class BlockRegistryPopulator {
|
|||
|
||||
GeyserBedrockBlock bedrockDefinition = blockStateOrderedMap.get(buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
||||
if (bedrockDefinition == null) {
|
||||
throw new RuntimeException("Unable to find " + javaId + " Bedrock BlockDefinition! Built NBT tag: \n" +
|
||||
buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
||||
throw new RuntimeException("Unable to find " + javaId + " Bedrock BlockDefinition on version "
|
||||
+ palette.getKey().key() + "! Built NBT tag: \n" + buildBedrockState(entry.getValue(), stateVersion, stateMapper));
|
||||
}
|
||||
|
||||
switch (javaId) {
|
||||
|
|
|
@ -34,10 +34,12 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v582.Bedrock_v582;
|
||||
import org.cloudburstmc.protocol.bedrock.codec.v588.Bedrock_v588;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.SimpleItemDefinition;
|
||||
|
@ -66,12 +68,40 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
*/
|
||||
public class ItemRegistryPopulator {
|
||||
|
||||
record PaletteVersion(int protocolVersion, Map<Item, String> additionalTranslatedItems) {
|
||||
record PaletteVersion(int protocolVersion, Map<Item, String> javaOnlyItems, Remapper remapper) {
|
||||
|
||||
public PaletteVersion(int protocolVersion) {
|
||||
this(protocolVersion, Collections.emptyMap(), (item, mapping) -> mapping);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface Remapper {
|
||||
@NonNull
|
||||
GeyserMappingItem remap(Item item, GeyserMappingItem mapping);
|
||||
}
|
||||
|
||||
public static void populate() {
|
||||
Map<Item, String> legacyJavaOnly = new HashMap<>();
|
||||
legacyJavaOnly.put(Items.MUSIC_DISC_RELIC, "minecraft:music_disc_wait");
|
||||
legacyJavaOnly.put(Items.PITCHER_PLANT, "minecraft:chorus_flower");
|
||||
legacyJavaOnly.put(Items.PITCHER_POD, "minecraft:beetroot");
|
||||
legacyJavaOnly.put(Items.SNIFFER_EGG, "minecraft:sniffer_spawn_egg"); // the BlockItem of the sniffer egg block
|
||||
|
||||
Map<String, PaletteVersion> paletteVersions = new Object2ObjectOpenHashMap<>();
|
||||
paletteVersions.put("1_19_80", new PaletteVersion(Bedrock_v582.CODEC.getProtocolVersion(), Collections.emptyMap()));
|
||||
paletteVersions.put("1_19_80", new PaletteVersion(Bedrock_v582.CODEC.getProtocolVersion(), legacyJavaOnly, (item, mapping) -> {
|
||||
String id = item.javaIdentifier();
|
||||
if (id.endsWith("pottery_sherd")) {
|
||||
return mapping.withBedrockIdentifier(id.replace("sherd", "shard"));
|
||||
} else if (id.endsWith("carpet") && !id.startsWith("minecraft:moss")) {
|
||||
return mapping.withBedrockIdentifier("minecraft:carpet");
|
||||
} else if (id.endsWith("coral")) {
|
||||
return mapping.withBedrockIdentifier("minecraft:coral");
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}));
|
||||
paletteVersions.put("1_20_0", new PaletteVersion(Bedrock_v588.CODEC.getProtocolVersion()));
|
||||
|
||||
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
|
||||
|
||||
|
@ -168,12 +198,11 @@ public class ItemRegistryPopulator {
|
|||
Set<Item> javaOnlyItems = new ObjectOpenHashSet<>();
|
||||
Collections.addAll(javaOnlyItems, Items.SPECTRAL_ARROW, Items.DEBUG_STICK,
|
||||
Items.KNOWLEDGE_BOOK, Items.TIPPED_ARROW, Items.BUNDLE);
|
||||
javaOnlyItems.add(Items.DECORATED_POT);
|
||||
if (!customItemsAllowed) {
|
||||
javaOnlyItems.add(Items.FURNACE_MINECART);
|
||||
}
|
||||
// Java-only items for this version
|
||||
javaOnlyItems.addAll(palette.getValue().additionalTranslatedItems().keySet());
|
||||
javaOnlyItems.addAll(palette.getValue().javaOnlyItems().keySet());
|
||||
|
||||
Int2ObjectMap<String> customIdMappings = new Int2ObjectOpenHashMap<>();
|
||||
Set<String> registeredItemNames = new ObjectOpenHashSet<>(); // This is used to check for duplicate item names
|
||||
|
@ -184,12 +213,12 @@ public class ItemRegistryPopulator {
|
|||
throw new RuntimeException("Extra item in mappings? " + entry.getKey());
|
||||
}
|
||||
GeyserMappingItem mappingItem;
|
||||
String replacementItem = palette.getValue().additionalTranslatedItems().get(javaItem);
|
||||
String replacementItem = palette.getValue().javaOnlyItems().get(javaItem);
|
||||
if (replacementItem != null) {
|
||||
mappingItem = items.get(replacementItem);
|
||||
mappingItem = items.get(replacementItem); // java only item, a java id fallback has been provided
|
||||
} else {
|
||||
// This items has a mapping specifically for this version of the game
|
||||
mappingItem = entry.getValue();
|
||||
// check if any mapping changes need to be made on this version
|
||||
mappingItem = palette.getValue().remapper().remap(javaItem, entry.getValue());
|
||||
}
|
||||
|
||||
if (customItemsAllowed && javaItem == Items.FURNACE_MINECART) {
|
||||
|
@ -201,7 +230,7 @@ public class ItemRegistryPopulator {
|
|||
String bedrockIdentifier = mappingItem.getBedrockIdentifier();
|
||||
ItemDefinition definition = definitions.get(bedrockIdentifier);
|
||||
if (definition == null) {
|
||||
throw new RuntimeException("Missing Bedrock ItemDefinition in mappings: " + bedrockIdentifier);
|
||||
throw new RuntimeException("Missing Bedrock ItemDefinition in version " + palette.getKey() + " for mapping: " + mappingItem);
|
||||
}
|
||||
|
||||
BlockDefinition bedrockBlock = null;
|
||||
|
|
|
@ -26,12 +26,22 @@
|
|||
package org.geysermc.geyser.registry.type;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.With;
|
||||
|
||||
/**
|
||||
* Represents Geyser's own serialized item information before being processed per-version
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@Getter
|
||||
@With
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GeyserMappingItem {
|
||||
@JsonProperty("bedrock_identifier") String bedrockIdentifier;
|
||||
@JsonProperty("bedrock_data") int bedrockData;
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue