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

API 2.8.3: Support 1.21.100, support sending skins via api (#5742)

* Support 1.21.100

* Add GeyserConnection#sendSkin, #joinAddress and #joinPort (#5641)

* Add GeyserConnection#sendSkin and GeyserConnection#clientConnectionAddress

* address reviews

* Bump to 2.8.3

* Split into joinAddress / joinPort

* Update api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java

* Update api/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java

* improve address / port parsing
This commit is contained in:
chris
2025-08-05 16:25:23 +02:00
committed by GitHub
parent bea10781bd
commit a41cc9e4a3
14 changed files with 22203 additions and 2049 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!
## Supported Versions
Geyser is currently supporting Minecraft Bedrock 1.21.70 - 1.21.94 and Minecraft Java 1.21.7 - 1.21.8. For more information, please see [here](https://geysermc.org/wiki/geyser/supported-versions/).
Geyser is currently supporting Minecraft Bedrock 1.21.70 - 1.21.100 and Minecraft Java 1.21.7 - 1.21.8. 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.

View File

@@ -26,6 +26,7 @@
package org.geysermc.geyser.api.connection;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.index.qual.Positive;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.api.connection.Connection;
@@ -35,8 +36,11 @@ import org.geysermc.geyser.api.command.CommandSource;
import org.geysermc.geyser.api.entity.EntityData;
import org.geysermc.geyser.api.entity.type.GeyserEntity;
import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
import org.geysermc.geyser.api.skin.SkinData;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
@@ -118,6 +122,50 @@ public interface GeyserConnection extends Connection, CommandSource {
*/
void sendCommand(String command);
/**
* Gets the hostname or ip address the player used to join this Geyser instance.
* Example:
* <ul>
* <li> {@code test.geysermc.org} </li>
* <li> {@code 127.0.0.1} </li>
* <li> {@code 06e9:c755:4eff:5f13:9b4c:4b21:9df2:6a73} </li>
* </ul>
*
* @throws NoSuchElementException if called before the session is fully initialized
* @return the ip address or hostname string the player used to join
* @since 2.8.3
*/
@NonNull
String joinAddress();
/**
* Gets the port the player used to join this Geyser instance.
* Example:
* <ul>
* <li> {@code 19132} </li>
* <li> {@code 2202} </li>
* </ul>
*
* @throws NoSuchElementException if called before the session is fully initialized
* @return the port the player used to join
* @since 2.8.3
*/
@Positive
int joinPort();
/**
* Applies a skin to a player seen by this Geyser connection.
* If the uuid matches the {@link GeyserConnection#javaUuid()}, this
* will update the skin of this Geyser connection.
* If the player uuid provided is not known to this connection, this method
* will silently return.
*
* @param player which player this skin should be applied to
* @param skinData the skin data to apply
* @since 2.8.3
*/
void sendSkin(@NonNull UUID player, @NonNull SkinData skinData);
/**
* @param javaId the Java entity ID to look up.
* @return a {@link GeyserEntity} if present in this connection's entity tracker.

View File

@@ -148,10 +148,10 @@ inner class GitInfo {
tasks.register<DownloadFilesTask>("downloadBedrockData") {
urls = listOf(
"https://raw.githubusercontent.com/CloudburstMC/Data/master/entity_identifiers.dat",
"https://raw.githubusercontent.com/CloudburstMC/Data/master/biome_definitions.dat",
"https://raw.githubusercontent.com/CloudburstMC/Data/master/block_palette.nbt",
"https://raw.githubusercontent.com/CloudburstMC/Data/master/creative_items.json",
"https://raw.githubusercontent.com/CloudburstMC/Data/master/runtime_item_states.json"
"https://raw.githubusercontent.com/CloudburstMC/Data/master/runtime_item_states.json",
"https://raw.githubusercontent.com/CloudburstMC/Data/master/stripped_biome_definitions.json"
)
suffixedFiles = listOf("block_palette.nbt", "creative_items.json", "runtime_item_states.json")

View File

@@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v786.Bedrock_v786;
import org.cloudburstmc.protocol.bedrock.codec.v800.Bedrock_v800;
import org.cloudburstmc.protocol.bedrock.codec.v818.Bedrock_v818;
import org.cloudburstmc.protocol.bedrock.codec.v819.Bedrock_v819;
import org.cloudburstmc.protocol.bedrock.codec.v827.Bedrock_v827;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.geysermc.geyser.api.util.MinecraftVersion;
import org.geysermc.geyser.impl.MinecraftVersionImpl;
@@ -87,6 +88,7 @@ public final class GameProtocol {
register(Bedrock_v800.CODEC, "1.21.80", "1.21.81", "1.21.82", "1.21.83", "1.21.84");
register(Bedrock_v818.CODEC, "1.21.90", "1.21.91", "1.21.92");
register(Bedrock_v819.CODEC, "1.21.93", "1.21.94");
register(Bedrock_v827.CODEC, "1.21.100");
MinecraftVersion latestBedrock = SUPPORTED_BEDROCK_VERSIONS.get(SUPPORTED_BEDROCK_VERSIONS.size() - 1);
DEFAULT_BEDROCK_VERSION = latestBedrock.versionString();

View File

@@ -45,6 +45,8 @@ import org.cloudburstmc.nbt.NbtUtils;
import org.cloudburstmc.protocol.bedrock.codec.v786.Bedrock_v786;
import org.cloudburstmc.protocol.bedrock.codec.v800.Bedrock_v800;
import org.cloudburstmc.protocol.bedrock.codec.v818.Bedrock_v818;
import org.cloudburstmc.protocol.bedrock.codec.v819.Bedrock_v819;
import org.cloudburstmc.protocol.bedrock.codec.v827.Bedrock_v827;
import org.cloudburstmc.protocol.bedrock.data.BlockPropertyData;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.geysermc.geyser.GeyserImpl;
@@ -120,6 +122,8 @@ public final class BlockRegistryPopulator {
.put(ObjectIntPair.of("1_21_70", Bedrock_v786.CODEC.getProtocolVersion()), Conversion800_786::remapBlock)
.put(ObjectIntPair.of("1_21_80", Bedrock_v800.CODEC.getProtocolVersion()), tag -> tag)
.put(ObjectIntPair.of("1_21_90", Bedrock_v818.CODEC.getProtocolVersion()), tag -> tag)
.put(ObjectIntPair.of("1_21_90", Bedrock_v819.CODEC.getProtocolVersion()), tag -> tag)
.put(ObjectIntPair.of("1_21_100", Bedrock_v827.CODEC.getProtocolVersion()), tag -> tag)
.build();
// We can keep this strong as nothing should be garbage collected

View File

@@ -49,6 +49,7 @@ import org.cloudburstmc.protocol.bedrock.codec.v786.Bedrock_v786;
import org.cloudburstmc.protocol.bedrock.codec.v800.Bedrock_v800;
import org.cloudburstmc.protocol.bedrock.codec.v818.Bedrock_v818;
import org.cloudburstmc.protocol.bedrock.codec.v819.Bedrock_v819;
import org.cloudburstmc.protocol.bedrock.codec.v827.Bedrock_v827;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.definitions.SimpleItemDefinition;
@@ -147,6 +148,7 @@ public class ItemRegistryPopulator {
paletteVersions.add(new PaletteVersion("1_21_80", Bedrock_v800.CODEC.getProtocolVersion(), fallbacks1_21_80));
paletteVersions.add(new PaletteVersion("1_21_90", Bedrock_v818.CODEC.getProtocolVersion(), Map.of(Items.MUSIC_DISC_LAVA_CHICKEN, Items.MUSIC_DISC_CHIRP)));
paletteVersions.add(new PaletteVersion("1_21_93", Bedrock_v819.CODEC.getProtocolVersion()));
paletteVersions.add(new PaletteVersion("1_21_100", Bedrock_v827.CODEC.getProtocolVersion()));
GeyserBootstrap bootstrap = GeyserImpl.getInstance().getBootstrap();

View File

@@ -46,6 +46,7 @@ import net.raphimc.minecraftauth.step.java.StepMCProfile;
import net.raphimc.minecraftauth.step.java.StepMCToken;
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.index.qual.Positive;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -120,6 +121,7 @@ import org.geysermc.geyser.api.entity.type.player.GeyserPlayerEntity;
import org.geysermc.geyser.api.event.bedrock.SessionDisconnectEvent;
import org.geysermc.geyser.api.event.bedrock.SessionLoginEvent;
import org.geysermc.geyser.api.network.RemoteServer;
import org.geysermc.geyser.api.skin.SkinData;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.GeyserCommandSource;
@@ -132,6 +134,7 @@ import org.geysermc.geyser.entity.type.BoatEntity;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.ItemFrameEntity;
import org.geysermc.geyser.entity.type.Tickable;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler;
@@ -149,7 +152,6 @@ import org.geysermc.geyser.inventory.recipe.GeyserSmithingRecipe;
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.BlockItem;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.level.physics.CollisionManager;
@@ -184,6 +186,7 @@ import org.geysermc.geyser.session.cache.waypoint.WaypointCache;
import org.geysermc.geyser.session.dialog.BuiltInDialog;
import org.geysermc.geyser.session.dialog.Dialog;
import org.geysermc.geyser.session.dialog.DialogManager;
import org.geysermc.geyser.skin.SkinManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator;
@@ -234,6 +237,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
@@ -1577,6 +1582,33 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
this.sendCommandPacket(command);
}
@Override
public @NonNull String joinAddress() {
String combined = Optional.ofNullable(clientData).orElseThrow().getServerAddress();
int index = combined.lastIndexOf(":");
return combined.substring(0, index);
}
@Override
public @Positive int joinPort() {
String combined = Optional.ofNullable(clientData).orElseThrow().getServerAddress();
int index = combined.lastIndexOf(":");
return Integer.parseInt(combined.substring(index + 1));
}
@Override
public void sendSkin(@NonNull UUID player, @NonNull SkinData skinData) {
Objects.requireNonNull(player, "player uuid must not be null!");
Objects.requireNonNull(skinData, "skinData must not be null!");
PlayerEntity entity = this.entityCache.getPlayerEntity(player);
if (entity == null) {
return;
}
SkinManager.sendSkinPacket(this, entity, skinData);
}
@Override
public void openPauseScreenAdditions() {
List<Dialog> additions = tagCache.get(DialogTag.PAUSE_SCREEN_ADDITIONS);

View File

@@ -111,7 +111,7 @@ public class GeyserSessionAdapter extends SessionAdapter {
String address;
if (geyser.getConfig().getRemote().isForwardHost()) {
address = clientData.getServerAddress().split(":")[0];
address = session.joinAddress();
} else {
address = intentionPacket.getHostname();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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