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

1.20.2 Support #1088

Merged
merged 42 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a38fa8d
initial work for 1.20.2
Paul19988 Sep 23, 2023
0adc6f0
update
Paul19988 Sep 24, 2023
e24b8da
I *think* I made it better
Paul19988 Sep 24, 2023
d2c30fc
fix client not agreeing with finish
Paul19988 Sep 24, 2023
22ee0c8
latest changes
Paul19988 Sep 24, 2023
3e9fb04
possibly fix old support
Paul19988 Sep 24, 2023
b014087
More bugfixes
Redned235 Sep 24, 2023
d81c78a
remove sysouts
Paul19988 Sep 24, 2023
1925195
Add a play packet queue for packets sent during the config state
Redned235 Sep 24, 2023
98013f0
Fix resource pack packet id
Redned235 Sep 24, 2023
252c40a
reduce amount of reformatting
Paul19988 Sep 24, 2023
2e5f7fb
fix random spaces
Paul19988 Sep 24, 2023
09a41c2
remove wildcards
Paul19988 Sep 24, 2023
f5b7fa8
make requested changes
Paul19988 Sep 24, 2023
87cd110
reformat using google style format
Paul19988 Sep 24, 2023
bea6c30
fix style violations
Paul19988 Sep 24, 2023
0a6e913
remove redundent code
Paul19988 Sep 24, 2023
4908501
remove missed references
Paul19988 Sep 24, 2023
034953e
Ensure super.channelInactive is called in PlayPacketQueueHandler
Redned235 Sep 25, 2023
75411ce
Fix login race case
pkt77 Sep 24, 2023
0bc584e
sigh
Redned235 Sep 25, 2023
53dc57e
fix style violations
Paul19988 Sep 25, 2023
2520dfd
fix climbables
Paul19988 Sep 25, 2023
f8a5594
fix support for skin layers not loading
Paul19988 Sep 26, 2023
0b12a2b
fix servers pinging servers
Paul19988 Sep 26, 2023
45f6167
fix client settings not forwarding between servers
Paul19988 Sep 26, 2023
1474c7e
change to a single value instead of a list
Paul19988 Sep 26, 2023
cb21a2c
disable auto reading during state switch
Gerrygames Sep 27, 2023
a097e34
ensure client settings packet is not null
Paul19988 Sep 27, 2023
c1c1b9b
remove cappedset
Paul19988 Sep 27, 2023
6b7afbc
bring back static imports
Paul19988 Sep 27, 2023
3572fb4
Merge pull request #1 from Gerrygames/dev/1.20.2
Paul19988 Sep 27, 2023
cd1d2dc
remove experimental
Paul19988 Sep 27, 2023
c24f4f6
Fix support for backend server resource packs & possibly fix plugin m…
Paul19988 Oct 3, 2023
fb94816
Code style changes
Paul19988 Oct 3, 2023
b789257
Allow serverbound config packets to pass through freely
Paul19988 Oct 3, 2023
1b07659
incorporate changes recommended by Wesley1808
Paul19988 Oct 3, 2023
c076f04
Support switch to config state by backend server
Gerrygames Oct 6, 2023
fadf839
Reapply resource pack after config state
Gerrygames Oct 7, 2023
f71bcfa
Add play packet queue after sending StartUpdate
Gerrygames Oct 7, 2023
3f6e69b
Make sure to decode packets with the correct state registry
Gerrygames Oct 7, 2023
3180764
Revert nearly all reformatting
bluegreensea Oct 10, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public enum ProtocolVersion {
MINECRAFT_1_19_1(760, "1.19.1", "1.19.2"),
MINECRAFT_1_19_3(761, "1.19.3"),
MINECRAFT_1_19_4(762, "1.19.4"),
MINECRAFT_1_20(763, "1.20", "1.20.1");
MINECRAFT_1_20(763, "1.20", "1.20.1"),
MINECRAFT_1_20_2(764, "1.20.2");

private static final int SNAPSHOT_BIT = 30;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface LoginPhaseConnection extends InboundConnection, KeyIdentifiable
* @param contents the message to send
* @param consumer the consumer that will respond to the message
*/
void sendLoginPluginMessage(ChannelIdentifier identifier, byte[] contents,
void sendLoginPluginMessage(int messageId, ChannelIdentifier identifier, byte[] contents,
Paul19988 marked this conversation as resolved.
Show resolved Hide resolved
MessageConsumer consumer);

/**
Expand Down
3 changes: 2 additions & 1 deletion proxy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ application {

tasks {
withType<Checkstyle> {
exclude("**/com/velocitypowered/proxy/protocol/packet/**")
exclude("**/com/velocitypowered/proxy/protocol/**")
exclude("**/com/velocitypowered/proxy/connection/**")
Paul19988 marked this conversation as resolved.
Show resolved Hide resolved
}

jar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
Expand All @@ -78,7 +81,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
private final Channel channel;
private SocketAddress remoteAddress;
private StateRegistry state;
private @Nullable MinecraftSessionHandler sessionHandler;
private Map<StateRegistry, MinecraftSessionHandler> sessionHandlers;
private @Nullable MinecraftSessionHandler activeSessionHandler;
private ProtocolVersion protocolVersion;
private @Nullable MinecraftConnectionAssociation association;
public final VelocityServer server;
Expand All @@ -96,12 +100,14 @@ public MinecraftConnection(Channel channel, VelocityServer server) {
this.remoteAddress = channel.remoteAddress();
this.server = server;
this.state = StateRegistry.HANDSHAKE;

this.sessionHandlers = new HashMap<>();
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
if (sessionHandler != null) {
sessionHandler.connected();
if (activeSessionHandler != null) {
activeSessionHandler.connected();
}

if (association != null && server.getConfiguration().isLogPlayerConnections()) {
Expand All @@ -111,26 +117,26 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception {

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (sessionHandler != null) {
sessionHandler.disconnected();
if (activeSessionHandler != null) {
activeSessionHandler.disconnected();
}

if (association != null && !knownDisconnect
&& !(sessionHandler instanceof StatusSessionHandler)
&& server.getConfiguration().isLogPlayerConnections()) {
&& !(activeSessionHandler instanceof StatusSessionHandler)
&& server.getConfiguration().isLogPlayerConnections()) {
logger.info("{} has disconnected", association);
}
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
if (sessionHandler == null) {
if (activeSessionHandler == null) {
// No session handler available, do nothing
return;
}

if (sessionHandler.beforeHandle()) {
if (activeSessionHandler.beforeHandle()) {
return;
}

Expand All @@ -140,15 +146,15 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

if (msg instanceof MinecraftPacket) {
MinecraftPacket pkt = (MinecraftPacket) msg;
if (!pkt.handle(sessionHandler)) {
sessionHandler.handleGeneric((MinecraftPacket) msg);
if (!pkt.handle(activeSessionHandler)) {
activeSessionHandler.handleGeneric((MinecraftPacket) msg);
}
} else if (msg instanceof HAProxyMessage) {
HAProxyMessage proxyMessage = (HAProxyMessage) msg;
this.remoteAddress = new InetSocketAddress(proxyMessage.sourceAddress(),
proxyMessage.sourcePort());
proxyMessage.sourcePort());
} else if (msg instanceof ByteBuf) {
sessionHandler.handleUnknown((ByteBuf) msg);
activeSessionHandler.handleUnknown((ByteBuf) msg);
}
} finally {
ReferenceCountUtil.release(msg);
Expand All @@ -157,34 +163,34 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
if (sessionHandler != null) {
sessionHandler.readCompleted();
if (activeSessionHandler != null) {
activeSessionHandler.readCompleted();
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (ctx.channel().isActive()) {
if (sessionHandler != null) {
if (activeSessionHandler != null) {
try {
sessionHandler.exception(cause);
activeSessionHandler.exception(cause);
} catch (Exception ex) {
logger.error("{}: exception handling exception in {}",
(association != null ? association : channel.remoteAddress()), sessionHandler, cause);
(association != null ? association : channel.remoteAddress()), activeSessionHandler, cause);
}
}

if (association != null) {
if (cause instanceof ReadTimeoutException) {
logger.error("{}: read timed out", association);
} else {
boolean frontlineHandler = sessionHandler instanceof InitialLoginSessionHandler
|| sessionHandler instanceof HandshakeSessionHandler
|| sessionHandler instanceof StatusSessionHandler;
boolean frontlineHandler = activeSessionHandler instanceof InitialLoginSessionHandler
|| activeSessionHandler instanceof HandshakeSessionHandler
|| activeSessionHandler instanceof StatusSessionHandler;
boolean isQuietDecoderException = cause instanceof QuietDecoderException;
boolean willLog = !isQuietDecoderException && !frontlineHandler;
if (willLog) {
logger.error("{}: exception encountered in {}", association, sessionHandler, cause);
logger.error("{}: exception encountered in {}", association, activeSessionHandler, cause);
} else {
knownDisconnect = true;
}
Expand All @@ -197,8 +203,8 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E

@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
if (sessionHandler != null) {
sessionHandler.writabilityChanged();
if (activeSessionHandler != null) {
activeSessionHandler.writabilityChanged();
}
}

Expand Down Expand Up @@ -253,7 +259,7 @@ public void flush() {
public void closeWith(Object msg) {
if (channel.isActive()) {
boolean is17 = this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) < 0
&& this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_2) >= 0;
&& this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_2) >= 0;
if (is17 && this.getState() != StateRegistry.STATUS) {
channel.eventLoop().execute(() -> {
// 1.7.x versions have a race condition with switching protocol states, so just explicitly
Expand Down Expand Up @@ -341,12 +347,8 @@ public void setAutoReading(boolean autoReading) {
}
}

/**
* Changes the state of the Minecraft connection.
*
* @param state the new state
*/
public void setState(StateRegistry state) {
// Ideally only used by the state switch
private void setState(StateRegistry state) {
ensureInEventLoop();

this.state = state;
Expand Down Expand Up @@ -382,25 +384,73 @@ public void setProtocolVersion(ProtocolVersion protocolVersion) {
}
}

public @Nullable MinecraftSessionHandler getSessionHandler() {
return sessionHandler;
public @Nullable MinecraftSessionHandler getActiveSessionHandler() {
return activeSessionHandler;
}

public @Nullable MinecraftSessionHandler getSessionHandlerForRegistry(StateRegistry registry) {
return this.sessionHandlers.getOrDefault(registry, null);
}

/**
* Sets the session handler for this connection.
*
* @param registry the registry of the handler
* @param sessionHandler the handler to use
*/
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
public void setActiveSessionHandler(StateRegistry registry, MinecraftSessionHandler sessionHandler) {
Preconditions.checkNotNull(registry);
ensureInEventLoop();

if (this.sessionHandler != null) {
this.sessionHandler.deactivated();
if (this.activeSessionHandler != null) {
this.activeSessionHandler.deactivated();
}
this.sessionHandler = sessionHandler;
this.sessionHandlers.put(registry, sessionHandler);
this.activeSessionHandler = sessionHandler;
setState(registry);
sessionHandler.activated();
}

/**
* Switches the active session handler to the respective registry one.
*
* @param registry the registry of the handler
* @return true if successful and handler is present
*/
public boolean setActiveSessionHandler(StateRegistry registry) {
Preconditions.checkNotNull(registry);
ensureInEventLoop();

MinecraftSessionHandler handler = getSessionHandlerForRegistry(registry);
if (handler != null) {
boolean flag = true;
if (this.activeSessionHandler != null
&& (flag = !Objects.equals(handler, this.activeSessionHandler))) {
this.activeSessionHandler.deactivated();
}
this.activeSessionHandler = handler;
setState(registry);
if (flag) {
handler.activated();
}
}
return handler != null;
}

/**
* Adds a secondary session handler for this connection.
*
* @param registry the registry of the handler
* @param sessionHandler the handler to use
*/
public void addSessionHandler(StateRegistry registry, MinecraftSessionHandler sessionHandler) {
Preconditions.checkNotNull(registry);
Preconditions.checkArgument(registry != state, "Handler would overwrite handler");
Paul19988 marked this conversation as resolved.
Show resolved Hide resolved
ensureInEventLoop();

this.sessionHandlers.put(registry, sessionHandler);
}

private void ensureOpen() {
Preconditions.checkState(!isClosed(), "Connection is closed.");
}
Expand All @@ -421,14 +471,14 @@ public void setCompressionThreshold(int threshold) {

if (removedDecoder != null && removedEncoder != null) {
channel.pipeline().addBefore(MINECRAFT_DECODER, FRAME_ENCODER,
MinecraftVarintLengthEncoder.INSTANCE);
MinecraftVarintLengthEncoder.INSTANCE);
channel.pipeline().fireUserEventTriggered(VelocityConnectionEvent.COMPRESSION_DISABLED);
}
} else {
MinecraftCompressDecoder decoder = (MinecraftCompressDecoder) channel.pipeline()
.get(COMPRESSION_DECODER);
.get(COMPRESSION_DECODER);
MinecraftCompressorAndLengthEncoder encoder =
(MinecraftCompressorAndLengthEncoder) channel.pipeline().get(COMPRESSION_ENCODER);
(MinecraftCompressorAndLengthEncoder) channel.pipeline().get(COMPRESSION_ENCODER);
if (decoder != null && encoder != null) {
decoder.setThreshold(threshold);
encoder.setThreshold(threshold);
Expand Down Expand Up @@ -464,9 +514,9 @@ public void enableEncryption(byte[] secret) throws GeneralSecurityException {
VelocityCipher decryptionCipher = factory.forDecryption(key);
VelocityCipher encryptionCipher = factory.forEncryption(key);
channel.pipeline()
.addBefore(FRAME_DECODER, CIPHER_DECODER, new MinecraftCipherDecoder(decryptionCipher));
.addBefore(FRAME_DECODER, CIPHER_DECODER, new MinecraftCipherDecoder(decryptionCipher));
channel.pipeline()
.addBefore(FRAME_ENCODER, CIPHER_ENCODER, new MinecraftCipherEncoder(encryptionCipher));
.addBefore(FRAME_ENCODER, CIPHER_ENCODER, new MinecraftCipherEncoder(encryptionCipher));

channel.pipeline().fireUserEventTriggered(VelocityConnectionEvent.ENCRYPTION_ENABLED);
}
Expand Down Expand Up @@ -498,4 +548,4 @@ public void setType(ConnectionType connectionType) {
this.connectionType = connectionType;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,15 @@
package com.velocitypowered.proxy.connection;

import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.AvailableCommands;
import com.velocitypowered.proxy.protocol.packet.BossBar;
import com.velocitypowered.proxy.protocol.packet.ClientSettings;
import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.EncryptionRequest;
import com.velocitypowered.proxy.protocol.packet.EncryptionResponse;
import com.velocitypowered.proxy.protocol.packet.Handshake;
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter;
import com.velocitypowered.proxy.protocol.packet.JoinGame;
import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.LegacyHandshake;
import com.velocitypowered.proxy.protocol.packet.LegacyPing;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn;
import com.velocitypowered.proxy.protocol.packet.ServerData;
import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import com.velocitypowered.proxy.protocol.packet.SetCompression;
import com.velocitypowered.proxy.protocol.packet.StatusPing;
import com.velocitypowered.proxy.protocol.packet.StatusRequest;
import com.velocitypowered.proxy.protocol.packet.StatusResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import com.velocitypowered.proxy.protocol.packet.*;
Paul19988 marked this conversation as resolved.
Show resolved Hide resolved
import com.velocitypowered.proxy.protocol.packet.chat.PlayerChatCompletion;
import com.velocitypowered.proxy.protocol.packet.chat.SystemChat;
import com.velocitypowered.proxy.protocol.packet.chat.keyed.KeyedPlayerChat;
import com.velocitypowered.proxy.protocol.packet.chat.keyed.KeyedPlayerCommand;
import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChat;
import com.velocitypowered.proxy.protocol.packet.chat.session.SessionPlayerChat;
import com.velocitypowered.proxy.protocol.packet.chat.session.SessionPlayerCommand;
import com.velocitypowered.proxy.protocol.packet.config.*;
Paul19988 marked this conversation as resolved.
Show resolved Hide resolved
import com.velocitypowered.proxy.protocol.packet.title.LegacyTitlePacket;
import com.velocitypowered.proxy.protocol.packet.title.TitleActionbarPacket;
import com.velocitypowered.proxy.protocol.packet.title.TitleClearPacket;
Expand Down Expand Up @@ -279,4 +251,32 @@ default boolean handle(RemovePlayerInfo packet) {
default boolean handle(UpsertPlayerInfo packet) {
return false;
}

default boolean handle(LoginAcknowledged packet) {
return false;
}

default boolean handle(ActiveFeatures packet) {
return false;
}

default boolean handle(FinishedUpdate packet) {
return false;
}

default boolean handle(RegistrySync packet) {
return false;
}

default boolean handle(TagsUpdate packet) {
return false;
}

default boolean handle(StartUpdate packet) {
return false;
}

default boolean handle(PingIdentify pingIdentify) {
return false;
}
}
Loading