1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-19 14:59:27 +00:00

API 2.9.1: Support 1.21.124, add tint/isotropic method to custom block material, allowing updating entity properties immediately (#5991)

* Prepare for 1.21.124

* Add tint method and isotropic properties to block material instances (#5977)

* Add tint method and isotropic properties to block material instances

* Check if tint method is null before including it

* Lets cover the null check on render method too

* Allow updating properties immediately (#5961)

---------

Co-authored-by: rtm516 <rtm516@users.noreply.github.com>
This commit is contained in:
chris
2025-11-20 14:52:56 +01:00
committed by GitHub
parent c0c7b51935
commit 53596d05bc
10 changed files with 116 additions and 39 deletions

View File

@@ -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! 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 ## Supported Versions
Geyser is currently supporting Minecraft Bedrock 1.21.90 - 1.21.120 and Minecraft Java 1.21.9 - 1.21.10. For more information, please see [here](https://geysermc.org/wiki/geyser/supported-versions/). Geyser is currently supporting Minecraft Bedrock 1.21.90 - 1.21.124 and Minecraft Java 1.21.9 - 1.21.10. For more information, please see [here](https://geysermc.org/wiki/geyser/supported-versions/).
## Setting Up ## Setting Up
Take a look [here](https://geysermc.org/wiki/geyser/setup/) for how to set up Geyser. Take a look [here](https://geysermc.org/wiki/geyser/setup/) for how to set up Geyser.

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org * Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -46,6 +46,13 @@ public interface MaterialInstance {
*/ */
@Nullable String renderMethod(); @Nullable String renderMethod();
/**
* Gets the tint method of the block
*
* @return The tint method of the block.
*/
@Nullable String tintMethod();
/** /**
* Gets if the block should be dimmed on certain faces * Gets if the block should be dimmed on certain faces
* *
@@ -60,6 +67,13 @@ public interface MaterialInstance {
*/ */
boolean ambientOcclusion(); boolean ambientOcclusion();
/**
* Gets if the block is isotropic
*
* @return If the block is isotropic.
*/
boolean isotropic();
/** /**
* Creates a builder for MaterialInstance. * Creates a builder for MaterialInstance.
* *
@@ -74,10 +88,14 @@ public interface MaterialInstance {
Builder renderMethod(@Nullable String renderMethod); Builder renderMethod(@Nullable String renderMethod);
Builder tintMethod(@Nullable String tintMethod);
Builder faceDimming(boolean faceDimming); Builder faceDimming(boolean faceDimming);
Builder ambientOcclusion(boolean ambientOcclusion); Builder ambientOcclusion(boolean ambientOcclusion);
Builder isotropic(boolean isotropic);
MaterialInstance build(); MaterialInstance build();
} }
} }

View File

@@ -62,7 +62,23 @@ public interface GeyserEntity {
/** /**
* Updates multiple properties with just one update packet. * Updates multiple properties with just one update packet.
* @see BatchPropertyUpdater * @see BatchPropertyUpdater
*
* @param consumer a batch updater
* @since 2.9.0 * @since 2.9.0
*/ */
void updatePropertiesBatched(Consumer<BatchPropertyUpdater> consumer); default void updatePropertiesBatched(Consumer<BatchPropertyUpdater> consumer) {
this.updatePropertiesBatched(consumer, false);
}
/**
* Updates multiple properties with just one update packet, which can be sent immediately to the client.
* Usually, sending updates immediately is not required except for specific situations where packet batching
* would result in update order issues.
* @see BatchPropertyUpdater
*
* @param consumer a batch updater
* @param immediate whether this update should be sent immediately
* @since 2.9.1
*/
void updatePropertiesBatched(Consumer<BatchPropertyUpdater> consumer, boolean immediate);
} }

View File

@@ -778,8 +778,11 @@ public class Entity implements GeyserEntity {
} }
@Override @Override
public void updatePropertiesBatched(Consumer<BatchPropertyUpdater> consumer) { public void updatePropertiesBatched(Consumer<BatchPropertyUpdater> consumer, boolean immediate) {
if (this.propertyManager != null) { if (this.propertyManager == null) {
throw new IllegalArgumentException("Given entity has no registered properties!");
}
Objects.requireNonNull(consumer); Objects.requireNonNull(consumer);
GeyserEntityProperties propertyDefinitions = definition.registeredProperties(); GeyserEntityProperties propertyDefinitions = definition.registeredProperties();
consumer.accept(new BatchPropertyUpdater() { consumer.accept(new BatchPropertyUpdater() {
@@ -808,10 +811,11 @@ public class Entity implements GeyserEntity {
packet.setRuntimeEntityId(getGeyserId()); packet.setRuntimeEntityId(getGeyserId());
propertyManager.applyFloatProperties(packet.getProperties().getFloatProperties()); propertyManager.applyFloatProperties(packet.getProperties().getFloatProperties());
propertyManager.applyIntProperties(packet.getProperties().getIntProperties()); propertyManager.applyIntProperties(packet.getProperties().getIntProperties());
if (immediate) {
session.sendUpstreamPacketImmediately(packet);
} else {
session.sendUpstreamPacket(packet); session.sendUpstreamPacket(packet);
} }
} else {
throw new IllegalArgumentException("Given entity has no registered properties!");
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org * Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -33,14 +33,18 @@ import org.geysermc.geyser.api.block.custom.component.MaterialInstance;
public class GeyserMaterialInstance implements MaterialInstance { public class GeyserMaterialInstance implements MaterialInstance {
private final String texture; private final String texture;
private final String renderMethod; private final String renderMethod;
private final String tintMethod;
private final boolean faceDimming; private final boolean faceDimming;
private final boolean ambientOcclusion; private final boolean ambientOcclusion;
private final boolean isotropic;
GeyserMaterialInstance(Builder builder) { GeyserMaterialInstance(Builder builder) {
this.texture = builder.texture; this.texture = builder.texture;
this.renderMethod = builder.renderMethod; this.renderMethod = builder.renderMethod;
this.tintMethod = builder.tintMethod;
this.faceDimming = builder.faceDimming; this.faceDimming = builder.faceDimming;
this.ambientOcclusion = builder.ambientOcclusion; this.ambientOcclusion = builder.ambientOcclusion;
this.isotropic = builder.isotropic;
} }
@Override @Override
@@ -53,6 +57,11 @@ public class GeyserMaterialInstance implements MaterialInstance {
return renderMethod; return renderMethod;
} }
@Override
public @Nullable String tintMethod() {
return tintMethod;
}
@Override @Override
public boolean faceDimming() { public boolean faceDimming() {
return faceDimming; return faceDimming;
@@ -63,11 +72,18 @@ public class GeyserMaterialInstance implements MaterialInstance {
return ambientOcclusion; return ambientOcclusion;
} }
@Override
public boolean isotropic() {
return isotropic;
}
public static class Builder implements MaterialInstance.Builder { public static class Builder implements MaterialInstance.Builder {
private String texture; private String texture;
private String renderMethod; private String renderMethod;
private String tintMethod;
private boolean faceDimming; private boolean faceDimming;
private boolean ambientOcclusion; private boolean ambientOcclusion;
private boolean isotropic;
@Override @Override
public Builder texture(@Nullable String texture) { public Builder texture(@Nullable String texture) {
@@ -81,6 +97,12 @@ public class GeyserMaterialInstance implements MaterialInstance {
return this; return this;
} }
@Override
public Builder tintMethod(@Nullable String tintMethod) {
this.tintMethod = tintMethod;
return this;
}
@Override @Override
public Builder faceDimming(boolean faceDimming) { public Builder faceDimming(boolean faceDimming) {
this.faceDimming = faceDimming; this.faceDimming = faceDimming;
@@ -93,6 +115,12 @@ public class GeyserMaterialInstance implements MaterialInstance {
return this; return this;
} }
@Override
public MaterialInstance.Builder isotropic(boolean isotropic) {
this.isotropic = isotropic;
return this;
}
@Override @Override
public MaterialInstance build() { public MaterialInstance build() {
return new GeyserMaterialInstance(this); return new GeyserMaterialInstance(this);

View File

@@ -89,6 +89,7 @@ public final class GameProtocol {
register(Bedrock_v827.CODEC, "1.21.100", "1.21.101"); register(Bedrock_v827.CODEC, "1.21.100", "1.21.101");
register(Bedrock_v844.CODEC, "1.21.111", "1.21.112", "1.21.113", "1.21.114"); register(Bedrock_v844.CODEC, "1.21.111", "1.21.112", "1.21.113", "1.21.114");
register(Bedrock_v859.CODEC, "1.21.120", "1.21.121", "1.21.122", "1.21.123"); register(Bedrock_v859.CODEC, "1.21.120", "1.21.121", "1.21.122", "1.21.123");
register(Bedrock_v859.CODEC.toBuilder().protocolVersion(860).minecraftVersion("1.21.124").build());
MinecraftVersion latestBedrock = SUPPORTED_BEDROCK_VERSIONS.get(SUPPORTED_BEDROCK_VERSIONS.size() - 1); MinecraftVersion latestBedrock = SUPPORTED_BEDROCK_VERSIONS.get(SUPPORTED_BEDROCK_VERSIONS.size() - 1);
DEFAULT_BEDROCK_VERSION = latestBedrock.versionString(); DEFAULT_BEDROCK_VERSION = latestBedrock.versionString();

View File

@@ -34,7 +34,6 @@ import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
@@ -128,7 +127,9 @@ public final class BlockRegistryPopulator {
.put(ObjectIntPair.of("1_21_90", Bedrock_v819.CODEC.getProtocolVersion()), Conversion827_819::remapBlock) .put(ObjectIntPair.of("1_21_90", Bedrock_v819.CODEC.getProtocolVersion()), Conversion827_819::remapBlock)
.put(ObjectIntPair.of("1_21_100", Bedrock_v827.CODEC.getProtocolVersion()), Conversion844_827::remapBlock) .put(ObjectIntPair.of("1_21_100", Bedrock_v827.CODEC.getProtocolVersion()), Conversion844_827::remapBlock)
.put(ObjectIntPair.of("1_21_110", Bedrock_v844.CODEC.getProtocolVersion()), tag -> tag) .put(ObjectIntPair.of("1_21_110", Bedrock_v844.CODEC.getProtocolVersion()), tag -> tag)
// 1.21.110 -> 1.21.12x doesn't change the block palette
.put(ObjectIntPair.of("1_21_110", Bedrock_v859.CODEC.getProtocolVersion()), tag -> tag) .put(ObjectIntPair.of("1_21_110", Bedrock_v859.CODEC.getProtocolVersion()), tag -> tag)
.put(ObjectIntPair.of("1_21_110", 860), 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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org * Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -448,8 +448,8 @@ public class CustomBlockRegistryPopulator {
for (Map.Entry<String, MaterialInstance> entry : components.materialInstances().entrySet()) { for (Map.Entry<String, MaterialInstance> entry : components.materialInstances().entrySet()) {
MaterialInstance materialInstance = entry.getValue(); MaterialInstance materialInstance = entry.getValue();
NbtMapBuilder materialBuilder = NbtMap.builder() NbtMapBuilder materialBuilder = NbtMap.builder()
.putString("render_method", materialInstance.renderMethod()) .putBoolean("ambient_occlusion", materialInstance.ambientOcclusion())
.putBoolean("ambient_occlusion", materialInstance.ambientOcclusion()); .putBoolean("isotropic", materialInstance.isotropic());
if (GameProtocol.is1_21_110orHigher(protocolVersion)) { if (GameProtocol.is1_21_110orHigher(protocolVersion)) {
materialBuilder.putBoolean("packed_bools", materialInstance.faceDimming()); materialBuilder.putBoolean("packed_bools", materialInstance.faceDimming());
@@ -457,6 +457,14 @@ public class CustomBlockRegistryPopulator {
materialBuilder.putBoolean("face_dimming", materialInstance.faceDimming()); materialBuilder.putBoolean("face_dimming", materialInstance.faceDimming());
} }
if (materialInstance.renderMethod() != null) {
materialBuilder.putString("render_method", materialInstance.renderMethod());
}
if (materialInstance.tintMethod() != null) {
materialBuilder.putString("tint_method", materialInstance.tintMethod());
}
// Texture can be unspecified when blocks.json is used in RP (https://wiki.bedrock.dev/blocks/blocks-stable.html#minecraft-material-instances) // Texture can be unspecified when blocks.json is used in RP (https://wiki.bedrock.dev/blocks/blocks-stable.html#minecraft-material-instances)
if (materialInstance.texture() != null) { if (materialInstance.texture() != null) {
materialBuilder.putString("texture", materialInstance.texture()); materialBuilder.putString("texture", materialInstance.texture());

View File

@@ -194,12 +194,13 @@ public class ItemRegistryPopulator {
Map<Item, Item> eightOneEightFallbacks = new HashMap<>(eightOneNineFallbacks); Map<Item, Item> eightOneEightFallbacks = new HashMap<>(eightOneNineFallbacks);
eightOneEightFallbacks.put(Items.MUSIC_DISC_LAVA_CHICKEN, Items.MUSIC_DISC_CHIRP); eightOneEightFallbacks.put(Items.MUSIC_DISC_LAVA_CHICKEN, Items.MUSIC_DISC_CHIRP);
List<PaletteVersion> paletteVersions = new ArrayList<>(4); List<PaletteVersion> paletteVersions = new ArrayList<>(6);
paletteVersions.add(new PaletteVersion("1_21_90", Bedrock_v818.CODEC.getProtocolVersion(), eightOneEightFallbacks, Conversion844_827::remapItem)); paletteVersions.add(new PaletteVersion("1_21_90", Bedrock_v818.CODEC.getProtocolVersion(), eightOneEightFallbacks, Conversion844_827::remapItem));
paletteVersions.add(new PaletteVersion("1_21_93", Bedrock_v819.CODEC.getProtocolVersion(), eightOneNineFallbacks, Conversion844_827::remapItem)); paletteVersions.add(new PaletteVersion("1_21_93", Bedrock_v819.CODEC.getProtocolVersion(), eightOneNineFallbacks, Conversion844_827::remapItem));
paletteVersions.add(new PaletteVersion("1_21_100", Bedrock_v827.CODEC.getProtocolVersion(), eightTwoSevenFallbacks, Conversion844_827::remapItem)); paletteVersions.add(new PaletteVersion("1_21_100", Bedrock_v827.CODEC.getProtocolVersion(), eightTwoSevenFallbacks, Conversion844_827::remapItem));
paletteVersions.add(new PaletteVersion("1_21_110", Bedrock_v844.CODEC.getProtocolVersion())); paletteVersions.add(new PaletteVersion("1_21_110", Bedrock_v844.CODEC.getProtocolVersion()));
paletteVersions.add(new PaletteVersion("1_21_120", Bedrock_v859.CODEC.getProtocolVersion())); paletteVersions.add(new PaletteVersion("1_21_120", Bedrock_v859.CODEC.getProtocolVersion()));
paletteVersions.add(new PaletteVersion("1_21_120", 860));
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap(); GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();

View File

@@ -8,5 +8,5 @@ org.gradle.vfs.watch=false
group=org.geysermc group=org.geysermc
id=geyser id=geyser
version=2.9.0-SNAPSHOT version=2.9.1-SNAPSHOT
description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers. description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers.