Skip to content

Commit

Permalink
Support Velocity forward protocol v3
Browse files Browse the repository at this point in the history
  • Loading branch information
james58899 committed Jul 28, 2022
1 parent c4b985e commit 1a0fbd6
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
13 changes: 11 additions & 2 deletions src/main/java/one/oktw/PacketHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerLoginNetworkHandler;
import net.minecraft.text.Text;
import one.oktw.mixin.IServerLoginNetworkHandler_RealUUID;
import one.oktw.mixin.core.ClientConnection_AddressAccessor;
import one.oktw.mixin.core.ServerLoginNetworkHandler_ProfileAccessor;
import org.apache.logging.log4j.LogManager;

import java.util.Optional;
import java.util.UUID;

class PacketHandler {
private final ModConfig config;
Expand Down Expand Up @@ -56,8 +58,14 @@ void handleVelocityPacket(MinecraftServer server, ServerLoginNetworkHandler hand
// Public key
boolean keyEnforce = server.shouldEnforceSecureProfile();
Optional<PlayerPublicKey.PublicKeyData> publicKey = Optional.empty();
Optional<UUID> profileId = Optional.empty();
try {
if (forwardVersion >= VelocityLib.MODERN_FORWARDING_WITH_KEY) publicKey = VelocityLib.readKey(buf);
// Ignore v1 KEY, it not work on 1.19.1+
if (forwardVersion >= VelocityLib.MODERN_FORWARDING_WITH_KEY_V2) {
publicKey = VelocityLib.readKey(buf);
profileId = VelocityLib.readUuid(buf);
}

if (keyEnforce && publicKey.isEmpty()) {
handler.disconnect(Text.translatable("multiplayer.disconnect.missing_public_key"));
return;
Expand All @@ -71,11 +79,12 @@ void handleVelocityPacket(MinecraftServer server, ServerLoginNetworkHandler hand
}

if (config.getHackEarlySend()) {
handler.onHello(new LoginHelloC2SPacket(profile.getName(), publicKey, Optional.of(profile.getId())));
handler.onHello(new LoginHelloC2SPacket(profile.getName(), publicKey, profileId.or(() ->Optional.of(profile.getId()))));
}

((ServerLoginNetworkHandler_ProfileAccessor) handler).setProfile(profile);
publicKey.ifPresent(((ServerLoginNetworkHandler_ProfileAccessor) handler)::setPublicKeyData);
profileId.ifPresent(((IServerLoginNetworkHandler_RealUUID) handler)::setRealUUID);
}));
}
}
16 changes: 14 additions & 2 deletions src/main/java/one/oktw/VelocityLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
import java.time.Instant;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;

import static java.util.Arrays.binarySearch;
import static net.minecraft.network.encryption.NetworkEncryptionUtils.decodeEncodedRsaPublicKey;

public class VelocityLib {
public static final Identifier PLAYER_INFO_CHANNEL = new Identifier("velocity", "player_info");
public static final PacketByteBuf PLAYER_INFO_PACKET = new PacketByteBuf(Unpooled.wrappedBuffer(new byte[]{(byte) VelocityLib.MODERN_FORWARDING_WITH_KEY}).asReadOnly());
public static final PacketByteBuf PLAYER_INFO_PACKET = new PacketByteBuf(Unpooled.wrappedBuffer(new byte[]{(byte) VelocityLib.MODERN_FORWARDING_WITH_KEY_V2}).asReadOnly());

public static final int MODERN_FORWARDING_DEFAULT = 1;
public static final int MODERN_FORWARDING_WITH_KEY = 2;
private static final int[] SUPPORTED_FORWARDING_VERSION = {MODERN_FORWARDING_DEFAULT, MODERN_FORWARDING_WITH_KEY};
public static final int MODERN_FORWARDING_WITH_KEY_V2 = 3;
private static final int[] SUPPORTED_FORWARDING_VERSION = {MODERN_FORWARDING_DEFAULT, MODERN_FORWARDING_WITH_KEY, MODERN_FORWARDING_WITH_KEY_V2};

public static boolean checkIntegrity(final PacketByteBuf buf) {
final byte[] signature = new byte[32];
Expand Down Expand Up @@ -80,6 +82,16 @@ public static Optional<PlayerPublicKey.PublicKeyData> readKey(final PacketByteBu
return Optional.of(new PlayerPublicKey.PublicKeyData(expiry, key, signature));
}

public static Optional<UUID> readUuid(final PacketByteBuf buf) {
try {
if (buf.readBoolean()) {
return Optional.of(buf.readUuid());
}
} catch (IndexOutOfBoundsException ignored) {
}
return Optional.empty();
}

private static void readProperties(final PacketByteBuf buf, final GameProfile profile) {
final int properties = buf.readVarInt();
for (int i1 = 0; i1 < properties; i1++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package one.oktw.mixin;

import java.util.UUID;

public interface IServerLoginNetworkHandler_RealUUID {
void setRealUUID(UUID uuid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package one.oktw.mixin.core;

import com.mojang.authlib.GameProfile;
import net.minecraft.server.network.ServerLoginNetworkHandler;
import one.oktw.mixin.IServerLoginNetworkHandler_RealUUID;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import java.util.UUID;

@Mixin(ServerLoginNetworkHandler.class)
public abstract class ServerLoginNetworkHandler_KeyCheck implements IServerLoginNetworkHandler_RealUUID {
private UUID realUUID = null;

@Redirect(method = "acceptPlayer", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/GameProfile;getId()Ljava/util/UUID;", remap = false))
private UUID overrideUuid(GameProfile instance) {
return realUUID != null ? realUUID : instance.getId();
}

@Override
public void setRealUUID(UUID uuid) {
realUUID = uuid;
}
}
1 change: 1 addition & 0 deletions src/main/resources/core.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"ClientConnection_AddressAccessor",
"ServerLoginNetworkHandler_KeyCheck",
"ServerLoginNetworkHandler_ProfileAccessor"
],
"injectors": {
Expand Down

0 comments on commit 1a0fbd6

Please sign in to comment.