mirror of
https://github.com/GeyserMC/Geyser.git
synced 2026-01-04 15:31:36 +00:00
Implement session restructure mcpl PR, fix disconnect messages in configuration stage (#5196)
* Implement session restructure mcpl PR
* Bump mcpl
* Update mcpl api usage
* Update MCPL to release, fix https://github.com/GeyserMC/Geyser/issues/5281 (1daf036f57)
* Use correct mcpl dependency
* apparently 1.21.4-1 doesn't exist? back to snapshots then
---------
Co-authored-by: onebeastchris <github@onechris.mozmail.com>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.platform.spigot;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||
import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
@@ -176,9 +177,9 @@ public class GeyserSpigotInjector extends GeyserInjector {
|
||||
*/
|
||||
private void workAroundWeirdBug(GeyserBootstrap bootstrap) {
|
||||
MinecraftProtocol protocol = new MinecraftProtocol();
|
||||
LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(),
|
||||
bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress,
|
||||
InetAddress.getLoopbackAddress().getHostAddress(), protocol, Runnable::run);
|
||||
LocalSession session = new LocalSession(this.serverSocketAddress, InetAddress.getLoopbackAddress().getHostAddress(), protocol, Runnable::run);
|
||||
session.setFlag(MinecraftConstants.CLIENT_HOST, bootstrap.getGeyserConfig().getRemote().address());
|
||||
session.setFlag(MinecraftConstants.CLIENT_PORT, bootstrap.getGeyserConfig().getRemote().port());
|
||||
session.connect();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class SessionDisconnectEventImpl extends SessionDisconnectEvent {
|
||||
private final Component reasonComponent;
|
||||
|
||||
public SessionDisconnectEventImpl(@NonNull GeyserSession session, Component reason) {
|
||||
super(session, MessageTranslator.convertToPlainText(reason, session.locale()));
|
||||
super(session, MessageTranslator.convertMessageRaw(reason, session.locale()));
|
||||
this.reasonComponent = reason;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unbreakable;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
|
||||
|
||||
import java.util.List;
|
||||
@@ -424,7 +425,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
||||
|
||||
private boolean hasDurability(GeyserItemStack itemStack) {
|
||||
if (itemStack.asItem().defaultMaxDamage() > 0) {
|
||||
return itemStack.getComponentOrFallback(DataComponentType.UNBREAKABLE, false);
|
||||
return itemStack.getComponent(DataComponentType.UNBREAKABLE) != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,18 +28,19 @@ package org.geysermc.geyser.network.netty;
|
||||
import io.netty.channel.local.LocalChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
* Client -> server storing the spoofed remote address.
|
||||
*/
|
||||
public class LocalChannelWithRemoteAddress extends LocalChannel {
|
||||
private InetSocketAddress spoofedAddress;
|
||||
private SocketAddress spoofedAddress;
|
||||
|
||||
public InetSocketAddress spoofedRemoteAddress() {
|
||||
public SocketAddress spoofedRemoteAddress() {
|
||||
return spoofedAddress;
|
||||
}
|
||||
|
||||
public void spoofedRemoteAddress(InetSocketAddress socketAddress) {
|
||||
public void spoofedRemoteAddress(SocketAddress socketAddress) {
|
||||
this.spoofedAddress = socketAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,150 +27,65 @@ package org.geysermc.geyser.network.netty;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFactory;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.DefaultEventLoopGroup;
|
||||
import io.netty.channel.ReflectiveChannelFactory;
|
||||
import io.netty.channel.unix.PreferredDirectByteBufAllocator;
|
||||
import io.netty.handler.codec.haproxy.HAProxyCommand;
|
||||
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||
import io.netty.handler.codec.haproxy.HAProxyMessageEncoder;
|
||||
import io.netty.handler.codec.haproxy.HAProxyProtocolVersion;
|
||||
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import io.netty.handler.timeout.WriteTimeoutHandler;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.mcprotocollib.network.BuiltinFlags;
|
||||
import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper;
|
||||
import org.geysermc.mcprotocollib.network.helper.NettyHelper;
|
||||
import org.geysermc.mcprotocollib.network.netty.MinecraftChannelInitializer;
|
||||
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
|
||||
import org.geysermc.mcprotocollib.network.tcp.FlushHandler;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpFlowControlHandler;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpPacketCodec;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpPacketCompression;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpPacketEncryptor;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpPacketSizer;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
|
||||
import org.geysermc.mcprotocollib.network.session.ClientNetworkSession;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Manages a Minecraft Java session over our LocalChannel implementations.
|
||||
*/
|
||||
public final class LocalSession extends TcpSession {
|
||||
private static DefaultEventLoopGroup DEFAULT_EVENT_LOOP_GROUP;
|
||||
public final class LocalSession extends ClientNetworkSession {
|
||||
private static PreferredDirectByteBufAllocator PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR = null;
|
||||
|
||||
private final SocketAddress targetAddress;
|
||||
private final String clientIp;
|
||||
private final PacketCodecHelper codecHelper;
|
||||
private final SocketAddress spoofedRemoteAddress;
|
||||
|
||||
public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) {
|
||||
super(host, port, protocol, packetHandlerExecutor);
|
||||
this.targetAddress = targetAddress;
|
||||
this.clientIp = clientIp;
|
||||
this.codecHelper = protocol.createHelper();
|
||||
public LocalSession(SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) {
|
||||
super(targetAddress, protocol, packetHandlerExecutor, null, null);
|
||||
this.spoofedRemoteAddress = new InetSocketAddress(clientIp, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(boolean wait, boolean transferring) {
|
||||
if (this.disconnected) {
|
||||
throw new IllegalStateException("Connection has already been disconnected.");
|
||||
}
|
||||
|
||||
if (DEFAULT_EVENT_LOOP_GROUP == null) {
|
||||
DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(new DefaultThreadFactory(this.getClass(), true));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(
|
||||
() -> DEFAULT_EVENT_LOOP_GROUP.shutdownGracefully(100, 500, TimeUnit.MILLISECONDS)));
|
||||
}
|
||||
|
||||
final Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.channel(LocalChannelWithRemoteAddress.class);
|
||||
bootstrap.handler(new ChannelInitializer<LocalChannelWithRemoteAddress>() {
|
||||
@Override
|
||||
public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) {
|
||||
channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0));
|
||||
PacketProtocol protocol = getPacketProtocol();
|
||||
protocol.newClientSession(LocalSession.this, transferring);
|
||||
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
|
||||
addHAProxySupport(pipeline);
|
||||
|
||||
pipeline.addLast("read-timeout", new ReadTimeoutHandler(getFlag(BuiltinFlags.READ_TIMEOUT, 30)));
|
||||
pipeline.addLast("write-timeout", new WriteTimeoutHandler(getFlag(BuiltinFlags.WRITE_TIMEOUT, 0)));
|
||||
|
||||
pipeline.addLast("encryption", new TcpPacketEncryptor());
|
||||
pipeline.addLast("sizer", new TcpPacketSizer(protocol.getPacketHeader(), getCodecHelper()));
|
||||
pipeline.addLast("compression", new TcpPacketCompression(getCodecHelper()));
|
||||
|
||||
pipeline.addLast("flow-control", new TcpFlowControlHandler());
|
||||
pipeline.addLast("codec", new TcpPacketCodec(LocalSession.this, true));
|
||||
pipeline.addLast("flush-handler", new FlushHandler());
|
||||
pipeline.addLast("manager", LocalSession.this);
|
||||
}
|
||||
}).group(DEFAULT_EVENT_LOOP_GROUP).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getFlag(BuiltinFlags.CLIENT_CONNECT_TIMEOUT, 30) * 1000);
|
||||
protected ChannelFactory<? extends Channel> getChannelFactory() {
|
||||
return new ReflectiveChannelFactory<>(LocalChannelWithRemoteAddress.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOptions(Bootstrap bootstrap) {
|
||||
if (PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR != null) {
|
||||
bootstrap.option(ChannelOption.ALLOCATOR, PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR);
|
||||
}
|
||||
|
||||
bootstrap.remoteAddress(targetAddress);
|
||||
|
||||
CompletableFuture<Void> handleFuture = new CompletableFuture<>();
|
||||
bootstrap.connect().addListener((futureListener) -> {
|
||||
if (!futureListener.isSuccess()) {
|
||||
exceptionCaught(null, futureListener.cause());
|
||||
}
|
||||
|
||||
handleFuture.complete(null);
|
||||
});
|
||||
|
||||
if (wait) {
|
||||
handleFuture.join();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftCodecHelper getCodecHelper() {
|
||||
return (MinecraftCodecHelper) this.codecHelper;
|
||||
}
|
||||
protected ChannelHandler getChannelHandler() {
|
||||
return new MinecraftChannelInitializer<>(channel -> {
|
||||
PacketProtocol protocol = getPacketProtocol();
|
||||
protocol.newClientSession(LocalSession.this);
|
||||
|
||||
// TODO duplicate code
|
||||
private void addHAProxySupport(ChannelPipeline pipeline) {
|
||||
InetSocketAddress clientAddress = getFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS);
|
||||
if (clientAddress != null) {
|
||||
pipeline.addFirst("proxy-protocol-packet-sender", new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelActive(@NonNull ChannelHandlerContext ctx) throws Exception {
|
||||
HAProxyProxiedProtocol proxiedProtocol = clientAddress.getAddress() instanceof Inet4Address ? HAProxyProxiedProtocol.TCP4 : HAProxyProxiedProtocol.TCP6;
|
||||
InetSocketAddress remoteAddress;
|
||||
if (ctx.channel().remoteAddress() instanceof InetSocketAddress) {
|
||||
remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
} else {
|
||||
remoteAddress = new InetSocketAddress(host, port);
|
||||
}
|
||||
ctx.channel().writeAndFlush(new HAProxyMessage(
|
||||
HAProxyProtocolVersion.V2, HAProxyCommand.PROXY, proxiedProtocol,
|
||||
clientAddress.getAddress().getHostAddress(), remoteAddress.getAddress().getHostAddress(),
|
||||
clientAddress.getPort(), remoteAddress.getPort()
|
||||
));
|
||||
ctx.pipeline().remove(this);
|
||||
ctx.pipeline().remove("proxy-protocol-encoder");
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
});
|
||||
pipeline.addFirst("proxy-protocol-encoder", HAProxyMessageEncoder.INSTANCE);
|
||||
}
|
||||
}
|
||||
return LocalSession.this;
|
||||
}, true) {
|
||||
@Override
|
||||
public void initChannel(@NonNull Channel channel) throws Exception {
|
||||
((LocalChannelWithRemoteAddress) channel).spoofedRemoteAddress(spoofedRemoteAddress);
|
||||
|
||||
NettyHelper.initializeHAProxySupport(LocalSession.this, channel);
|
||||
|
||||
super.initChannel(channel);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called when direct ByteBufs should be preferred. At this moment, this should only be called on BungeeCord.
|
||||
|
||||
@@ -29,14 +29,14 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.mcprotocollib.network.ClientSession;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class DownstreamSession {
|
||||
private final TcpSession session;
|
||||
private final ClientSession session;
|
||||
|
||||
public void sendPacket(@NonNull Packet packet) {
|
||||
this.session.send(packet);
|
||||
|
||||
@@ -181,9 +181,9 @@ import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.geyser.util.MinecraftAuthLogger;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.network.BuiltinFlags;
|
||||
import org.geysermc.mcprotocollib.network.ClientSession;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpClientSession;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
import org.geysermc.mcprotocollib.network.session.ClientNetworkSession;
|
||||
import org.geysermc.mcprotocollib.protocol.ClientListener;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
|
||||
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
|
||||
@@ -199,6 +199,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.setting.ParticleStatus;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.setting.SkinPart;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.CustomStatistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.statistic.Statistic;
|
||||
import org.geysermc.mcprotocollib.protocol.data.handshake.HandshakeIntent;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundClientInformationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatCommandSignedPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundChatPacket;
|
||||
@@ -770,7 +771,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
// Default move speed
|
||||
// Bedrock clients move very fast by default until they get an attribute packet correcting the speed
|
||||
attributesPacket.setAttributes(Collections.singletonList(
|
||||
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
|
||||
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
|
||||
upstream.sendPacket(attributesPacket);
|
||||
|
||||
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
|
||||
@@ -826,8 +827,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
StepMCToken.MCToken mcToken = mcProfile.getMcToken();
|
||||
|
||||
protocol = new MinecraftProtocol(
|
||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||
mcToken.getAccessToken()
|
||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||
mcToken.getAccessToken()
|
||||
);
|
||||
geyser.saveAuthChain(bedrockUsername(), GSON.toJson(step.toJson(response)));
|
||||
return Boolean.TRUE;
|
||||
@@ -872,7 +873,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
sendUpstreamPacket(packet);
|
||||
|
||||
final PendingMicrosoftAuthentication.AuthenticationTask task = geyser.getPendingMicrosoftAuthentication().getOrCreateTask(
|
||||
getAuthData().xuid()
|
||||
getAuthData().xuid()
|
||||
);
|
||||
if (task.getAuthentication() != null && task.getAuthentication().isDone()) {
|
||||
onMicrosoftLoginComplete(task);
|
||||
@@ -898,8 +899,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
if (ex != null) {
|
||||
geyser.getLogger().error("Failed to log in with Microsoft code!", ex);
|
||||
if (ex instanceof CompletionException ce
|
||||
&& ce.getCause() instanceof MinecraftRequestException mre
|
||||
&& mre.getResponse().getStatusCode() == 404) {
|
||||
&& ce.getCause() instanceof MinecraftRequestException mre
|
||||
&& mre.getResponse().getStatusCode() == 404) {
|
||||
// Player is trying to join with a Microsoft account that doesn't have Java Edition purchased
|
||||
disconnect(GeyserLocale.getPlayerLocaleString("geyser.network.remote.invalid_account", locale()));
|
||||
} else {
|
||||
@@ -912,8 +913,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
StepMCToken.MCToken mcToken = mcProfile.getMcToken();
|
||||
|
||||
this.protocol = new MinecraftProtocol(
|
||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||
mcToken.getAccessToken()
|
||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||
mcToken.getAccessToken()
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -937,7 +938,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
GeyserImpl.getInstance().eventBus().fire(loginEvent);
|
||||
if (loginEvent.isCancelled()) {
|
||||
String disconnectReason = loginEvent.disconnectReason() == null ?
|
||||
BedrockDisconnectReasons.DISCONNECTED : loginEvent.disconnectReason();
|
||||
BedrockDisconnectReasons.DISCONNECTED : loginEvent.disconnectReason();
|
||||
disconnect(disconnectReason);
|
||||
return;
|
||||
}
|
||||
@@ -948,15 +949,17 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
// Start ticking
|
||||
tickThread = tickEventLoop.scheduleAtFixedRate(this::tick, nanosecondsPerTick, nanosecondsPerTick, TimeUnit.NANOSECONDS);
|
||||
|
||||
TcpSession downstream;
|
||||
ClientSession downstream;
|
||||
if (geyser.getBootstrap().getSocketAddress() != null) {
|
||||
// We're going to connect through the JVM and not through TCP
|
||||
downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(),
|
||||
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
|
||||
this.protocol, this.tickEventLoop);
|
||||
downstream = new LocalSession(geyser.getBootstrap().getSocketAddress(),
|
||||
upstream.getAddress().getAddress().getHostAddress(),
|
||||
this.protocol, this.tickEventLoop);
|
||||
downstream.setFlag(MinecraftConstants.CLIENT_HOST, this.remoteServer.address());
|
||||
downstream.setFlag(MinecraftConstants.CLIENT_PORT, this.remoteServer.port());
|
||||
this.downstream = new DownstreamSession(downstream);
|
||||
} else {
|
||||
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), "0.0.0.0", 0, this.protocol, null, tickEventLoop);
|
||||
downstream = new ClientNetworkSession(new InetSocketAddress(this.remoteServer.address(), this.remoteServer.port()), this.protocol, tickEventLoop, null, null);
|
||||
this.downstream = new DownstreamSession(downstream);
|
||||
|
||||
boolean resolveSrv = false;
|
||||
@@ -986,11 +989,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
protocol.setUseDefaultListeners(false);
|
||||
|
||||
// MCPL listener comes first to handle protocol state switching before Geyser translates packets
|
||||
downstream.addListener(new ClientListener(ProtocolState.LOGIN, loginEvent.transferring()));
|
||||
downstream.addListener(new ClientListener(HandshakeIntent.LOGIN));
|
||||
// Geyser adapter second to ensure translating packets in the correct states
|
||||
downstream.addListener(new GeyserSessionAdapter(this));
|
||||
|
||||
downstream.connect(false, loginEvent.transferring());
|
||||
downstream.setFlag(BuiltinFlags.CLIENT_TRANSFERRING, loginEvent.transferring());
|
||||
downstream.connect(false);
|
||||
|
||||
if (!daylightCycle) {
|
||||
setDaylightCycle(true);
|
||||
@@ -1287,7 +1291,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
public void setClientData(BedrockClientData data) {
|
||||
this.clientData = data;
|
||||
this.inputCache.setInputMode(
|
||||
org.cloudburstmc.protocol.bedrock.data.InputMode.values()[data.getCurrentInputMode().ordinal()]);
|
||||
org.cloudburstmc.protocol.bedrock.data.InputMode.values()[data.getCurrentInputMode().ordinal()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1295,7 +1299,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
*/
|
||||
public void useItem(Hand hand) {
|
||||
sendDownstreamGamePacket(new ServerboundUseItemPacket(
|
||||
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
|
||||
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
|
||||
}
|
||||
|
||||
public void releaseItem() {
|
||||
@@ -1351,7 +1355,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
private boolean disableBlocking() {
|
||||
if (playerEntity.getFlag(EntityFlag.BLOCKING)) {
|
||||
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM,
|
||||
Vector3i.ZERO, Direction.DOWN, 0);
|
||||
Vector3i.ZERO, Direction.DOWN, 0);
|
||||
sendDownstreamGamePacket(releaseItemPacket);
|
||||
playerEntity.setFlag(EntityFlag.BLOCKING, false);
|
||||
return true;
|
||||
@@ -1361,7 +1365,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
|
||||
public void requestOffhandSwap() {
|
||||
ServerboundPlayerActionPacket swapHandsPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, Vector3i.ZERO,
|
||||
Direction.DOWN, 0);
|
||||
Direction.DOWN, 0);
|
||||
sendDownstreamGamePacket(swapHandsPacket);
|
||||
}
|
||||
|
||||
@@ -1585,7 +1589,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
unconfirmedTeleport.resetUnconfirmedFor();
|
||||
geyser.getLogger().debug("Resending teleport " + unconfirmedTeleport.getTeleportConfirmId());
|
||||
getPlayerEntity().moveAbsolute(Vector3f.from(unconfirmedTeleport.getX(), unconfirmedTeleport.getY(), unconfirmedTeleport.getZ()),
|
||||
unconfirmedTeleport.getYaw(), unconfirmedTeleport.getPitch(), playerEntity.isOnGround(), true);
|
||||
unconfirmedTeleport.getYaw(), unconfirmedTeleport.getPitch(), playerEntity.isOnGround(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1841,8 +1845,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
public void sendJavaClientSettings() {
|
||||
// Locale is lowercase on Java - (https://github.com/GeyserMC/Geyser/issues/5235)
|
||||
ServerboundClientInformationPacket clientSettingsPacket = new ServerboundClientInformationPacket(locale().toLowerCase(Locale.ROOT),
|
||||
getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS,
|
||||
HandPreference.RIGHT_HAND, false, true, ParticleStatus.ALL); // TODO particle status
|
||||
getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS,
|
||||
HandPreference.RIGHT_HAND, false, true, ParticleStatus.ALL); // TODO particle status
|
||||
sendDownstreamPacket(clientSettingsPacket);
|
||||
}
|
||||
|
||||
@@ -1895,8 +1899,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
return switch (pose) {
|
||||
case SNEAKING -> 1.27f;
|
||||
case SWIMMING,
|
||||
FALL_FLYING, // Elytra
|
||||
SPIN_ATTACK -> 0.4f; // Trident spin attack
|
||||
FALL_FLYING, // Elytra
|
||||
SPIN_ATTACK -> 0.4f; // Trident spin attack
|
||||
case SLEEPING -> 0.2f;
|
||||
default -> EntityDefinitions.PLAYER.offset();
|
||||
};
|
||||
|
||||
@@ -119,9 +119,7 @@ public final class CustomItemTranslator {
|
||||
|
||||
private static boolean isDamagableItem(DataComponents components) {
|
||||
// mapping.getMaxDamage > 0 should also be checked (return false if not true) but we already check prior to this function
|
||||
Boolean unbreakable = components.get(DataComponentType.UNBREAKABLE);
|
||||
// Tag must either not be present or be set to false
|
||||
return unbreakable == null || !unbreakable;
|
||||
return components.get(DataComponentType.UNBREAKABLE) == null;
|
||||
}
|
||||
|
||||
private CustomItemTranslator() {
|
||||
|
||||
@@ -15,7 +15,7 @@ protocol-common = "3.0.0.Beta5-20241213.160944-20"
|
||||
protocol-codec = "3.0.0.Beta5-20241213.160944-20"
|
||||
raknet = "1.0.0.CR3-20240416.144209-1"
|
||||
minecraftauth = "4.1.1"
|
||||
mcprotocollib = "1.21.4-20241222.190029-11"
|
||||
mcprotocollib = "1.21.4-20250118.113140-16"
|
||||
adventure = "4.14.0"
|
||||
adventure-platform = "4.3.0"
|
||||
junit = "5.9.2"
|
||||
|
||||
Reference in New Issue
Block a user