Compare commits

...
7 Commits
17 changed files with 78 additions and 88 deletions

No files matched your search

@@ -34,6 +34,8 @@ import xyz.jonesdev.sonar.common.fallback.netty.FallbackVarInt21FrameDecoder;
import xyz.jonesdev.sonar.common.fallback.netty.FallbackVarIntLengthEncoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketDecoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketEncoder;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer;
import xyz.jonesdev.sonar.common.fallback.protocol.packets.play.DisconnectPacket;
import xyz.jonesdev.sonar.common.fallback.verification.FallbackPreJoinHandler;
import xyz.jonesdev.sonar.common.statistics.GlobalSonarStatistics;
@@ -42,9 +44,6 @@ import xyz.jonesdev.sonar.common.util.ProtocolUtil;
import java.net.InetAddress;
import static xyz.jonesdev.sonar.api.fallback.FallbackPipelines.*;
import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry.GAME;
import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacketRegistry.LOGIN;
import static xyz.jonesdev.sonar.common.fallback.protocol.FallbackPreparer.loginSuccess;
@Getter
@ToString(of = {"protocolVersion", "inetAddress", "geyser"})
@@ -112,15 +111,15 @@ public final class FallbackUserWrapper implements FallbackUser {
channel.pipeline().addLast(FALLBACK_PACKET_DECODER, newDecoder);
// We're sending the LoginSuccess packet now
newDecoder.updateRegistry(LOGIN);
newEncoder.updateRegistry(LOGIN);
newDecoder.updateRegistry(FallbackPacketRegistry.LOGIN);
newEncoder.updateRegistry(FallbackPacketRegistry.LOGIN);
// Send LoginSuccess packet to make the client think they are joining the server
write(loginSuccess);
write(FallbackPreparer.loginSuccess);
// pre-1.20.2 clients do not have the configuration stage
if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_20_2)) {
newDecoder.updateRegistry(GAME);
newEncoder.updateRegistry(GAME);
newDecoder.updateRegistry(FallbackPacketRegistry.GAME);
newEncoder.updateRegistry(FallbackPacketRegistry.GAME);
}
// Listen for all incoming packets by setting the packet listener
@@ -135,7 +134,7 @@ public final class FallbackUserWrapper implements FallbackUser {
@Override
public void disconnect(final @NotNull Component reason) {
final FallbackPacketEncoder encoder = channel.pipeline().get(FallbackPacketEncoder.class);
final boolean duringLogin = encoder != null && encoder.getPacketRegistry() == LOGIN;
ProtocolUtil.closeWith(channel, protocolVersion, DisconnectPacket.create(reason, duringLogin));
final boolean duringLogin = encoder != null && encoder.getPacketRegistry() == FallbackPacketRegistry.LOGIN;
ProtocolUtil.closeWith(channel, protocolVersion, new DisconnectPacket(reason, duringLogin));
}
}
@@ -31,7 +31,7 @@ public final class FallbackTailExceptionsHandler extends ChannelDuplexHandler {
// Additionally, this will also run after our custom decoder.
@Override
public void exceptionCaught(final @NotNull ChannelHandlerContext ctx,
final @NotNull Throwable cause) throws Exception {
final Throwable cause) throws Exception {
// Close the channel if we encounter any errors.
ctx.close();
}
@@ -39,20 +39,18 @@ public interface FallbackPacket {
void decode(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) throws Exception;
/**
* @param byteBuf ByteBuf
* @param protocolVersion Protocol version of the player
* @return The minimum allowed length of the decoded packet
*/
default int expectedMinLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
default int expectedMinLength(final ProtocolVersion protocolVersion) {
return -1;
}
/**
* @param byteBuf ByteBuf
* @param protocolVersion Protocol version of the player
* @return The maximum allowed length of the decoded packet
*/
default int expectedMaxLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
default int expectedMaxLength(final ProtocolVersion protocolVersion) {
return -1;
}
}
@@ -43,8 +43,7 @@ public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
}
@Override
public void channelRead(final @NotNull ChannelHandlerContext ctx,
final @NotNull Object msg) throws Exception {
public void channelRead(final @NotNull ChannelHandlerContext ctx, final Object msg) throws Exception {
if (msg instanceof ByteBuf) {
final ByteBuf byteBuf = (ByteBuf) msg;
@@ -71,7 +70,7 @@ public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
}
// Ensure that the packet isn't too large or too small
checkPacketSize(byteBuf, packet);
checkPacketSize(byteBuf.readableBytes(), packet);
try {
// Try to decode the packet for the given protocol version
@@ -99,15 +98,13 @@ public final class FallbackPacketDecoder extends ChannelInboundHandlerAdapter {
}
}
private void checkPacketSize(final @NotNull ByteBuf byteBuf,
final @NotNull FallbackPacket packet) throws Exception {
final int packetSize = byteBuf.readableBytes();
final int expectedMaxLen = packet.expectedMaxLength(byteBuf, protocolVersion);
private void checkPacketSize(final int packetSize, final @NotNull FallbackPacket packet) throws Exception {
final int expectedMaxLen = packet.expectedMaxLength(protocolVersion);
if (expectedMaxLen != -1 && packetSize > expectedMaxLen) {
throw ProtocolUtil.DEBUG ? new DecoderException("Packet too large: " + packetSize + " max: " + expectedMaxLen)
: QuietDecoderException.INSTANCE;
}
final int expectedMinLen = packet.expectedMinLength(byteBuf, protocolVersion);
final int expectedMinLen = packet.expectedMinLength(protocolVersion);
if (expectedMinLen != -1 && packetSize < expectedMinLen) {
throw ProtocolUtil.DEBUG ? new DecoderException("Packet too small: " + packetSize + " min: " + expectedMinLen)
: QuietDecoderException.INSTANCE;
@@ -96,7 +96,7 @@ public class FallbackPreparer {
public static final FallbackPacket SET_VEHICLE_PASSENGERS = new FallbackPacketSnapshot(
new SetPassengersPacket(VEHICLE_ENTITY_ID, PLAYER_ENTITY_ID));
public static FallbackPacket loginSuccess;
public FallbackPacket loginSuccess;
public FallbackPacket welcomeMessage;
public FallbackPacket enterCodeMessage;
public FallbackPacket incorrectCaptcha;
@@ -183,13 +183,13 @@ public class FallbackPreparer {
}
// Prepare disconnect packets during login
blacklisted = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getBlacklisted(), true));
alreadyVerifying = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getAlreadyVerifying(), true));
alreadyQueued = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getAlreadyQueued(), true));
protocolBlacklisted = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getProtocolBlacklisted(), true));
reconnectedTooFast = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getTooFastReconnect(), true));
invalidUsername = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getVerification().getInvalidUsername(), true));
tooManyOnlinePerIP = new FallbackPacketSnapshot(DisconnectPacket.create(Sonar.get().getConfig().getTooManyOnlinePerIp(), true));
blacklisted = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getBlacklisted(), true));
alreadyVerifying = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getAlreadyVerifying(), true));
alreadyQueued = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getAlreadyQueued(), true));
protocolBlacklisted = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getProtocolBlacklisted(), true));
reconnectedTooFast = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getTooFastReconnect(), true));
invalidUsername = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getVerification().getInvalidUsername(), true));
tooManyOnlinePerIP = new FallbackPacketSnapshot(new DisconnectPacket(Sonar.get().getConfig().getTooManyOnlinePerIp(), true));
// Prepare transfer packet
if (Sonar.get().getConfig().getGeneralConfig().getBoolean("verification.transfer.enabled")) {
@@ -32,7 +32,7 @@ public final class FinishConfigurationPacket implements FallbackPacket {
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMaxLength(final ProtocolVersion protocolVersion) {
// This packet is always empty; see https://wiki.vg/Protocol#Finish_Configuration
return 0;
}
@@ -33,7 +33,7 @@ public final class LoginAcknowledgedPacket implements FallbackPacket {
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMaxLength(final ProtocolVersion protocolVersion) {
// This packet is always empty; see https://wiki.vg/Protocol#Login_Acknowledged
return 0;
}
@@ -79,12 +79,12 @@ public final class ClientInformationPacket implements FallbackPacket {
}
@Override
public int expectedMinLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMinLength(final ProtocolVersion protocolVersion) {
return 2;
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMaxLength(final ProtocolVersion protocolVersion) {
return 0xff + 1; // 256 as a hard-limit
}
}
@@ -21,7 +21,6 @@ import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
@@ -29,24 +28,25 @@ import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.util.ComponentHolder;
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class DisconnectPacket implements FallbackPacket {
private @NotNull ComponentHolder componentHolder;
private boolean duringLogin;
public DisconnectPacket(final @NotNull Component component, final boolean duringLogin) {
this.componentHolder = new ComponentHolder(component);
this.duringLogin = duringLogin;
}
@Override
public void encode(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion) throws Exception {
componentHolder.write(byteBuf, duringLogin ? ProtocolVersion.MINECRAFT_1_20_2 : protocolVersion);
// Force json serialization during login phase
componentHolder.write(byteBuf, protocolVersion, duringLogin);
}
@Override
public void decode(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
throw new UnsupportedOperationException();
}
public static @NotNull DisconnectPacket create(final @NotNull Component component, final boolean duringLogin) {
return new DisconnectPacket(new ComponentHolder(component), duringLogin);
}
}
@@ -27,7 +27,6 @@ import net.kyori.adventure.nbt.ListBinaryTag;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.FallbackPacket;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionType;
import xyz.jonesdev.sonar.common.util.ProtocolUtil;
@@ -78,7 +77,7 @@ public final class JoinGamePacket implements FallbackPacket {
ProtocolUtil.writeStringArray(byteBuf, levelNames);
final CompoundBinaryTag codec = getCodec(protocolVersion);
final CompoundBinaryTag codec = ProtocolUtil.getCodec(protocolVersion);
if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_20_2)) {
ProtocolUtil.writeBinaryTag(byteBuf, protocolVersion, codec);
@@ -177,23 +176,4 @@ public final class JoinGamePacket implements FallbackPacket {
public void decode(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
throw new UnsupportedOperationException();
}
private static CompoundBinaryTag getCodec(final @NotNull ProtocolVersion protocolVersion) {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21)) {
return DimensionRegistry.CODEC_1_21;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_20)) {
return DimensionRegistry.CODEC_1_20;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19_4)) {
return DimensionRegistry.CODEC_1_19_4;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19_1)) {
return DimensionRegistry.CODEC_1_19_1;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19)) {
return DimensionRegistry.CODEC_1_19;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_18_2)) {
return DimensionRegistry.CODEC_1_18_2;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_16_2)) {
return DimensionRegistry.CODEC_1_16_2;
}
return DimensionRegistry.CODEC_1_16;
}
}
@@ -61,12 +61,12 @@ public final class PluginMessagePacket implements FallbackPacket {
}
@Override
public int expectedMinLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMinLength(final ProtocolVersion protocolVersion) {
return 4;
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMaxLength(final ProtocolVersion protocolVersion) {
return 0xFFF; // strict size limit
}
}
@@ -58,12 +58,12 @@ public final class SetPlayerPositionPacket implements FallbackPacket {
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion) {
public int expectedMaxLength(final @NotNull ProtocolVersion protocolVersion) {
return protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_8) ? 33 : 25;
}
@Override
public int expectedMinLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMinLength(final ProtocolVersion protocolVersion) {
return 25;
}
}
@@ -95,12 +95,12 @@ public final class SetPlayerPositionRotationPacket implements FallbackPacket {
}
@Override
public int expectedMaxLength(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion) {
public int expectedMaxLength(final @NotNull ProtocolVersion protocolVersion) {
return protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_8) ? 41 : 33;
}
@Override
public int expectedMinLength(final ByteBuf byteBuf, final ProtocolVersion protocolVersion) {
public int expectedMinLength(final ProtocolVersion protocolVersion) {
return 33;
}
}
@@ -18,7 +18,6 @@
package xyz.jonesdev.sonar.common.fallback.protocol.packets.play;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.DecoderException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -47,7 +46,7 @@ public final class SystemChatPacket implements FallbackPacket {
@Override
public void encode(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion) throws Exception {
// Serialized message
componentHolder.write(byteBuf, protocolVersion);
componentHolder.write(byteBuf, protocolVersion, false);
// Type
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19_1)) {
@@ -70,12 +69,7 @@ public final class SystemChatPacket implements FallbackPacket {
message = ProtocolUtil.readString(byteBuf, 256);
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19)) {
final long timestamp = byteBuf.readLong();
final long now = System.currentTimeMillis();
if (timestamp > now) {
throw ProtocolUtil.DEBUG ? new DecoderException("Message appears to be from the future: "
+ "(expected >" + now + ", got " + timestamp + ")") : QuietDecoderException.INSTANCE;
}
byteBuf.readLong(); // timestamp
if (protocolVersion.lessThanOrEquals(ProtocolVersion.MINECRAFT_1_19_1)) {
final long saltLong = byteBuf.readLong();
@@ -32,11 +32,14 @@ import java.util.Map;
import java.util.Objects;
public final class ComponentHolder {
private final String serializedComponent;
private BinaryTag cachedBinaryTag;
private final String modernJson;
private final String legacyJson;
private final BinaryTag binaryTag;
public ComponentHolder(final @NotNull Component component) {
this.serializedComponent = GsonComponentSerializer.gson().serialize(component);
this.modernJson = GsonComponentSerializer.gson().serialize(component);
this.legacyJson = GsonComponentSerializer.colorDownsamplingGson().serialize(component);
this.binaryTag = serialize(new JsonParser().parse(this.modernJson));
}
// https://github.com/PaperMC/Velocity/blob/dev/3.0.0/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/ComponentHolder.java
@@ -137,14 +140,12 @@ public final class ComponentHolder {
return EndBinaryTag.endBinaryTag();
}
public void write(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion) {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_20_3)) {
if (cachedBinaryTag == null) {
cachedBinaryTag = serialize(new JsonParser().parse(serializedComponent));
}
ProtocolUtil.writeBinaryTag(byteBuf, protocolVersion, cachedBinaryTag);
public void write(final ByteBuf byteBuf, final @NotNull ProtocolVersion protocolVersion, final boolean forceJson) {
if (!forceJson && protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_20_3)) {
ProtocolUtil.writeBinaryTag(byteBuf, protocolVersion, binaryTag);
} else {
ProtocolUtil.writeString(byteBuf, serializedComponent);
ProtocolUtil.writeString(byteBuf,
protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_16) ? modernJson : legacyJson);
}
}
}
@@ -49,8 +49,10 @@ import io.netty.util.Version;
import lombok.experimental.UtilityClass;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagType;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import org.jetbrains.annotations.NotNull;
import xyz.jonesdev.sonar.api.fallback.protocol.ProtocolVersion;
import xyz.jonesdev.sonar.common.fallback.protocol.dimension.DimensionRegistry;
import xyz.jonesdev.sonar.common.util.exception.QuietDecoderException;
import java.io.IOException;
@@ -318,6 +320,25 @@ public class ProtocolUtil {
return ((high & 0xFF) << 15) | low;
}
public static CompoundBinaryTag getCodec(final @NotNull ProtocolVersion protocolVersion) {
if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_21)) {
return DimensionRegistry.CODEC_1_21;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_20)) {
return DimensionRegistry.CODEC_1_20;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19_4)) {
return DimensionRegistry.CODEC_1_19_4;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19_1)) {
return DimensionRegistry.CODEC_1_19_1;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_19)) {
return DimensionRegistry.CODEC_1_19;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_18_2)) {
return DimensionRegistry.CODEC_1_18_2;
} else if (protocolVersion.greaterThanOrEquals(ProtocolVersion.MINECRAFT_1_16_2)) {
return DimensionRegistry.CODEC_1_16_2;
}
return DimensionRegistry.CODEC_1_16;
}
private void checkState(final boolean expression, final String message) {
if (!expression) {
throw DEBUG ? new DecoderException(message) : QuietDecoderException.INSTANCE;
+1 -1
View File
@@ -1,3 +1,3 @@
group=xyz.jonesdev
version=2.1.11
version=2.1.13
description=A lightweight, effective, and easy-to-use anti-bot plugin for Velocity, BungeeCord, and Bukkit.