Skip to content

Commit 613718a

Browse files
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 #5281 (GeyserMC/MCProtocolLib@1daf036) * Use correct mcpl dependency * apparently 1.21.4-1 doesn't exist? back to snapshots then --------- Co-authored-by: onebeastchris <[email protected]>
1 parent a7d475e commit 613718a

File tree

9 files changed

+78
-158
lines changed

9 files changed

+78
-158
lines changed

bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
package org.geysermc.geyser.platform.spigot;
2727

28+
import org.geysermc.mcprotocollib.protocol.MinecraftConstants;
2829
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
2930
import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer;
3031
import io.netty.bootstrap.ServerBootstrap;
@@ -176,9 +177,9 @@ private ChannelInitializer<Channel> getChildHandler(GeyserBootstrap bootstrap, C
176177
*/
177178
private void workAroundWeirdBug(GeyserBootstrap bootstrap) {
178179
MinecraftProtocol protocol = new MinecraftProtocol();
179-
LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(),
180-
bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress,
181-
InetAddress.getLoopbackAddress().getHostAddress(), protocol, Runnable::run);
180+
LocalSession session = new LocalSession(this.serverSocketAddress, InetAddress.getLoopbackAddress().getHostAddress(), protocol, Runnable::run);
181+
session.setFlag(MinecraftConstants.CLIENT_HOST, bootstrap.getGeyserConfig().getRemote().address());
182+
session.setFlag(MinecraftConstants.CLIENT_PORT, bootstrap.getGeyserConfig().getRemote().port());
182183
session.connect();
183184
}
184185

core/src/main/java/org/geysermc/geyser/event/type/SessionDisconnectEventImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class SessionDisconnectEventImpl extends SessionDisconnectEvent {
4242
private final Component reasonComponent;
4343

4444
public SessionDisconnectEventImpl(@NonNull GeyserSession session, Component reason) {
45-
super(session, MessageTranslator.convertToPlainText(reason, session.locale()));
45+
super(session, MessageTranslator.convertMessageRaw(reason, session.locale()));
4646
this.reasonComponent = reason;
4747
}
4848
}

core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
4848
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
4949
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
50+
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unbreakable;
5051
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
5152

5253
import java.util.List;
@@ -424,7 +425,7 @@ private int getRepairCost(GeyserItemStack itemStack) {
424425

425426
private boolean hasDurability(GeyserItemStack itemStack) {
426427
if (itemStack.asItem().defaultMaxDamage() > 0) {
427-
return itemStack.getComponentOrFallback(DataComponentType.UNBREAKABLE, false);
428+
return itemStack.getComponent(DataComponentType.UNBREAKABLE) != null;
428429
}
429430
return false;
430431
}

core/src/main/java/org/geysermc/geyser/network/netty/LocalChannelWithRemoteAddress.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,19 @@
2828
import io.netty.channel.local.LocalChannel;
2929

3030
import java.net.InetSocketAddress;
31+
import java.net.SocketAddress;
3132

3233
/**
3334
* Client -> server storing the spoofed remote address.
3435
*/
3536
public class LocalChannelWithRemoteAddress extends LocalChannel {
36-
private InetSocketAddress spoofedAddress;
37+
private SocketAddress spoofedAddress;
3738

38-
public InetSocketAddress spoofedRemoteAddress() {
39+
public SocketAddress spoofedRemoteAddress() {
3940
return spoofedAddress;
4041
}
4142

42-
public void spoofedRemoteAddress(InetSocketAddress socketAddress) {
43+
public void spoofedRemoteAddress(SocketAddress socketAddress) {
4344
this.spoofedAddress = socketAddress;
4445
}
4546
}

core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java

Lines changed: 32 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -27,151 +27,66 @@
2727

2828
import io.netty.bootstrap.Bootstrap;
2929
import io.netty.buffer.ByteBufAllocator;
30-
import io.netty.channel.ChannelHandlerContext;
31-
import io.netty.channel.ChannelInboundHandlerAdapter;
32-
import io.netty.channel.ChannelInitializer;
30+
import io.netty.channel.Channel;
31+
import io.netty.channel.ChannelFactory;
32+
import io.netty.channel.ChannelHandler;
3333
import io.netty.channel.ChannelOption;
34-
import io.netty.channel.ChannelPipeline;
35-
import io.netty.channel.DefaultEventLoopGroup;
34+
import io.netty.channel.ReflectiveChannelFactory;
3635
import io.netty.channel.unix.PreferredDirectByteBufAllocator;
37-
import io.netty.handler.codec.haproxy.HAProxyCommand;
38-
import io.netty.handler.codec.haproxy.HAProxyMessage;
39-
import io.netty.handler.codec.haproxy.HAProxyMessageEncoder;
40-
import io.netty.handler.codec.haproxy.HAProxyProtocolVersion;
41-
import io.netty.handler.codec.haproxy.HAProxyProxiedProtocol;
42-
import io.netty.handler.timeout.ReadTimeoutHandler;
43-
import io.netty.handler.timeout.WriteTimeoutHandler;
44-
import io.netty.util.concurrent.DefaultThreadFactory;
4536
import org.checkerframework.checker.nullness.qual.NonNull;
46-
import org.geysermc.mcprotocollib.network.BuiltinFlags;
47-
import org.geysermc.mcprotocollib.network.codec.PacketCodecHelper;
37+
import org.geysermc.mcprotocollib.network.helper.NettyHelper;
38+
import org.geysermc.mcprotocollib.network.netty.MinecraftChannelInitializer;
4839
import org.geysermc.mcprotocollib.network.packet.PacketProtocol;
49-
import org.geysermc.mcprotocollib.network.tcp.FlushHandler;
50-
import org.geysermc.mcprotocollib.network.tcp.TcpFlowControlHandler;
51-
import org.geysermc.mcprotocollib.network.tcp.TcpPacketCodec;
52-
import org.geysermc.mcprotocollib.network.tcp.TcpPacketCompression;
53-
import org.geysermc.mcprotocollib.network.tcp.TcpPacketEncryptor;
54-
import org.geysermc.mcprotocollib.network.tcp.TcpPacketSizer;
55-
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
56-
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
40+
import org.geysermc.mcprotocollib.network.session.ClientNetworkSession;
5741

58-
import java.net.Inet4Address;
5942
import java.net.InetSocketAddress;
6043
import java.net.SocketAddress;
61-
import java.util.concurrent.CompletableFuture;
6244
import java.util.concurrent.Executor;
63-
import java.util.concurrent.TimeUnit;
6445

6546
/**
6647
* Manages a Minecraft Java session over our LocalChannel implementations.
6748
*/
68-
public final class LocalSession extends TcpSession {
69-
private static DefaultEventLoopGroup DEFAULT_EVENT_LOOP_GROUP;
49+
public final class LocalSession extends ClientNetworkSession {
7050
private static PreferredDirectByteBufAllocator PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR = null;
7151

72-
private final SocketAddress targetAddress;
73-
private final String clientIp;
74-
private final PacketCodecHelper codecHelper;
52+
private final SocketAddress spoofedRemoteAddress;
7553

76-
public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) {
77-
super(host, port, protocol, packetHandlerExecutor);
78-
this.targetAddress = targetAddress;
79-
this.clientIp = clientIp;
80-
this.codecHelper = protocol.createHelper();
54+
public LocalSession(SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) {
55+
super(targetAddress, protocol, packetHandlerExecutor, null, null);
56+
this.spoofedRemoteAddress = new InetSocketAddress(clientIp, 0);
8157
}
8258

8359
@Override
84-
public void connect(boolean wait, boolean transferring) {
85-
if (this.disconnected) {
86-
throw new IllegalStateException("Connection has already been disconnected.");
87-
}
88-
89-
if (DEFAULT_EVENT_LOOP_GROUP == null) {
90-
DEFAULT_EVENT_LOOP_GROUP = new DefaultEventLoopGroup(new DefaultThreadFactory(this.getClass(), true));
91-
Runtime.getRuntime().addShutdownHook(new Thread(
92-
() -> DEFAULT_EVENT_LOOP_GROUP.shutdownGracefully(100, 500, TimeUnit.MILLISECONDS)));
93-
}
94-
95-
final Bootstrap bootstrap = new Bootstrap();
96-
bootstrap.channel(LocalChannelWithRemoteAddress.class);
97-
bootstrap.handler(new ChannelInitializer<LocalChannelWithRemoteAddress>() {
98-
@Override
99-
public void initChannel(@NonNull LocalChannelWithRemoteAddress channel) {
100-
channel.spoofedRemoteAddress(new InetSocketAddress(clientIp, 0));
101-
PacketProtocol protocol = getPacketProtocol();
102-
protocol.newClientSession(LocalSession.this, transferring);
103-
104-
ChannelPipeline pipeline = channel.pipeline();
105-
106-
addHAProxySupport(pipeline);
107-
108-
pipeline.addLast("read-timeout", new ReadTimeoutHandler(getFlag(BuiltinFlags.READ_TIMEOUT, 30)));
109-
pipeline.addLast("write-timeout", new WriteTimeoutHandler(getFlag(BuiltinFlags.WRITE_TIMEOUT, 0)));
110-
111-
pipeline.addLast("encryption", new TcpPacketEncryptor());
112-
pipeline.addLast("sizer", new TcpPacketSizer(protocol.getPacketHeader(), getCodecHelper()));
113-
pipeline.addLast("compression", new TcpPacketCompression(getCodecHelper()));
114-
115-
pipeline.addLast("flow-control", new TcpFlowControlHandler());
116-
pipeline.addLast("codec", new TcpPacketCodec(LocalSession.this, true));
117-
pipeline.addLast("flush-handler", new FlushHandler());
118-
pipeline.addLast("manager", LocalSession.this);
119-
}
120-
}).group(DEFAULT_EVENT_LOOP_GROUP).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getFlag(BuiltinFlags.CLIENT_CONNECT_TIMEOUT, 30) * 1000);
60+
protected ChannelFactory<? extends Channel> getChannelFactory() {
61+
return new ReflectiveChannelFactory<>(LocalChannelWithRemoteAddress.class);
62+
}
12163

64+
@Override
65+
protected void setOptions(Bootstrap bootstrap) {
12266
if (PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR != null) {
12367
bootstrap.option(ChannelOption.ALLOCATOR, PREFERRED_DIRECT_BYTE_BUF_ALLOCATOR);
12468
}
69+
}
12570

126-
bootstrap.remoteAddress(targetAddress);
127-
128-
CompletableFuture<Void> handleFuture = new CompletableFuture<>();
129-
bootstrap.connect().addListener((futureListener) -> {
130-
if (!futureListener.isSuccess()) {
131-
exceptionCaught(null, futureListener.cause());
132-
}
71+
@Override
72+
protected ChannelHandler getChannelHandler() {
73+
return new MinecraftChannelInitializer<>(channel -> {
74+
PacketProtocol protocol = getPacketProtocol();
75+
protocol.newClientSession(LocalSession.this);
13376

134-
handleFuture.complete(null);
135-
});
77+
return LocalSession.this;
78+
}, true) {
79+
@Override
80+
public void initChannel(@NonNull Channel channel) throws Exception {
81+
((LocalChannelWithRemoteAddress) channel).spoofedRemoteAddress(spoofedRemoteAddress);
13682

137-
if (wait) {
138-
handleFuture.join();
139-
}
140-
}
83+
NettyHelper.initializeHAProxySupport(LocalSession.this, channel);
14184

142-
@Override
143-
public MinecraftCodecHelper getCodecHelper() {
144-
return (MinecraftCodecHelper) this.codecHelper;
85+
super.initChannel(channel);
86+
}
87+
};
14588
}
14689

147-
// TODO duplicate code
148-
private void addHAProxySupport(ChannelPipeline pipeline) {
149-
InetSocketAddress clientAddress = getFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS);
150-
if (clientAddress != null) {
151-
pipeline.addFirst("proxy-protocol-packet-sender", new ChannelInboundHandlerAdapter() {
152-
@Override
153-
public void channelActive(@NonNull ChannelHandlerContext ctx) throws Exception {
154-
HAProxyProxiedProtocol proxiedProtocol = clientAddress.getAddress() instanceof Inet4Address ? HAProxyProxiedProtocol.TCP4 : HAProxyProxiedProtocol.TCP6;
155-
InetSocketAddress remoteAddress;
156-
if (ctx.channel().remoteAddress() instanceof InetSocketAddress) {
157-
remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
158-
} else {
159-
remoteAddress = new InetSocketAddress(host, port);
160-
}
161-
ctx.channel().writeAndFlush(new HAProxyMessage(
162-
HAProxyProtocolVersion.V2, HAProxyCommand.PROXY, proxiedProtocol,
163-
clientAddress.getAddress().getHostAddress(), remoteAddress.getAddress().getHostAddress(),
164-
clientAddress.getPort(), remoteAddress.getPort()
165-
));
166-
ctx.pipeline().remove(this);
167-
ctx.pipeline().remove("proxy-protocol-encoder");
168-
super.channelActive(ctx);
169-
}
170-
});
171-
pipeline.addFirst("proxy-protocol-encoder", HAProxyMessageEncoder.INSTANCE);
172-
}
173-
}
174-
17590
/**
17691
* Should only be called when direct ByteBufs should be preferred. At this moment, this should only be called on BungeeCord.
17792
*/

core/src/main/java/org/geysermc/geyser/session/DownstreamSession.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
import lombok.RequiredArgsConstructor;
3030
import net.kyori.adventure.text.Component;
3131
import org.checkerframework.checker.nullness.qual.NonNull;
32+
import org.geysermc.mcprotocollib.network.ClientSession;
3233
import org.geysermc.mcprotocollib.network.packet.Packet;
33-
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
3434
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
3535

3636
@Getter
3737
@RequiredArgsConstructor
3838
public class DownstreamSession {
39-
private final TcpSession session;
39+
private final ClientSession session;
4040

4141
public void sendPacket(@NonNull Packet packet) {
4242
this.session.send(packet);

0 commit comments

Comments
 (0)