Skip to content

Commit

Permalink
Feature: 1.21.50 support (#5180)
Browse files Browse the repository at this point in the history
* Drop pre-1.21.40 support, start adapting to 1.21.50 changes

* fix camera definitions

* remove more old workarounds, make it compile

* Add 1.21.50 data files

* Add item tags, update block registry populator

* finishing touches

* Don't add items to the creative inventory that we don't have a Java mapping for

* fix readme typo
  • Loading branch information
onebeastchris authored Dec 3, 2024
1 parent d956354 commit 9e276c1
Show file tree
Hide file tree
Showing 42 changed files with 2,139 additions and 42,708 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,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!

## Supported Versions
Geyser is currently supporting Minecraft Bedrock 1.20.80 - 1.21.44 and Minecraft Java 1.21.2/1.21.3. For more information, please see [here](https://geysermc.org/wiki/geyser/supported-versions/).
Geyser is currently supporting Minecraft Bedrock 1.21.40 - 1.21.50 and Minecraft Java 1.21.2/1.21.3. For more information, please see [here](https://geysermc.org/wiki/geyser/supported-versions/).

## Setting Up
Take a look [here](https://geysermc.org/wiki/geyser/setup/) for how to set up Geyser.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.AttributeUtils;
import org.geysermc.geyser.util.DimensionUtils;
Expand Down Expand Up @@ -235,12 +234,7 @@ protected void setAirSupply(int amount) {
// the bubbles visually pop
setFlag(EntityFlag.BREATHING, amount >= this.lastAirSupply);
this.lastAirSupply = amount;

if (amount == getMaxAir() && GameProtocol.isPre1_21_0(session)) {
super.setAirSupply(0); // Hide the bubble counter from the UI for the player
} else {
super.setAirSupply(amount);
}
super.setAirSupply(amount);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@

public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksEvent {

private final Map<String, ResourcePack> packs;
private final Map<UUID, ResourcePack> packs;

public SessionLoadResourcePacksEventImpl(GeyserSession session, Map<String, ResourcePack> packMap) {
public SessionLoadResourcePacksEventImpl(GeyserSession session, Map<UUID, ResourcePack> packMap) {
super(session);
this.packs = packMap;
}

public @NonNull Map<String, ResourcePack> getPacks() {
public @NonNull Map<UUID, ResourcePack> getPacks() {
return packs;
}

Expand All @@ -54,16 +54,16 @@ public SessionLoadResourcePacksEventImpl(GeyserSession session, Map<String, Reso

@Override
public boolean register(@NonNull ResourcePack resourcePack) {
String packID = resourcePack.manifest().header().uuid().toString();
UUID packID = resourcePack.manifest().header().uuid();
if (packs.containsValue(resourcePack) || packs.containsKey(packID)) {
return false;
}
packs.put(resourcePack.manifest().header().uuid().toString(), resourcePack);
packs.put(resourcePack.manifest().header().uuid(), resourcePack);
return true;
}

@Override
public boolean unregister(@NonNull UUID uuid) {
return packs.remove(uuid.toString()) != null;
return packs.remove(uuid) != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ public class CameraDefinitions {

static {
CAMERA_PRESETS = List.of(
new CameraPreset(CameraPerspective.FIRST_PERSON.id(), "", null, null, null, null, null, null, OptionalBoolean.empty(), null, OptionalBoolean.empty(), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset(CameraPerspective.FREE.id(), "", null, null, null, null, null, null, OptionalBoolean.empty(), null, OptionalBoolean.empty(), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset(CameraPerspective.THIRD_PERSON.id(), "", null, null, null, null, null, null, OptionalBoolean.empty(), null, OptionalBoolean.empty(), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset(CameraPerspective.THIRD_PERSON_FRONT.id(), "", null, null, null, null, null, null, OptionalBoolean.empty(), null, OptionalBoolean.empty(), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset("geyser:free_audio", "minecraft:free", null, null, null, null, null, CameraAudioListener.PLAYER, OptionalBoolean.empty(), null, OptionalBoolean.of(false), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset("geyser:free_effects", "minecraft:free", null, null, null, null, null, CameraAudioListener.CAMERA, OptionalBoolean.empty(), null, OptionalBoolean.of(true), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()),
new CameraPreset("geyser:free_audio_effects", "minecraft:free", null, null, null, null, null, CameraAudioListener.PLAYER, OptionalBoolean.empty(), null, OptionalBoolean.of(true), null, null, null, OptionalBoolean.empty(), OptionalBoolean.empty()));
CameraPreset.builder().identifier(CameraPerspective.FIRST_PERSON.id()).build(),
CameraPreset.builder().identifier(CameraPerspective.FREE.id()).build(),
CameraPreset.builder().identifier(CameraPerspective.THIRD_PERSON.id()).build(),
CameraPreset.builder().identifier(CameraPerspective.THIRD_PERSON_FRONT.id()).build(),
CameraPreset.builder().identifier("geyser:free_audio").parentPreset(CameraPerspective.FREE.id()).listener(CameraAudioListener.PLAYER).playEffect(OptionalBoolean.of(false)).build(),
CameraPreset.builder().identifier("geyser:free_effects").parentPreset(CameraPerspective.FREE.id()).listener(CameraAudioListener.CAMERA).playEffect(OptionalBoolean.of(true)).build(),
CameraPreset.builder().identifier("geyser:free_audio_effects").parentPreset(CameraPerspective.FREE.id()).listener(CameraAudioListener.PLAYER).playEffect(OptionalBoolean.of(true)).build()
);

SimpleDefinitionRegistry.Builder<NamedDefinition> builder = SimpleDefinitionRegistry.builder();
for (int i = 0; i < CAMERA_PRESETS.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,40 +416,6 @@ public BlockCollision getCollisionLavaWalking(int blockId, int blockY, BoundingB
return BlockUtils.getCollision(blockId);
}

public boolean isOnGround() {
// Temporary until pre-1.21.30 support is dropped.
Vector3d bottomCenter = playerBoundingBox.getBottomCenter();
Vector3i groundPos = Vector3i.from(bottomCenter.getX(), bottomCenter.getY() - 1, bottomCenter.getZ());
BlockCollision collision = BlockUtils.getCollisionAt(session, groundPos);
if (collision == null) {
return false; // Probably air.
}

// Hack to not check below the player
playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() - 0.001);
playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() + 0.002);

boolean intersected = collision.checkIntersection(groundPos.getX(), groundPos.getY(), groundPos.getZ(), playerBoundingBox);

playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() + 0.001);
playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() - 0.002);

boolean result;
if (intersected) {
result = true;
} else {
// Hack to check slightly below the player
playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() + 0.001);
playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() - 0.002);

result = collision.checkIntersection(groundPos.getX(), groundPos.getY(), groundPos.getZ(), playerBoundingBox);

playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() - 0.001);
playerBoundingBox.setMiddleY(playerBoundingBox.getMiddleY() + 0.002);
}
return result;
}

/**
* @return if the player is currently in a water block
*/
Expand Down
48 changes: 7 additions & 41 deletions core/src/main/java/org/geysermc/geyser/network/GameProtocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,9 @@

import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.v671.Bedrock_v671;
import org.cloudburstmc.protocol.bedrock.codec.v685.Bedrock_v685;
import org.cloudburstmc.protocol.bedrock.codec.v686.Bedrock_v686;
import org.cloudburstmc.protocol.bedrock.codec.v712.Bedrock_v712;
import org.cloudburstmc.protocol.bedrock.codec.v729.Bedrock_v729;
import org.cloudburstmc.protocol.bedrock.codec.v748.Bedrock_v748;
import org.cloudburstmc.protocol.bedrock.codec.v765.Bedrock_v765;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodec;
import org.geysermc.mcprotocollib.protocol.codec.PacketCodec;

Expand All @@ -51,8 +46,9 @@ 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 = CodecProcessor.processCodec(Bedrock_v748.CODEC.toBuilder()
.minecraftVersion("1.21.44")
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = CodecProcessor.processCodec(Bedrock_v765.CODEC.toBuilder()
.minecraftVersion("1.21.50")
.protocolVersion(766)
.build());

/**
Expand All @@ -67,24 +63,10 @@ public final class GameProtocol {
private static final PacketCodec DEFAULT_JAVA_CODEC = MinecraftCodec.CODEC;

static {
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v671.CODEC.toBuilder()
.minecraftVersion("1.20.80/1.20.81")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v685.CODEC.toBuilder()
.minecraftVersion("1.21.0/1.21.1")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v686.CODEC.toBuilder()
.minecraftVersion("1.21.2/1.21.3")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v712.CODEC.toBuilder()
.minecraftVersion("1.21.20 - 1.21.23")
.build()));
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v729.CODEC.toBuilder()
.minecraftVersion("1.21.30/1.21.31")
.build()));
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v748.CODEC.toBuilder()
.minecraftVersion("1.21.40 - 1.21.44")
.build());
.build()));
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
}

/**
Expand All @@ -103,22 +85,6 @@ public final class GameProtocol {

/* Bedrock convenience methods to gatekeep features and easily remove the check on version removal */

public static boolean isPre1_21_0(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v685.CODEC.getProtocolVersion();
}

public static boolean isPre1_21_2(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v686.CODEC.getProtocolVersion();
}

public static boolean isPre1_21_30(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v729.CODEC.getProtocolVersion();
}

public static boolean isPre1_21_40(GeyserSession session) {
return session.getUpstream().getProtocolVersion() < Bedrock_v748.CODEC.getProtocolVersion();
}

/**
* Gets the {@link PacketCodec} for Minecraft: Java Edition.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@
import java.util.Deque;
import java.util.HashMap;
import java.util.OptionalInt;
import java.util.UUID;

public class UpstreamPacketHandler extends LoggingPacketHandler {

private boolean networkSettingsRequested = false;
private final Deque<String> packsToSent = new ArrayDeque<>();
private final Deque<String> packsToSend = new ArrayDeque<>();
private final CompressionStrategy compressionStrategy;

private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
Expand Down Expand Up @@ -133,8 +134,6 @@ private boolean setCorrectCodec(int protocolVersion) {
}

session.getUpstream().getSession().setCodec(packetCodec);
// FIXME temporary until 1.20.80 is dropped
session.getPlayerEntity().resetAir();
return true;
}

Expand Down Expand Up @@ -209,10 +208,12 @@ public PacketSignal handle(LoginPacket loginPacket) {
PackCodec codec = pack.codec();
ResourcePackManifest.Header header = pack.manifest().header();
resourcePacksInfo.getResourcePackInfos().add(new ResourcePacksInfoPacket.Entry(
header.uuid().toString(), header.version().toString(), codec.size(), pack.contentKey(),
header.uuid(), header.version().toString(), codec.size(), pack.contentKey(),
"", header.uuid().toString(), false, false, false, ""));
}
resourcePacksInfo.setForcedToAccept(GeyserImpl.getInstance().getConfig().isForceResourcePacks());
resourcePacksInfo.setWorldTemplateId(UUID.randomUUID());
resourcePacksInfo.setWorldTemplateVersion("*");
session.sendUpstreamPacket(resourcePacksInfo);

GeyserLocale.loadGeyserLocale(session.locale());
Expand All @@ -233,8 +234,8 @@ public PacketSignal handle(ResourcePackClientResponsePacket packet) {
break;

case SEND_PACKS:
packsToSent.addAll(packet.getPackIds());
sendPackDataInfo(packsToSent.pop());
packsToSend.addAll(packet.getPackIds());
sendPackDataInfo(packsToSend.pop());
break;

case HAVE_ALL_PACKS:
Expand Down Expand Up @@ -311,7 +312,7 @@ public PacketSignal handle(PlayerAuthInputPacket packet) {
@Override
public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
ResourcePackChunkDataPacket data = new ResourcePackChunkDataPacket();
ResourcePack pack = this.resourcePackLoadEvent.getPacks().get(packet.getPackId().toString());
ResourcePack pack = this.resourcePackLoadEvent.getPacks().get(packet.getPackId());
PackCodec codec = pack.codec();

data.setChunkIndex(packet.getChunkIndex());
Expand All @@ -335,8 +336,8 @@ public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
session.sendUpstreamPacket(data);

// Check if it is the last chunk and send next pack in queue when available.
if (remainingSize <= GeyserResourcePack.CHUNK_SIZE && !packsToSent.isEmpty()) {
sendPackDataInfo(packsToSent.pop());
if (remainingSize <= GeyserResourcePack.CHUNK_SIZE && !packsToSend.isEmpty()) {
sendPackDataInfo(packsToSend.pop());
}

return PacketSignal.HANDLED;
Expand All @@ -345,7 +346,8 @@ public PacketSignal handle(ResourcePackChunkRequestPacket packet) {
private void sendPackDataInfo(String id) {
ResourcePackDataInfoPacket data = new ResourcePackDataInfoPacket();
String[] packID = id.split("_");
ResourcePack pack = this.resourcePackLoadEvent.getPacks().get(packID[0]);
UUID uuid = UUID.fromString(packID[0]);
ResourcePack pack = this.resourcePackLoadEvent.getPacks().get(uuid);
PackCodec codec = pack.codec();
ResourcePackManifest.Header header = pack.manifest().header();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
* Holds all the common registries in Geyser.
Expand Down Expand Up @@ -163,7 +164,7 @@ public final class Registries {
/**
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
*/
public static final SimpleMappedDeferredRegistry<String, ResourcePack> RESOURCE_PACKS = SimpleMappedDeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), RegistryLoaders.RESOURCE_PACKS);
public static final SimpleMappedDeferredRegistry<UUID, ResourcePack> RESOURCE_PACKS = SimpleMappedDeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), RegistryLoaders.RESOURCE_PACKS);

/**
* A versioned registry holding most Bedrock tags, with the Java item list (sorted) being the key, and the tag name as the value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -54,7 +55,7 @@
/**
* Loads {@link ResourcePack}s within a {@link Path} directory, firing the {@link GeyserLoadResourcePacksEvent}.
*/
public class ResourcePackLoader implements RegistryLoader<Path, Map<String, ResourcePack>> {
public class ResourcePackLoader implements RegistryLoader<Path, Map<UUID, ResourcePack>> {

static final PathMatcher PACK_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**.{zip,mcpack}");

Expand All @@ -64,8 +65,8 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
* Loop through the packs directory and locate valid resource pack files
*/
@Override
public Map<String, ResourcePack> load(Path directory) {
Map<String, ResourcePack> packMap = new HashMap<>();
public Map<UUID, ResourcePack> load(Path directory) {
Map<UUID, ResourcePack> packMap = new HashMap<>();

if (!Files.exists(directory)) {
try {
Expand Down Expand Up @@ -100,7 +101,7 @@ public Map<String, ResourcePack> load(Path directory) {
for (Path path : event.resourcePacks()) {
try {
GeyserResourcePack pack = readPack(path);
packMap.put(pack.manifest().header().uuid().toString(), pack);
packMap.put(pack.manifest().header().uuid(), pack);
} catch (Exception e) {
e.printStackTrace();
}
Expand Down
Loading

0 comments on commit 9e276c1

Please sign in to comment.