3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-25 15:50:14 +01:00

Bedrock 1.21.0 Support (#4687)

* 1.21.0

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>

* Deprecate Bedrock 1.20.70 and below

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>

* Strictly disconnect on all exceptions

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>

* Remove old version resources

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>

---------

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
Dieser Commit ist enthalten in:
Kas-tle 2024-05-26 20:00:47 -07:00 committet von GitHub
Ursprung 0ea01bfa48
Commit fa6808a620
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
40 geänderte Dateien mit 2325 neuen und 37177 gelöschten Zeilen

Datei anzeigen

@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here! Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
### Currently supporting Minecraft Bedrock 1.20.40 - 1.20.80/81 and Minecraft Java 1.20.5/1.20.6 ### Currently supporting Minecraft Bedrock 1.20.80 - 1.21.0 and Minecraft Java 1.20.5/1.20.6
## Setting Up ## Setting Up
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser. Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.

Datei anzeigen

@ -163,6 +163,7 @@ public class BlockInventoryHolder extends InventoryHolder {
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();
packet.setId((byte) inventory.getBedrockId()); packet.setId((byte) inventory.getBedrockId());
packet.setServerInitiated(true); packet.setServerInitiated(true);
packet.setType(ContainerType.CONTAINER);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
return; return;
} }

Datei anzeigen

@ -224,7 +224,7 @@ class CodecProcessor {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static BedrockCodec processCodec(BedrockCodec codec) { static BedrockCodec processCodec(BedrockCodec codec) {
return codec.toBuilder() BedrockCodec.Builder codecBuilder = codec.toBuilder()
// Illegal unused serverbound EDU packets // Illegal unused serverbound EDU packets
.updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(PhotoTransferPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER) .updateSerializer(LabTablePacket.class, ILLEGAL_SERIALIZER)
@ -236,6 +236,7 @@ class CodecProcessor {
.updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(PurchaseReceiptPacket.class, ILLEGAL_SERIALIZER)
// Illegal unused serverbound packets that are deprecated // Illegal unused serverbound packets that are deprecated
.updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(ClientCheatAbilityPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(CraftingEventPacket.class, ILLEGAL_SERIALIZER)
// Illegal unusued serverbound packets that relate to unused features // Illegal unusued serverbound packets that relate to unused features
.updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(PlayerAuthInputPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(ClientCacheBlobStatusPacket.class, ILLEGAL_SERIALIZER)
@ -243,7 +244,6 @@ class CodecProcessor {
.updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(SubChunkRequestPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(GameTestRequestPacket.class, ILLEGAL_SERIALIZER)
// Ignored serverbound packets // Ignored serverbound packets
.updateSerializer(CraftingEventPacket.class, IGNORED_SERIALIZER) // Make illegal when 1.20.40 is removed
.updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER) .updateSerializer(ClientToServerHandshakePacket.class, IGNORED_SERIALIZER)
.updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER) .updateSerializer(EntityFallPacket.class, IGNORED_SERIALIZER)
.updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER) .updateSerializer(MapCreateLockedCopyPacket.class, IGNORED_SERIALIZER)
@ -260,22 +260,25 @@ class CodecProcessor {
.updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER) .updateSerializer(PlayerHotbarPacket.class, PLAYER_HOTBAR_SERIALIZER)
.updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER) .updateSerializer(PlayerSkinPacket.class, PLAYER_SKIN_SERIALIZER)
.updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER) .updateSerializer(SetEntityDataPacket.class, SET_ENTITY_DATA_SERIALIZER)
.updateSerializer(SetEntityMotionPacket.class, codec.getProtocolVersion() < 662 ? .updateSerializer(SetEntityMotionPacket.class, SET_ENTITY_MOTION_SERIALIZER_V662)
SET_ENTITY_MOTION_SERIALIZER_V291 :
SET_ENTITY_MOTION_SERIALIZER_V662)
.updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER) .updateSerializer(SetEntityLinkPacket.class, SET_ENTITY_LINK_SERIALIZER)
// Valid serverbound packets where reading of some fields can be skipped // Valid serverbound packets where reading of some fields can be skipped
.updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER) .updateSerializer(MobEquipmentPacket.class, MOB_EQUIPMENT_SERIALIZER)
// // Illegal bidirectional packets // Illegal bidirectional packets
.updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(DebugInfoPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER) .updateSerializer(EditorNetworkPacket.class, ILLEGAL_SERIALIZER)
.updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER) .updateSerializer(ScriptMessagePacket.class, ILLEGAL_SERIALIZER)
// // Ignored bidirectional packets // Ignored bidirectional packets
.updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER) .updateSerializer(ClientCacheStatusPacket.class, IGNORED_SERIALIZER)
.updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER) .updateSerializer(SimpleEventPacket.class, IGNORED_SERIALIZER)
.updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER) .updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER);
.updateSerializer(MultiplayerSettingsPacket.class, IGNORED_SERIALIZER)
.build(); if (codec.getProtocolVersion() < 685) {
// Ignored bidirectional packets
codecBuilder.updateSerializer(TickSyncPacket.class, IGNORED_SERIALIZER);
}
return codecBuilder.build();
} }
/** /**

Datei anzeigen

@ -27,11 +27,8 @@ package org.geysermc.geyser.network;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec; import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec; import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec;
@ -50,8 +47,8 @@ public final class GameProtocol {
* 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 BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder() public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v685.CODEC.toBuilder()
.minecraftVersion("1.20.81") .minecraftVersion("1.21.0")
.build()); .build());
/** /**
@ -66,20 +63,11 @@ public final class GameProtocol {
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC; private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;
static { static {
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v622.CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder()
.minecraftVersion("1.20.40/1.20.41") .minecraftVersion("1.20.80/1.20.81")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v630.CODEC.toBuilder()
.minecraftVersion("1.20.50/1.20.51")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v649.CODEC.toBuilder()
.minecraftVersion("1.20.60/1.20.62")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v662.CODEC.toBuilder()
.minecraftVersion("1.20.70/1.20.73")
.build())); .build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder() SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(DEFAULT_BEDROCK_CODEC.toBuilder()
.minecraftVersion("1.20.80/1.20.81") .minecraftVersion("1.21.0")
.build())); .build()));
} }
@ -99,16 +87,8 @@ public final class GameProtocol {
/* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */ /* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */
public static boolean isPre1_20_50(GeyserSession session) { public static boolean isPre1_21_0(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v630.CODEC.getProtocolVersion(); return session.getUpstream().getProtocolVersion() < Bedrock_v685.CODEC.getProtocolVersion();
}
public static boolean isPre1_20_70(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v662.CODEC.getProtocolVersion();
}
public static boolean is1_20_60orHigher(int protocolVersion) {
return protocolVersion >= Bedrock_v649.CODEC.getProtocolVersion();
} }
/** /**

Datei anzeigen

@ -47,7 +47,9 @@ public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
if (!(rootCause instanceof IllegalArgumentException)) { if (!(rootCause instanceof IllegalArgumentException)) {
super.exceptionCaught(ctx, cause); // Kick users that cause exceptions
session.getGeyser().getLogger().warning("Exception caught in session of" + session.bedrockUsername() + ": " + rootCause.getMessage());
session.disconnect("An internal error occurred!");
return; return;
} }

Datei anzeigen

@ -38,11 +38,8 @@ import it.unimi.dsi.fastutil.objects.*;
import org.cloudburstmc.blockstateupdater.BlockStateUpdater; import org.cloudburstmc.blockstateupdater.BlockStateUpdater;
import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext; import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext;
import org.cloudburstmc.nbt.*; import org.cloudburstmc.nbt.*;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData; import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
@ -125,12 +122,8 @@ public final class BlockRegistryPopulator {
private static void registerBedrockBlocks() { private static void registerBedrockBlocks() {
var blockMappers = ImmutableMap.<ObjectIntPair<String>, Remapper>builder() var blockMappers = ImmutableMap.<ObjectIntPair<String>, Remapper>builder()
.put(ObjectIntPair.of("1_20_40", Bedrock_v622.CODEC.getProtocolVersion()), Conversion630_622::remapBlock) .put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), Conversion685_671::remapBlock)
.put(ObjectIntPair.of("1_20_50", Bedrock_v630.CODEC.getProtocolVersion()), Conversion649_630::remapBlock) .put(ObjectIntPair.of("1_21_0", Bedrock_v685.CODEC.getProtocolVersion()), tag -> tag)
// Only changes in 1.20.60 are hard_stained_glass (an EDU only block)
.put(ObjectIntPair.of("1_20_60", Bedrock_v649.CODEC.getProtocolVersion()), Conversion662_649::remapBlock)
.put(ObjectIntPair.of("1_20_70", Bedrock_v662.CODEC.getProtocolVersion()), Conversion671_662::remapBlock)
.put(ObjectIntPair.of("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()), tag -> tag)
.build(); .build();
// We can keep this strong as nothing should be garbage collected // We can keep this strong as nothing should be garbage collected

Datei anzeigen

@ -1,217 +0,0 @@
/*
* Copyright (c) 2019-2023 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.registry.populator;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.type.GeyserMappingItem;
import java.util.List;
import java.util.Map;
/**
* Backwards-maps the blocks and items of 1.20.50 (630) to 1.20.40 (622)
*/
class Conversion630_622 {
private static final List<String> NEW_STONES = List.of("minecraft:stone", "minecraft:granite", "minecraft:polished_granite", "minecraft:diorite", "minecraft:polished_diorite", "minecraft:andesite", "minecraft:polished_andesite");
private static final List<String> NEW_WOODS = List.of("minecraft:oak_planks", "minecraft:spruce_planks", "minecraft:birch_planks", "minecraft:jungle_planks", "minecraft:acacia_planks", "minecraft:dark_oak_planks");
private static final Map<String, String> ITEMS = new Object2ObjectOpenHashMap<>();
static {
ITEMS.put("minecraft:acacia_planks", "minecraft:planks");
ITEMS.put("minecraft:birch_planks", "minecraft:planks");
ITEMS.put("minecraft:dark_oak_planks", "minecraft:planks");
ITEMS.put("minecraft:jungle_planks", "minecraft:planks");
ITEMS.put("minecraft:oak_planks", "minecraft:planks");
ITEMS.put("minecraft:spruce_planks", "minecraft:planks");
ITEMS.put("minecraft:diorite", "minecraft:stone");
ITEMS.put("minecraft:andesite", "minecraft:stone");
ITEMS.put("minecraft:granite", "minecraft:stone");
ITEMS.put("minecraft:polished_andesite", "minecraft:stone");
ITEMS.put("minecraft:polished_diorite", "minecraft:stone");
ITEMS.put("minecraft:polished_granite", "minecraft:stone");
ITEMS.put("minecraft:chiseled_tuff", "minecraft:chiseled_deepslate");
ITEMS.put("minecraft:chiseled_tuff_bricks", "minecraft:chiseled_deepslate");
ITEMS.put("minecraft:polished_tuff", "minecraft:polished_deepslate");
ITEMS.put("minecraft:polished_tuff_double_slab", "minecraft:polished_deepslate_double_slab");
ITEMS.put("minecraft:polished_tuff_slab", "minecraft:polished_deepslate_slab");
ITEMS.put("minecraft:polished_tuff_stairs", "minecraft:polished_deepslate_stairs");
ITEMS.put("minecraft:polished_tuff_wall", "minecraft:polished_deepslate_wall");
ITEMS.put("minecraft:tuff_brick_double_slab", "minecraft:deepslate_brick_double_slab");
ITEMS.put("minecraft:tuff_brick_slab", "minecraft:deepslate_brick_slab");
ITEMS.put("minecraft:tuff_brick_stairs", "minecraft:deepslate_brick_stairs");
ITEMS.put("minecraft:tuff_brick_wall", "minecraft:deepslate_brick_wall");
ITEMS.put("minecraft:tuff_bricks", "minecraft:deepslate_bricks");
ITEMS.put("minecraft:tuff_double_slab", "minecraft:cobbled_deepslate_double_slab");
ITEMS.put("minecraft:tuff_slab", "minecraft:cobbled_deepslate_slab");
ITEMS.put("minecraft:tuff_stairs", "minecraft:cobbled_deepslate_stairs");
ITEMS.put("minecraft:tuff_wall", "minecraft:cobbled_deepslate_wall");
ITEMS.put("minecraft:chiseled_copper", "minecraft:copper_block");
ITEMS.put("minecraft:copper_bulb", "minecraft:copper_block");
ITEMS.put("minecraft:copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:exposed_chiseled_copper", "minecraft:exposed_copper");
ITEMS.put("minecraft:exposed_copper_bulb", "minecraft:exposed_copper");
ITEMS.put("minecraft:exposed_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:exposed_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:exposed_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:oxidized_chiseled_copper", "minecraft:oxidized_copper");
ITEMS.put("minecraft:oxidized_copper_bulb", "minecraft:oxidized_copper");
ITEMS.put("minecraft:oxidized_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:oxidized_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:oxidized_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:waxed_chiseled_copper", "minecraft:waxed_copper");
ITEMS.put("minecraft:waxed_copper_bulb", "minecraft:waxed_copper");
ITEMS.put("minecraft:waxed_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:waxed_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:waxed_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:waxed_exposed_chiseled_copper", "minecraft:waxed_exposed_copper");
ITEMS.put("minecraft:waxed_exposed_copper_bulb", "minecraft:waxed_exposed_copper");
ITEMS.put("minecraft:waxed_exposed_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:waxed_exposed_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:waxed_exposed_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:waxed_oxidized_chiseled_copper", "minecraft:waxed_oxidized_copper");
ITEMS.put("minecraft:waxed_oxidized_copper_bulb", "minecraft:waxed_oxidized_copper");
ITEMS.put("minecraft:waxed_oxidized_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:waxed_oxidized_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:waxed_oxidized_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:waxed_weathered_chiseled_copper", "minecraft:waxed_weathered_copper");
ITEMS.put("minecraft:waxed_weathered_copper_bulb", "minecraft:waxed_weathered_copper");
ITEMS.put("minecraft:waxed_weathered_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:waxed_weathered_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:waxed_weathered_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:weathered_chiseled_copper", "minecraft:weathered_copper");
ITEMS.put("minecraft:weathered_copper_bulb", "minecraft:weathered_copper");
ITEMS.put("minecraft:weathered_copper_door", "minecraft:iron_door");
ITEMS.put("minecraft:weathered_copper_grate", "minecraft:raw_iron_block");
ITEMS.put("minecraft:weathered_copper_trapdoor", "minecraft:iron_trapdoor");
ITEMS.put("minecraft:crafter", "minecraft:crafting_table");
}
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
mapping = Conversion649_630.remapItem(item, mapping);
String replacement = ITEMS.get(mapping.getBedrockIdentifier());
if (replacement == null) {
return mapping;
} else {
return mapping.withBedrockIdentifier(replacement);
}
}
static NbtMap remapBlock(NbtMap tag) {
tag = Conversion649_630.remapBlock(tag);
final String name = tag.getString("name");
String replacement;
if (NEW_STONES.contains(name) || NEW_WOODS.contains(name)) {
String typeKey;
String type = name.substring(10);
if (NEW_STONES.contains(name)) {
replacement = "minecraft:stone";
typeKey = "stone_type";
if (type.startsWith("polished_")) {
type = type.substring(9) + "_smooth";
}
} else {
replacement = "minecraft:planks";
typeKey = "wood_type";
type = type.substring(0, type.indexOf("_planks"));
}
return tag.toBuilder()
.putString("name", replacement)
.putCompound("states", NbtMap.builder().putString(typeKey, type).build())
.build();
} else if (name.contains("tuff") && !name.equals("minecraft:tuff")) {
if (name.contains("brick") || name.contains("polished") || name.contains("chiseled")) {
replacement = name.replace("tuff", "deepslate");
if (name.contains("chiseled")) {
// chiseled deepslate bricks don't exist. just use chiseled deepslate instead
replacement = replacement.replace("_bricks", "");
}
} else {
replacement = name.replace("tuff", "cobbled_deepslate");
}
return tag.toBuilder()
.putString("name", replacement)
.build();
} else if (name.contains("copper")) {
boolean removeStates = false;
if (name.contains("chiseled")) {
replacement = name.replace("_chiseled", ""); // special chiseled
replacement = replacement.replace("chiseled_", ""); // plain chiseled
} else if (name.endsWith("bulb")) {
replacement = name.replace("_bulb", "");
removeStates = true;
} else if (name.endsWith("grate")) {
replacement = "minecraft:raw_iron_block";
} else if (name.endsWith("door")) {
if (name.contains("trap")) {
replacement = "minecraft:iron_trapdoor";
} else {
replacement = "minecraft:iron_door";
}
} else {
return tag;
}
if (replacement.endsWith(":copper")) {
// case for plain chiseled copper and plain bulb
replacement = replacement + "_block";
}
NbtMapBuilder builder = tag.toBuilder();
builder.putString("name", replacement);
if (removeStates) {
builder.putCompound("states", NbtMap.EMPTY);
}
return builder.build();
} else if (name.equals("minecraft:crafter")) {
NbtMapBuilder builder = tag.toBuilder();
builder.put("name", "minecraft:crafting_table");
builder.put("states", NbtMap.EMPTY);
return builder.build();
}
return tag;
}
}

Datei anzeigen

@ -1,64 +0,0 @@
/*
* Copyright (c) 2019-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.registry.populator;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.type.GeyserMappingItem;
public class Conversion649_630 {
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
mapping = Conversion662_649.remapItem(item, mapping);
String identifer = mapping.getBedrockIdentifier();
switch (identifer) {
case "minecraft:armadillo_scute", "minecraft:turtle_scute" -> { return mapping.withBedrockIdentifier("minecraft:scute"); }
case "minecraft:armadillo_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:rabbit_spawn_egg"); }
case "minecraft:trial_spawner" -> { return mapping.withBedrockIdentifier("minecraft:mob_spawner"); }
case "minecraft:trial_key" -> { return mapping.withBedrockIdentifier("minecraft:echo_shard"); }
case "minecraft:wolf_armor" -> { return mapping.withBedrockIdentifier("minecraft:leather_horse_armor"); }
default -> { return mapping; }
}
}
static NbtMap remapBlock(NbtMap tag) {
tag = Conversion662_649.remapBlock(tag);
final String name = tag.getString("name");
if (name.equals("minecraft:trial_spawner")) {
NbtMapBuilder builder = tag.toBuilder()
.putString("name", "minecraft:mob_spawner")
.putCompound("states", NbtMap.EMPTY);
return builder.build();
}
return tag;
}
}

Datei anzeigen

@ -1,187 +0,0 @@
/*
* Copyright (c) 2019-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.registry.populator;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.type.GeyserMappingItem;
import java.util.List;
import java.util.stream.Stream;
public class Conversion662_649 {
private static final List<String> NEW_MISC = List.of("minecraft:grass_block", "minecraft:vault");
private static final List<String> NEW_WOODS = List.of("minecraft:oak_wood", "minecraft:spruce_wood", "minecraft:birch_wood", "minecraft:jungle_wood", "minecraft:acacia_wood", "minecraft:dark_oak_wood", "minecraft:stripped_oak_wood", "minecraft:stripped_spruce_wood", "minecraft:stripped_birch_wood", "minecraft:stripped_jungle_wood", "minecraft:stripped_acacia_wood", "minecraft:stripped_dark_oak_wood");
private static final List<String> NEW_LEAVES = List.of("minecraft:oak_leaves", "minecraft:spruce_leaves", "minecraft:birch_leaves", "minecraft:jungle_leaves");
private static final List<String> NEW_LEAVES2 = List.of("minecraft:acacia_leaves", "minecraft:dark_oak_leaves");
private static final List<String> NEW_SLABS = List.of("minecraft:oak_slab", "minecraft:spruce_slab", "minecraft:birch_slab", "minecraft:jungle_slab", "minecraft:acacia_slab", "minecraft:dark_oak_slab", "minecraft:oak_double_slab", "minecraft:spruce_double_slab", "minecraft:birch_double_slab", "minecraft:jungle_double_slab", "minecraft:acacia_double_slab", "minecraft:dark_oak_double_slab");
private static final List<String> NEW_BLOCKS = Stream.of(NEW_WOODS, NEW_LEAVES, NEW_LEAVES2, NEW_SLABS, NEW_MISC).flatMap(List::stream).toList();
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
mapping = Conversion671_662.remapItem(item, mapping);
String identifer = mapping.getBedrockIdentifier();
switch (identifer) {
case "minecraft:bogged_spawn_egg" -> { return mapping.withBedrockIdentifier("minecraft:creeper_spawn_egg"); }
case "minecraft:grass_block" -> { return mapping.withBedrockIdentifier("minecraft:grass"); }
case "minecraft:vault" -> { return mapping.withBedrockIdentifier("minecraft:trial_spawner"); }
case "minecraft:wind_charge" -> { return mapping.withBedrockIdentifier("minecraft:snowball"); }
};
if (NEW_WOODS.contains(identifer)) {
switch (identifer) {
case "minecraft:oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(0); }
case "minecraft:spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(1); }
case "minecraft:birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(2); }
case "minecraft:jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(3); }
case "minecraft:acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(4); }
case "minecraft:dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(5); }
case "minecraft:stripped_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(8); }
case "minecraft:stripped_spruce_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(9); }
case "minecraft:stripped_birch_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(10); }
case "minecraft:stripped_jungle_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(11); }
case "minecraft:stripped_acacia_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(12); }
case "minecraft:stripped_dark_oak_wood" -> { return mapping.withBedrockIdentifier("minecraft:wood").withBedrockData(13); }
}
}
if (NEW_SLABS.contains(identifer)) {
switch (identifer) {
case "minecraft:oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(0); }
case "minecraft:spruce_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(1); }
case "minecraft:birch_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(2); }
case "minecraft:jungle_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(3); }
case "minecraft:acacia_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(4); }
case "minecraft:dark_oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:wooden_slab").withBedrockData(5); }
}
}
if (NEW_LEAVES.contains(identifer) || NEW_LEAVES2.contains(identifer)) {
switch (identifer) {
case "minecraft:oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(0); }
case "minecraft:spruce_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(1); }
case "minecraft:birch_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(2); }
case "minecraft:jungle_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves").withBedrockData(3); }
case "minecraft:acacia_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(0); }
case "minecraft:dark_oak_leaves" -> { return mapping.withBedrockIdentifier("minecraft:leaves2").withBedrockData(1); }
}
}
return mapping;
}
static NbtMap remapBlock(NbtMap tag) {
tag = Conversion671_662.remapBlock(tag);
final String name = tag.getString("name");
if (!NEW_BLOCKS.contains(name)) {
return tag;
}
String replacement;
if (name.equals("minecraft:grass_block")) {
replacement = "minecraft:grass";
NbtMapBuilder builder = tag.toBuilder();
builder.putString("name", replacement);
return builder.build();
}
if (name.equals("minecraft:vault")) {
replacement = "minecraft:trial_spawner";
NbtMapBuilder statesBuilder = NbtMap.builder()
.putInt("trial_spawner_state", 0);
NbtMapBuilder builder = tag.toBuilder();
builder.putString("name", replacement);
builder.putCompound("states", statesBuilder.build());
return builder.build();
}
if (NEW_WOODS.contains(name)) {
replacement = "minecraft:wood";
NbtMap states = tag.getCompound("states");
boolean stripped = name.startsWith("minecraft:stripped_");
String woodType = name.replaceAll("minecraft:|_wood|stripped_", "");
NbtMapBuilder statesBuilder = states.toBuilder()
.putString("wood_type", woodType)
.putBoolean("stripped_bit", stripped);
NbtMapBuilder builder = tag.toBuilder()
.putString("name", replacement)
.putCompound("states", statesBuilder.build());
return builder.build();
}
if (NEW_LEAVES.contains(name) || NEW_LEAVES2.contains(name)) {
boolean leaves2 = NEW_LEAVES2.contains(name);
replacement = leaves2 ? "minecraft:leaves2" : "minecraft:leaves";
NbtMap states = tag.getCompound("states");
String leafType = name.replaceAll("minecraft:|_leaves", "");
NbtMapBuilder statesBuilder = states.toBuilder()
.putString(leaves2 ? "new_leaf_type" : "old_leaf_type", leafType);
NbtMapBuilder builder = tag.toBuilder()
.putString("name", replacement)
.putCompound("states", statesBuilder.build());
return builder.build();
}
if (NEW_SLABS.contains(name)) {
replacement = name.contains("double") ? "minecraft:double_wooden_slab" : "minecraft:wooden_slab";
NbtMap states = tag.getCompound("states");
String woodType = name.replaceAll("minecraft:|_double|_slab", "");
NbtMapBuilder statesBuilder = states.toBuilder()
.putString("wood_type", woodType);
NbtMapBuilder builder = tag.toBuilder()
.putString("name", replacement)
.putCompound("states", statesBuilder.build());
return builder.build();
}
return tag;
}
}

Datei anzeigen

@ -1,205 +0,0 @@
/*
* Copyright (c) 2019-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.registry.populator;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.type.GeyserMappingItem;
import java.util.List;
import java.util.stream.Stream;
public class Conversion671_662 {
private static final List<String> NEW_MISC = List.of("minecraft:heavy_core", "minecraft:mace", "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern", "minecraft:flow_armor_trim_smithing_template", "minecraft:bolt_armor_trim_smithing_template", "minecraft:flow_pottery_sherd", "minecraft:guster_pottery_sherd", "minecraft:scrape_pottery_sherd", "minecraft:breeze_rod");
private static final List<String> NEW_CORAL_FANS = List.of("minecraft:tube_coral_fan", "minecraft:brain_coral_fan", "minecraft:bubble_coral_fan", "minecraft:fire_coral_fan", "minecraft:horn_coral_fan");
private static final List<String> NEW_DEAD_CORAL_FANS = List.of("minecraft:dead_tube_coral_fan", "minecraft:dead_brain_coral_fan", "minecraft:dead_bubble_coral_fan", "minecraft:dead_fire_coral_fan", "minecraft:dead_horn_coral_fan");
private static final List<String> NEW_FLOWERS = List.of("minecraft:poppy", "minecraft:blue_orchid", "minecraft:allium", "minecraft:azure_bluet", "minecraft:red_tulip", "minecraft:orange_tulip", "minecraft:white_tulip", "minecraft:pink_tulip", "minecraft:oxeye_daisy", "minecraft:cornflower", "minecraft:lily_of_the_valley");
private static final List<String> NEW_SAPLINGS = List.of("minecraft:oak_sapling", "minecraft:spruce_sapling", "minecraft:birch_sapling", "minecraft:jungle_sapling", "minecraft:acacia_sapling", "minecraft:dark_oak_sapling", "minecraft:bamboo_sapling");
private static final List<String> NEW_BLOCKS = Stream.of(NEW_MISC, NEW_CORAL_FANS, NEW_DEAD_CORAL_FANS, NEW_FLOWERS, NEW_SAPLINGS).flatMap(List::stream).toList();
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
String identifer = mapping.getBedrockIdentifier();
if (!NEW_BLOCKS.contains(identifer)) {
return mapping;
}
switch (identifer) {
case "minecraft:bolt_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:wayfinder_armor_trim_smithing_template"); }
case "minecraft:breeze_rod" -> { return mapping.withBedrockIdentifier("minecraft:blaze_rod"); }
case "minecraft:flow_armor_trim_smithing_template" -> { return mapping.withBedrockIdentifier("minecraft:spire_armor_trim_smithing_template"); }
case "minecraft:flow_banner_pattern", "minecraft:guster_banner_pattern" -> { return mapping.withBedrockIdentifier("minecraft:globe_banner_pattern"); }
case "minecraft:flow_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:skull_pottery_sherd"); }
case "minecraft:guster_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:shelter_pottery_sherd"); }
case "minecraft:scrape_pottery_sherd" -> { return mapping.withBedrockIdentifier("minecraft:heartbreak_pottery_sherd"); }
case "minecraft:heavy_core" -> { return mapping.withBedrockIdentifier("minecraft:conduit"); }
case "minecraft:mace" -> { return mapping.withBedrockIdentifier("minecraft:netherite_axe"); }
}
if (NEW_FLOWERS.contains(identifer)) {
switch (identifer) {
case "minecraft:poppy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); }
case "minecraft:blue_orchid" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); }
case "minecraft:allium" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); }
case "minecraft:azure_bluet" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); }
case "minecraft:red_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); }
case "minecraft:orange_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(5); }
case "minecraft:white_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(6); }
case "minecraft:pink_tulip" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(7); }
case "minecraft:oxeye_daisy" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); }
case "minecraft:cornflower" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); }
case "minecraft:lily_of_the_valley" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); }
}
}
if (NEW_SAPLINGS.contains(identifer)) {
switch (identifer) {
case "minecraft:oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(0); }
case "minecraft:spruce_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(1); }
case "minecraft:birch_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(2); }
case "minecraft:jungle_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(3); }
case "minecraft:acacia_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(4); }
case "minecraft:dark_oak_sapling" -> { return mapping.withBedrockIdentifier("minecraft:sapling").withBedrockData(5); }
}
}
if (NEW_CORAL_FANS.contains(identifer)) {
switch (identifer) {
case "minecraft:tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(0); }
case "minecraft:brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(1); }
case "minecraft:bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(2); }
case "minecraft:fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(3); }
case "minecraft:horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan").withBedrockData(4); }
}
}
if (NEW_DEAD_CORAL_FANS.contains(identifer)) {
switch (identifer) {
case "minecraft:dead_tube_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(0); }
case "minecraft:dead_brain_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(1); }
case "minecraft:dead_bubble_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(2); }
case "minecraft:dead_fire_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(3); }
case "minecraft:dead_horn_coral_fan" -> { return mapping.withBedrockIdentifier("minecraft:coral_fan_dead").withBedrockData(4); }
}
}
return mapping;
}
static NbtMap remapBlock(NbtMap tag) {
final String name = tag.getString("name");
if (!NEW_BLOCKS.contains(name)) {
return tag;
}
if (name.equals("minecraft:bamboo_sapling")) {
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("sapling_type", "oak")
.build();
return tag.toBuilder().putCompound("states", states).build();
}
String replacement;
if (name.equals("minecraft:heavy_core")) {
replacement = "minecraft:conduit";
NbtMapBuilder builder = tag.toBuilder();
builder.putString("name", replacement);
return builder.build();
}
if (NEW_SAPLINGS.contains(name)) {
replacement = "minecraft:sapling";
String saplingType = name.replaceAll("minecraft:|_sapling", "");;
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("sapling_type", saplingType)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
if (NEW_FLOWERS.contains(name)) {
replacement = "minecraft:red_flower";
String flowerType;
switch (name) {
case "minecraft:poppy" -> flowerType = "poppy";
case "minecraft:blue_orchid" -> flowerType = "orchid";
case "minecraft:allium" -> flowerType = "allium";
case "minecraft:azure_bluet" -> flowerType = "houstonia";
case "minecraft:red_tulip" -> flowerType = "tulip_red";
case "minecraft:orange_tulip" -> flowerType = "tulip_orange";
case "minecraft:white_tulip" -> flowerType = "tulip_white";
case "minecraft:pink_tulip" -> flowerType = "tulip_pink";
case "minecraft:oxeye_daisy" -> flowerType = "oxeye";
case "minecraft:cornflower" -> flowerType = "cornflower";
case "minecraft:lily_of_the_valley" -> flowerType = "lily_of_the_valley";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("flower_type", flowerType)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
boolean isLiveCoralFan = NEW_CORAL_FANS.contains(name);
boolean isDeadCoralFan = NEW_DEAD_CORAL_FANS.contains(name);
if (isLiveCoralFan || isDeadCoralFan) {
replacement = isLiveCoralFan ? "minecraft:coral_fan" : "minecraft:coral_fan_dead";
String coralColor;
switch (name) {
case "minecraft:tube_coral_fan", "minecraft:dead_tube_coral_fan" -> coralColor = "blue";
case "minecraft:brain_coral_fan", "minecraft:dead_brain_coral_fan" -> coralColor = "pink";
case "minecraft:bubble_coral_fan", "minecraft:dead_bubble_coral_fan" -> coralColor = "purple";
case "minecraft:fire_coral_fan", "minecraft:dead_fire_coral_fan" -> coralColor = "yellow";
case "minecraft:horn_coral_fan", "minecraft:dead_horn_coral_fan" -> coralColor = "red";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("coral_color", coralColor)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
return tag;
}
}

Datei anzeigen

@ -0,0 +1,205 @@
/*
* Copyright (c) 2019-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.registry.populator;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.type.GeyserMappingItem;
import java.util.List;
import java.util.stream.Stream;
public class Conversion685_671 {
private static final List<String> NEW_CORAL_BLOCKS = List.of("minecraft:tube_coral_block", "minecraft:brain_coral_block", "minecraft:bubble_coral_block", "minecraft:fire_coral_block", "minecraft:horn_coral_block", "minecraft:dead_tube_coral_block", "minecraft:dead_brain_coral_block", "minecraft:dead_bubble_coral_block", "minecraft:dead_fire_coral_block", "minecraft:dead_horn_coral_block");
private static final List<String> NEW_DOUBLE_PLANTS = List.of("minecraft:sunflower", "minecraft:lilac", "minecraft:tall_grass", "minecraft:large_fern", "minecraft:rose_bush", "minecraft:peony");
private static final List<String> NEW_STONE_BLOCK_SLABS = List.of("minecraft:smooth_stone_slab", "minecraft:sandstone_slab", "minecraft:petrified_oak_slab", "minecraft:cobblestone_slab", "minecraft:brick_slab", "minecraft:stone_brick_slab", "minecraft:quartz_slab", "minecraft:nether_brick_slab");
private static final List<String> NEW_TALLGRASSES = List.of("minecraft:fern", "minecraft:short_grass");
private static final List<String> OMINOUS_BLOCKS = List.of("minecraft:trial_spawner", "minecraft:vault");
private static final List<String> NEW_BLOCKS = Stream.of(NEW_CORAL_BLOCKS, NEW_DOUBLE_PLANTS, NEW_STONE_BLOCK_SLABS, NEW_TALLGRASSES).flatMap(List::stream).toList();
private static final List<String> MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList();
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
String identifer = mapping.getBedrockIdentifier();
if (!NEW_BLOCKS.contains(identifer)) {
return mapping;
}
if (NEW_CORAL_BLOCKS.contains(identifer)) {
switch (identifer) {
case "minecraft:tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(0); }
case "minecraft:brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(1); }
case "minecraft:bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(2); }
case "minecraft:fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(3); }
case "minecraft:horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(4); }
case "minecraft:dead_tube_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(8); }
case "minecraft:dead_brain_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(9); }
case "minecraft:dead_bubble_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(10); }
case "minecraft:dead_fire_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(11); }
case "minecraft:dead_horn_coral_block" -> { return mapping.withBedrockIdentifier("minecraft:red_flower").withBedrockData(12); }
}
}
if (NEW_DOUBLE_PLANTS.contains(identifer)) {
switch (identifer) {
case "minecraft:sunflower" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(0); }
case "minecraft:lilac" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(1); }
case "minecraft:tall_grass" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(2); }
case "minecraft:large_fern" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(3); }
case "minecraft:rose_bush" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(4); }
case "minecraft:peony" -> { return mapping.withBedrockIdentifier("minecraft:double_plant").withBedrockData(5); }
}
}
if (NEW_STONE_BLOCK_SLABS.contains(identifer)) {
switch (identifer) {
case "minecraft:smooth_stone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(0); }
case "minecraft:sandstone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(1); }
case "minecraft:petrified_oak_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(2); }
case "minecraft:cobblestone_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(3); }
case "minecraft:brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(4); }
case "minecraft:stone_brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(5); }
case "minecraft:quartz_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(6); }
case "minecraft:nether_brick_slab" -> { return mapping.withBedrockIdentifier("minecraft:stone_block_slab").withBedrockData(7); }
}
}
if (NEW_TALLGRASSES.contains(identifer)) {
switch (identifer) {
case "minecraft:short_grass" -> { return mapping.withBedrockIdentifier("minecraft:tallgrass").withBedrockData(1); }
case "minecraft:fern" -> { return mapping.withBedrockIdentifier("minecraft:tallgrass").withBedrockData(2); }
}
}
return mapping;
}
static NbtMap remapBlock(NbtMap tag) {
final String name = tag.getString("name");
if (!MODIFIED_BLOCKS.contains(name)) {
return tag;
}
if (OMINOUS_BLOCKS.contains(name)) {
NbtMapBuilder builder = tag.getCompound("states").toBuilder();
builder.remove("ominous");
return tag.toBuilder().putCompound("states", builder.build()).build();
}
String replacement;
if (NEW_CORAL_BLOCKS.contains(name)) {
replacement = "minecraft:coral_block";
String coralColor;
boolean deadBit = name.startsWith("minecraft:dead_");
switch(name) {
case "minecraft:tube_coral_block", "minecraft:dead_tube_coral_block" -> coralColor = "blue";
case "minecraft:brain_coral_block", "minecraft:dead_brain_coral_block" -> coralColor = "pink";
case "minecraft:bubble_coral_block", "minecraft:dead_bubble_coral_block" -> coralColor = "purple";
case "minecraft:fire_coral_block", "minecraft:dead_fire_coral_block" -> coralColor = "yellow";
case "minecraft:horn_coral_block", "minecraft:dead_horn_coral_block" -> coralColor = "red";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("coral_color", coralColor)
.putBoolean("dead_bit", deadBit)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
if (NEW_DOUBLE_PLANTS.contains(name)) {
replacement = "minecraft:double_plant";
String doublePlantType;
switch(name) {
case "minecraft:sunflower" -> doublePlantType = "sunflower";
case "minecraft:lilac" -> doublePlantType = "syringa";
case "minecraft:tall_grass" -> doublePlantType = "grass";
case "minecraft:large_fern" -> doublePlantType = "fern";
case "minecraft:rose_bush" -> doublePlantType = "rose";
case "minecraft:peony" -> doublePlantType = "paeonia";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("double_plant_type", doublePlantType)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
if (NEW_STONE_BLOCK_SLABS.contains(name)) {
replacement = "minecraft:stone_block_slab";
String stoneSlabType;
switch(name) {
case "minecraft:smooth_stone_slab" -> stoneSlabType = "smooth_stone";
case "minecraft:sandstone_slab" -> stoneSlabType = "sandstone";
case "minecraft:petrified_oak_slab" -> stoneSlabType = "wood";
case "minecraft:cobblestone_slab" -> stoneSlabType = "cobblestone";
case "minecraft:brick_slab" -> stoneSlabType = "brick";
case "minecraft:stone_brick_slab" -> stoneSlabType = "stone_brick";
case "minecraft:quartz_slab" -> stoneSlabType = "quartz";
case "minecraft:nether_brick_slab" -> stoneSlabType = "nether_brick";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("stone_slab_type", stoneSlabType)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
if (NEW_TALLGRASSES.contains(name)) {
replacement = "minecraft:tallgrass";
String tallGrassType;
switch(name) {
case "minecraft:short_grass" -> tallGrassType = "tall";
case "minecraft:fern" -> tallGrassType = "fern";
default -> throw new IllegalStateException("Unexpected value: " + name);
}
NbtMap states = tag.getCompound("states")
.toBuilder()
.putString("tall_grass_type", tallGrassType)
.build();
return tag.toBuilder().putString("name", replacement).putCompound("states", states).build();
}
return tag;
}
}

Datei anzeigen

@ -53,7 +53,6 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockData;
import org.geysermc.geyser.level.block.GeyserCustomBlockState; import org.geysermc.geyser.level.block.GeyserCustomBlockState;
import org.geysermc.geyser.level.block.GeyserGeometryComponent; import org.geysermc.geyser.level.block.GeyserGeometryComponent;
import org.geysermc.geyser.level.block.GeyserMaterialInstance; import org.geysermc.geyser.level.block.GeyserMaterialInstance;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.mappings.MappingsConfigReader;
import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.registry.type.CustomSkull;
@ -325,13 +324,11 @@ public class CustomBlockRegistryPopulator {
// meaning of this version is unknown, but it's required for tags to work and should probably be checked periodically // meaning of this version is unknown, but it's required for tags to work and should probably be checked periodically
.putInt("molangVersion", 1) .putInt("molangVersion", 1)
.putList("permutations", NbtType.COMPOUND, permutations) .putList("permutations", NbtType.COMPOUND, permutations)
.putList("properties", NbtType.COMPOUND, properties); .putList("properties", NbtType.COMPOUND, properties)
.putCompound("vanilla_block_data", NbtMap.builder()
if (GameProtocol.is1_20_60orHigher(protocolVersion)) {
propertyTag.putCompound("vanilla_block_data", NbtMap.builder()
.putInt("block_id", BLOCK_ID.getAndIncrement()) .putInt("block_id", BLOCK_ID.getAndIncrement())
.build()); .build());
}
return new BlockPropertyData(customBlock.identifier(), propertyTag.build()); return new BlockPropertyData(customBlock.identifier(), propertyTag.build());
} }

Datei anzeigen

@ -44,7 +44,6 @@ import org.geysermc.geyser.item.GeyserCustomMappingData;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.components.WearableSlot; import org.geysermc.geyser.item.components.WearableSlot;
import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.mappings.MappingsConfigReader;
import org.geysermc.geyser.registry.type.GeyserMappingItem; import org.geysermc.geyser.registry.type.GeyserMappingItem;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
@ -260,18 +259,11 @@ public class CustomItemRegistryPopulator {
} }
private static void setupBasicItemInfo(int maxDamage, int stackSize, boolean displayHandheld, CustomItemData customItemData, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int protocolVersion) { private static void setupBasicItemInfo(int maxDamage, int stackSize, boolean displayHandheld, CustomItemData customItemData, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder, int protocolVersion) {
NbtMap iconMap; NbtMap iconMap = NbtMap.builder()
if (GameProtocol.is1_20_60orHigher(protocolVersion)) { .putCompound("textures", NbtMap.builder()
iconMap = NbtMap.builder() .putString("default", customItemData.icon())
.putCompound("textures", NbtMap.builder() .build())
.putString("default", customItemData.icon()) .build();
.build())
.build();
} else {
iconMap = NbtMap.builder()
.putString("texture", customItemData.icon())
.build();
}
itemProperties.putCompound("minecraft:icon", iconMap); itemProperties.putCompound("minecraft:icon", iconMap);
if (customItemData.creativeCategory().isPresent()) { if (customItemData.creativeCategory().isPresent()) {
@ -427,64 +419,56 @@ public class CustomItemRegistryPopulator {
// Make bows, tridents, and crossbows enchantable // Make bows, tridents, and crossbows enchantable
itemProperties.putInt("enchantable_value", 1); itemProperties.putInt("enchantable_value", 1);
if (GameProtocol.is1_20_60orHigher(protocolVersion)) { componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder()
componentBuilder.putCompound("minecraft:use_modifiers", NbtMap.builder() .putFloat("use_duration", 100F)
.putFloat("use_duration", 100F) .putFloat("movement_modifier", 0.35F)
.putFloat("movement_modifier", 0.35F) .build());
.build());
switch (mapping) { switch (mapping) {
case "minecraft:bow" -> { case "minecraft:bow" -> {
itemProperties.putString("enchantable_slot", "bow"); itemProperties.putString("enchantable_slot", "bow");
itemProperties.putInt("frame_count", 3); itemProperties.putInt("frame_count", 3);
componentBuilder.putCompound("minecraft:shooter", NbtMap.builder() componentBuilder.putCompound("minecraft:shooter", NbtMap.builder()
.putList("ammunition", NbtType.COMPOUND, List.of( .putList("ammunition", NbtType.COMPOUND, List.of(
NbtMap.builder() NbtMap.builder()
.putCompound("item", NbtMap.builder() .putCompound("item", NbtMap.builder()
.putString("name", "minecraft:arrow") .putString("name", "minecraft:arrow")
.build()) .build())
.putBoolean("use_offhand", true) .putBoolean("use_offhand", true)
.putBoolean("search_inventory", true) .putBoolean("search_inventory", true)
.build() .build()
)) ))
.putFloat("max_draw_duration", 0f) .putFloat("max_draw_duration", 0f)
.putBoolean("charge_on_draw", true) .putBoolean("charge_on_draw", true)
.putBoolean("scale_power_by_draw_duration", true) .putBoolean("scale_power_by_draw_duration", true)
.build()); .build());
componentBuilder.putInt("minecraft:use_duration", 999); componentBuilder.putInt("minecraft:use_duration", 999);
}
case "minecraft:trident" -> {
itemProperties.putString("enchantable_slot", "trident");
componentBuilder.putInt("minecraft:use_duration", 999);
}
case "minecraft:crossbow" -> {
itemProperties.putString("enchantable_slot", "crossbow");
itemProperties.putInt("frame_count", 10);
componentBuilder.putCompound("minecraft:shooter", NbtMap.builder()
.putList("ammunition", NbtType.COMPOUND, List.of(
NbtMap.builder()
.putCompound("item", NbtMap.builder()
.putString("name", "minecraft:arrow")
.build())
.putBoolean("use_offhand", true)
.putBoolean("search_inventory", true)
.build()
))
.putFloat("max_draw_duration", 1f)
.putBoolean("charge_on_draw", true)
.putBoolean("scale_power_by_draw_duration", true)
.build());
componentBuilder.putInt("minecraft:use_duration", 999);
}
} }
} else { case "minecraft:trident" -> {
// ensure client moves at slow speed while charging (note: this was calculated by hand as the movement modifer value does not seem to scale linearly) itemProperties.putString("enchantable_slot", "trident");
componentBuilder.putCompound("minecraft:chargeable", NbtMap.builder().putFloat("movement_modifier", 0.35F).build()); componentBuilder.putInt("minecraft:use_duration", 999);
}
case "minecraft:crossbow" -> {
itemProperties.putString("enchantable_slot", "crossbow");
itemProperties.putInt("frame_count", 10);
// keep item enchantable; also works on 1.20.50 componentBuilder.putCompound("minecraft:shooter", NbtMap.builder()
itemProperties.putString("enchantable_slot", mapping.replace("minecraft:", "")); .putList("ammunition", NbtType.COMPOUND, List.of(
NbtMap.builder()
.putCompound("item", NbtMap.builder()
.putString("name", "minecraft:arrow")
.build())
.putBoolean("use_offhand", true)
.putBoolean("search_inventory", true)
.build()
))
.putFloat("max_draw_duration", 1f)
.putBoolean("charge_on_draw", true)
.putBoolean("scale_power_by_draw_duration", true)
.build());
componentBuilder.putInt("minecraft:use_duration", 999);
}
} }
} }

Datei anzeigen

@ -38,11 +38,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671; import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent; import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
@ -62,7 +59,6 @@ import org.geysermc.geyser.inventory.item.StoredItemMappings;
import org.geysermc.geyser.item.GeyserCustomMappingData; import org.geysermc.geyser.item.GeyserCustomMappingData;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.Item; import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.*; import org.geysermc.geyser.registry.type.*;
@ -91,11 +87,8 @@ public class ItemRegistryPopulator {
public static void populate() { public static void populate() {
List<PaletteVersion> paletteVersions = new ArrayList<>(3); List<PaletteVersion> paletteVersions = new ArrayList<>(3);
paletteVersions.add(new PaletteVersion("1_20_40", Bedrock_v622.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion630_622::remapItem)); paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion685_671::remapItem));
paletteVersions.add(new PaletteVersion("1_20_50", Bedrock_v630.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion649_630::remapItem)); paletteVersions.add(new PaletteVersion("1_21_0", Bedrock_v685.CODEC.getProtocolVersion()));
paletteVersions.add(new PaletteVersion("1_20_60", Bedrock_v649.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion662_649::remapItem));
paletteVersions.add(new PaletteVersion("1_20_70", Bedrock_v662.CODEC.getProtocolVersion(), Collections.emptyMap(), Conversion671_662::remapItem));
paletteVersions.add(new PaletteVersion("1_20_80", Bedrock_v671.CODEC.getProtocolVersion()));
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();
@ -602,18 +595,11 @@ public class ItemRegistryPopulator {
NbtMapBuilder componentBuilder = NbtMap.builder(); NbtMapBuilder componentBuilder = NbtMap.builder();
// Conveniently, as of 1.16.200, the furnace minecart has a texture AND translation string already. // Conveniently, as of 1.16.200, the furnace minecart has a texture AND translation string already.
// Not so conveniently, the way to set an icon changed in 1.20.60 // Not so conveniently, the way to set an icon changed in 1.20.60
NbtMap iconMap; NbtMap iconMap = NbtMap.builder()
if (GameProtocol.is1_20_60orHigher(protocolVersion)) { .putCompound("textures", NbtMap.builder()
iconMap = NbtMap.builder() .putString("default", "minecart_furnace")
.putCompound("textures", NbtMap.builder() .build())
.putString("default", "minecart_furnace") .build();
.build())
.build();
} else {
iconMap = NbtMap.builder()
.putString("texture", "minecart_furnace")
.build();
}
itemProperties.putCompound("minecraft:icon", iconMap); itemProperties.putCompound("minecraft:icon", iconMap);
componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", "item.minecartFurnace.name").build()); componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", "item.minecartFurnace.name").build());

Datei anzeigen

@ -35,6 +35,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.nbt.NbtUtils;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData;
@ -173,7 +174,7 @@ public class RecipeRegistryPopulator {
/* Convert end */ /* Convert end */
return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(), return ShapedRecipeData.shaped(uuid.toString(), shape.get(0).length(), shape.size(),
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false); inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID);
} }
List<ItemData> inputs = new ObjectArrayList<>(); List<ItemData> inputs = new ObjectArrayList<>();
for (JsonNode entry : node.get("inputs")) { for (JsonNode entry : node.get("inputs")) {
@ -196,7 +197,7 @@ public class RecipeRegistryPopulator {
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId);
} }
return ShapelessRecipeData.shapeless(uuid.toString(), return ShapelessRecipeData.shapeless(uuid.toString(),
inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId); inputs.stream().map(ItemDescriptorWithCount::fromItem).toList(), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID);
} }
private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) { private static ItemData getBedrockItemFromIdentifierJson(ItemMapping mapping, JsonNode itemNode) {

Datei anzeigen

@ -1546,6 +1546,10 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
startGamePacket.setRewindHistorySize(0); startGamePacket.setRewindHistorySize(0);
startGamePacket.setServerAuthoritativeBlockBreaking(false); startGamePacket.setServerAuthoritativeBlockBreaking(false);
startGamePacket.setServerId("");
startGamePacket.setWorldId("");
startGamePacket.setScenarioId("");
upstream.sendPacket(startGamePacket); upstream.sendPacket(startGamePacket);
} }

Datei anzeigen

@ -35,7 +35,6 @@ import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.*; import org.geysermc.geyser.inventory.*;
import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater; import org.geysermc.geyser.inventory.updater.ContainerInventoryUpdater;
import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.Blocks;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.BlockEntityUtils;
import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.InventoryUtils;
@ -44,7 +43,6 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket;
import java.util.Collections; import java.util.Collections;
@ -152,13 +150,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
} else if (lecternContainer.getBlockEntityTag() == null) { } else if (lecternContainer.getBlockEntityTag() == null) {
Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition(); Vector3i position = lecternContainer.isUsingRealBlock() ? session.getLastInteractionBlockPosition() : inventory.getHolderPosition();
// If shouldExpectLecternHandled returns true, this is already handled for us
// shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet
// TODO: yeet after 1.20.60 is minimum supported version
boolean shouldRefresh = !session.getGeyser().getWorldManager().shouldExpectLecternHandled(session)
&& !session.getLecternCache().contains(position)
&& !GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion());
NbtMap blockEntityTag; NbtMap blockEntityTag;
if (book.getComponents() != null) { if (book.getComponents() != null) {
int pages = 0; int pages = 0;
@ -205,16 +196,6 @@ public class LecternInventoryTranslator extends AbstractBlockInventoryTranslator
lecternContainer.setPosition(position); lecternContainer.setPosition(position);
BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position); BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position);
if (shouldRefresh) {
// the lectern cache doesn't always exist; only when we must refresh
session.getLecternCache().add(position);
// Close the window - we will reopen it once the client has this data synced
ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(lecternContainer.getJavaId());
session.sendDownstreamGamePacket(closeWindowPacket);
InventoryUtils.closeInventory(session, inventory.getJavaId(), false);
}
} }
} }

Datei anzeigen

@ -550,6 +550,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();
packet.setServerInitiated(true); packet.setServerInitiated(true);
packet.setId((byte) ContainerId.INVENTORY); packet.setId((byte) ContainerId.INVENTORY);
packet.setType(org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType.INVENTORY);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }

Datei anzeigen

@ -152,6 +152,7 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator {
ContainerClosePacket packet = new ContainerClosePacket(); ContainerClosePacket packet = new ContainerClosePacket();
packet.setId((byte) inventory.getBedrockId()); packet.setId((byte) inventory.getBedrockId());
packet.setServerInitiated(true); packet.setServerInitiated(true);
packet.setType(ContainerType.MINECART_CHEST);
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
return; return;
} }

Datei anzeigen

@ -42,7 +42,6 @@ import org.geysermc.geyser.level.block.Blocks;
import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.property.Properties;
import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.level.block.type.BlockState; import org.geysermc.geyser.level.block.type.BlockState;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
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;
@ -331,10 +330,6 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
session.sendDownstreamGamePacket(new ServerboundPlayerAbilitiesPacket(false)); session.sendDownstreamGamePacket(new ServerboundPlayerAbilitiesPacket(false));
break; break;
case DIMENSION_CHANGE_REQUEST_OR_CREATIVE_DESTROY_BLOCK: // Used by client to get book from lecterns and items from item frame in creative mode since 1.20.70 case DIMENSION_CHANGE_REQUEST_OR_CREATIVE_DESTROY_BLOCK: // Used by client to get book from lecterns and items from item frame in creative mode since 1.20.70
if (GameProtocol.isPre1_20_70(session)) {
break;
}
BlockState state = session.getGeyser().getWorldManager().blockAt(session, vector); BlockState state = session.getGeyser().getWorldManager().blockAt(session, vector);
if (state.getValue(Properties.HAS_BOOK, false)) { if (state.getValue(Properties.HAS_BOOK, false)) {

Datei anzeigen

@ -30,6 +30,7 @@ import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.MultiRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.RecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTrimRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTrimRecipeData;
@ -133,7 +134,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
bedrockRecipeIDs.add(uuid.toString()); bedrockRecipeIDs.add(uuid.toString());
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(), craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(),
Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId)); Arrays.asList(inputs), Collections.singletonList(output), uuid, "crafting_table", 0, netId, RecipeUnlockingRequirement.INVALID));
recipeMap.put(netId++, new GeyserShapelessRecipe(shapelessRecipeData)); recipeMap.put(netId++, new GeyserShapelessRecipe(shapelessRecipeData));
} }
addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
@ -158,7 +159,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
bedrockRecipeIDs.add(uuid.toString()); bedrockRecipeIDs.add(uuid.toString());
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(), craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData.shaped(uuid.toString(),
shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs), shapedRecipeData.getWidth(), shapedRecipeData.getHeight(), Arrays.asList(inputs),
Collections.singletonList(output), uuid, "crafting_table", 0, netId, false)); Collections.singletonList(output), uuid, "crafting_table", 0, netId, false, RecipeUnlockingRequirement.INVALID));
recipeMap.put(netId++, new GeyserShapedRecipe(shapedRecipeData)); recipeMap.put(netId++, new GeyserShapedRecipe(shapedRecipeData));
} }
addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs); addRecipeIdentifier(session, recipe.getIdentifier(), bedrockRecipeIDs);
@ -249,7 +250,7 @@ public class JavaUpdateRecipesTranslator extends PacketTranslator<ClientboundUpd
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
// We need to register stonecutting recipes, so they show up on Bedrock // We need to register stonecutting recipes, so they show up on Bedrock
craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(), craftingDataPacket.getCraftingData().add(org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapelessRecipeData.shapeless(uuid.toString(),
Collections.singletonList(descriptor), Collections.singletonList(output), uuid, "stonecutter", 0, netId)); Collections.singletonList(descriptor), Collections.singletonList(output), uuid, "stonecutter", 0, netId, RecipeUnlockingRequirement.INVALID));
// Save the recipe list for reference when crafting // Save the recipe list for reference when crafting
// Add the net ID as the key and the button required + output for the value // Add the net ID as the key and the button required + output for the value

Datei anzeigen

@ -30,6 +30,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.recipe.Ingredient;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData;
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount; import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket; import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
@ -194,7 +195,8 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
"crafting_table", "crafting_table",
0, 0,
newRecipeId, newRecipeId,
false false,
RecipeUnlockingRequirement.INVALID
)); ));
craftPacket.setCleanRecipes(false); craftPacket.setCleanRecipes(false);
session.sendUpstreamPacket(craftPacket); session.sendUpstreamPacket(craftPacket);

Datei anzeigen

@ -29,7 +29,6 @@ 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;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -61,11 +60,6 @@ public class JavaOpenBookTranslator extends PacketTranslator<ClientboundOpenBook
return; return;
} }
// Only post 1.20.60 is it possible to tell the client to open a lectern.
if (!GameProtocol.is1_20_60orHigher(session.getUpstream().getProtocolVersion())) {
return;
}
if (stack.asItem().equals(Items.WRITTEN_BOOK)) { if (stack.asItem().equals(Items.WRITTEN_BOOK)) {
Inventory openInventory = session.getOpenInventory(); Inventory openInventory = session.getOpenInventory();
if (openInventory != null) { if (openInventory != null) {

Datei anzeigen

@ -30,9 +30,7 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.C
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClosePacket;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.geysermc.geyser.inventory.Inventory; import org.geysermc.geyser.inventory.Inventory;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.inventory.OldSmithingTableTranslator; import org.geysermc.geyser.translator.inventory.OldSmithingTableTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -57,10 +55,6 @@ public class JavaOpenScreenTranslator extends PacketTranslator<ClientboundOpenSc
// Hack: ViaVersion translates the old (pre 1.20) smithing table to a furnace (does not work for Bedrock). We can detect this and translate it back to a smithing table. // Hack: ViaVersion translates the old (pre 1.20) smithing table to a furnace (does not work for Bedrock). We can detect this and translate it back to a smithing table.
if (session.isOldSmithingTable() && packet.getType() == ContainerType.FURNACE && packet.getTitle().equals(SMITHING_TABLE_COMPONENT)) { if (session.isOldSmithingTable() && packet.getType() == ContainerType.FURNACE && packet.getTitle().equals(SMITHING_TABLE_COMPONENT)) {
newTranslator = OldSmithingTableTranslator.INSTANCE; newTranslator = OldSmithingTableTranslator.INSTANCE;
} else if (packet.getType() == ContainerType.CRAFTER_3x3 && GameProtocol.isPre1_20_50(session)) {
// Hack 2: Crafters are only supported by 1.20.50 and above. If 1.20.40 tries to open one, they'll get locked out of all inventories.
newTranslator = null; // close immediately below
session.sendMessage(ChatColor.RED + "Update your Bedrock Edition client to 1.20.50 or above to gain access to the Crafter.");
} else { } else {
newTranslator = InventoryTranslator.inventoryTranslator(packet.getType()); newTranslator = InventoryTranslator.inventoryTranslator(packet.getType());
} }

Binäre Datei nicht angezeigt.

@ -1 +1 @@
Subproject commit 968a22bbab02d7d003c5b451a40d8bb2439b0d97 Subproject commit ec45f59c8590945c9226921ef7e339f510983dc1

Datei anzeigen

@ -10,8 +10,7 @@ netty-io-uring = "0.0.25.Final-SNAPSHOT"
guava = "29.0-jre" guava = "29.0-jre"
gson = "2.3.1" # Provided by Spigot 1.8.8 gson = "2.3.1" # Provided by Spigot 1.8.8
websocket = "1.5.1" websocket = "1.5.1"
protocol = "3.0.0.Beta1-20240411.165033-129" protocol = "3.0.0.Beta2-20240520.153053-5"
protocol-connection = "3.0.0.Beta1-20240411.165033-128"
raknet = "1.0.0.CR3-20240416.144209-1" raknet = "1.0.0.CR3-20240416.144209-1"
blockstateupdater="1.20.80-20240411.142413-1" blockstateupdater="1.20.80-20240411.142413-1"
mcauthlib = "e5b0bcc" mcauthlib = "e5b0bcc"
@ -117,12 +116,9 @@ viaproxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaproxy"
viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" } viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" }
websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" } websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" }
#protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" } protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol" }
#protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" } protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" }
#protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" } protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol" }
protocol-common = { group = "com.github.GeyserMC.Protocol", name = "common", version = "ade21be" }
protocol-codec = { group = "com.github.GeyserMC.Protocol", name = "bedrock-codec", version = "ade21be" }
protocol-connection = { group = "com.github.GeyserMC.Protocol", name = "bedrock-connection", version = "ade21be" }
math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" } math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" }