Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 1.21.50 support #5180

Merged
merged 9 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.20.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
47 changes: 6 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,8 @@ public final class GameProtocol {
* Default Bedrock codec that should act as a fallback. Should represent the latest available
* release of the game that Geyser supports.
*/
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = 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")
.build());

/**
Expand All @@ -67,24 +62,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")
SUPPORTED_BEDROCK_CODECS.add(CodecProcessor.processCodec(Bedrock_v748.CODEC.toBuilder()
.minecraftVersion("1.21.50")
.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()
.minecraftVersion("1.21.40 - 1.21.44")
.build());
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
}

/**
Expand All @@ -103,22 +84,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,7 +208,7 @@ 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());
Expand All @@ -233,8 +232,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 +310,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 +334,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 +344,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
Original file line number Diff line number Diff line change
Expand Up @@ -2241,9 +2241,7 @@ public int protocolVersion() {

@Override
public void closeForm() {
if (!GameProtocol.isPre1_21_2(this)) {
sendUpstreamPacket(new ClientboundCloseFormPacket());
}
sendUpstreamPacket(new ClientboundCloseFormPacket());
}

public void addCommandEnum(String name, String enums) {
Expand Down
Loading
Loading