diff --git a/src/main/java/de/florianmichael/viafabricplus/definition/v1_19_0/storage/ChatSession1_19_0.java b/src/main/java/de/florianmichael/viafabricplus/definition/v1_19_0/storage/ChatSession1_19_0.java index 7291983c..7e41ce20 100644 --- a/src/main/java/de/florianmichael/viafabricplus/definition/v1_19_0/storage/ChatSession1_19_0.java +++ b/src/main/java/de/florianmichael/viafabricplus/definition/v1_19_0/storage/ChatSession1_19_0.java @@ -34,11 +34,8 @@ import java.util.UUID; public class ChatSession1_19_0 extends AbstractChatSession { - private final byte[] legacyKey; - - public ChatSession1_19_0(UserConnection user, ProfileKey profileKey, PrivateKey privateKey, byte[] legacyKey) { + public ChatSession1_19_0(UserConnection user, ProfileKey profileKey, PrivateKey privateKey) { super(user, profileKey, privateKey); - this.legacyKey = legacyKey; } public byte[] sign(final UUID sender, final MessageMetadataModel messageMetadata) { @@ -54,8 +51,4 @@ public class ChatSession1_19_0 extends AbstractChatSession { updater.update(JsonHelper.toSortedString(TextComponentSerializer.V1_18.serializeJson(new StringComponent(messageMetadata.plain()))).getBytes(StandardCharsets.UTF_8)); }); } - - public byte[] getLegacyKey() { - return legacyKey; - } } diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinConnectScreen_1.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinConnectScreen_1.java index 66691a8d..eeddc3db 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinConnectScreen_1.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinConnectScreen_1.java @@ -97,7 +97,6 @@ public class MixinConnectScreen_1 { final UserConnection userConnection = connection.channel.attr(ProtocolHack.LOCAL_VIA_CONNECTION).get(); if (userConnection == null) { - ViaFabricPlus.LOGGER.warn("ViaVersion userConnection is null"); return; } final ComparableProtocolVersion targetVersion = ProtocolHack.getTargetVersion(connection.channel); @@ -120,14 +119,13 @@ public class MixinConnectScreen_1 { final PlayerKeyPair playerKeyPair = MinecraftClient.getInstance().getProfileKeys().fetchKeyPair().get().orElse(null); if (playerKeyPair != null) { final PlayerPublicKey.PublicKeyData publicKeyData = playerKeyPair.publicKey().data(); - final ProfileKey profileKey = new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), publicKeyData.keySignature()); - userConnection.put(new ChatSession1_19_2(userConnection, profileKey, playerKeyPair.privateKey())); + userConnection.put(new ChatSession1_19_2(userConnection, new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), publicKeyData.keySignature()), playerKeyPair.privateKey())); if (targetVersion.isEqualTo(ProtocolVersion.v1_19)) { final byte[] legacyKey = ((IPublicKeyData) (Object) publicKeyData).viafabricplus_getV1Key().array(); if (legacyKey != null) { - userConnection.put(new ChatSession1_19_0(userConnection, profileKey, playerKeyPair.privateKey(), legacyKey)); + userConnection.put(new ChatSession1_19_0(userConnection, new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), legacyKey), playerKeyPair.privateKey())); } else { ViaFabricPlus.LOGGER.warn("Mojang removed the legacy key"); } diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_1to1_19/MixinProtocol1_19_1To1_19.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_1to1_19/MixinProtocol1_19_1To1_19.java index 5a7193c9..6735e0be 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_1to1_19/MixinProtocol1_19_1To1_19.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_1to1_19/MixinProtocol1_19_1To1_19.java @@ -49,22 +49,14 @@ public class MixinProtocol1_19_1To1_19 extends AbstractProtocol { final ChatSession1_19_0 chatSession1190 = wrapper.user().get(ChatSession1_19_0.class); - if (chatSession1190 != null) { - final ProfileKey profileKey = wrapper.get(Type.OPTIONAL_PROFILE_KEY, 0); - if (profileKey != null) { - wrapper.set(Type.OPTIONAL_PROFILE_KEY, 0, new ProfileKey( - profileKey.expiresAt(), - profileKey.publicKey(), - chatSession1190.getLegacyKey() - )); - } - } + + wrapper.write(Type.OPTIONAL_PROFILE_KEY, chatSession1190 == null ? null : chatSession1190.getProfileKey()); }); - this.read(Type.OPTIONAL_UUID); + read(Type.OPTIONAL_UUID); } }, true); this.registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), new PacketHandlers() { @@ -90,18 +82,7 @@ public class MixinProtocol1_19_1To1_19 extends AbstractProtocol argument : commandArgumentsProvider.getSignedArguments(command)) { - final byte[] signature = chatSession1190.sign( - sender, - new MessageMetadataModel( - argument.value(), - timestamp, - salt - ) - ); + for (Pair argument : commandArgumentsProvider.getSignedArguments(command)) { + final byte[] signature = chatSession1190.sign(sender, new MessageMetadataModel(argument.value(), timestamp, salt)); - - wrapper.write(Type.STRING, argument.key()); - wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); - } - } + wrapper.write(Type.STRING, argument.key()); + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); } } } diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_3to1_19_1/MixinProtocol1_19_3To1_19_1.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_3to1_19_1/MixinProtocol1_19_3To1_19_1.java index 269c39d4..83d0cf51 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_3to1_19_1/MixinProtocol1_19_3To1_19_1.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/protocol1_19_3to1_19_1/MixinProtocol1_19_3To1_19_1.java @@ -20,17 +20,12 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.viaversion.protoco import com.google.common.primitives.Longs; import com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.storage.NonceStorage; import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.minecraft.PlayerMessageSignature; import com.viaversion.viaversion.api.protocol.AbstractProtocol; -import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.State; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.BitSetType; import com.viaversion.viaversion.api.type.types.ByteArrayType; -import com.viaversion.viaversion.libs.gson.JsonElement; -import com.viaversion.viaversion.libs.kyori.adventure.text.Component; -import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.ClientboundPackets1_19_1; @@ -63,9 +58,6 @@ public class MixinProtocol1_19_3To1_19_1 extends AbstractProtocol { - final UUID uuid = wrapper.read(Type.OPTIONAL_UUID); - final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); - wrapper.write(Type.OPTIONAL_PROFILE_KEY, chatSession1192 != null ? chatSession1192.getProfileKey() : null); - - wrapper.write(Type.OPTIONAL_UUID, uuid); + wrapper.write(Type.OPTIONAL_PROFILE_KEY, chatSession1192 != null ? chatSession1192.getProfileKey() : null); // Profile Key }); + map(Type.OPTIONAL_UUID); // UUID } }, true); + this.registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY.getId(), ServerboundLoginPackets.ENCRYPTION_KEY.getId(), new PacketHandlers() { @Override public void register() { map(Type.BYTE_ARRAY_PRIMITIVE); // Keys - create(Type.BOOLEAN, true); // Is nonce - // Removing new nonce if chat session is connected handler(wrapper -> { final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); + final byte[] encryptedNonce = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); + + wrapper.write(Type.BOOLEAN, chatSession1192 == null); if (chatSession1192 != null) { - wrapper.read(Type.BYTE_ARRAY_PRIMITIVE); // Encrypted Nonce + final long salt = ChatSession1_19_2.SECURE_RANDOM.nextLong(); + final byte[] signedNonce = chatSession1192.getSigner().sign(updater -> { + updater.update(wrapper.user().get(NonceStorage.class).nonce()); + updater.update(Longs.toByteArray(salt)); + }); + + wrapper.write(Type.LONG, salt); + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signedNonce); + } else { + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, encryptedNonce); } }); - - // Writing original packet data if chat session is connected - handler(wrapper -> { - final NonceStorage nonceStorage = wrapper.user().get(NonceStorage.class); - if (nonceStorage != null) { - final byte[] nonce = nonceStorage.nonce(); - if (nonce == null) { - throw new IllegalStateException("Didn't tracked the packet nonce???"); - } - final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); - if (chatSession1192 != null) { - wrapper.set(Type.BOOLEAN, 0, false); // Now it's a nonce - final long salt = ChatSession1_19_2.SECURE_RANDOM.nextLong(); - final byte[] signedNonce = chatSession1192.getSigner().sign(updater -> { - if (updater != null) { - updater.update(nonce); - updater.update(Longs.toByteArray(salt)); - } - }); - - wrapper.write(Type.LONG, salt); - wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signedNonce); - } - } - }); - } - }, true); - - this.registerClientbound(ClientboundPackets1_19_1.PLAYER_CHAT, ClientboundPackets1_19_3.DISGUISED_CHAT, new PacketHandlers() { - @Override - public void register() { - read(Type.OPTIONAL_BYTE_ARRAY_PRIMITIVE); // Previous signature - handler(wrapper -> { - final PlayerMessageSignature signature = wrapper.read(Type.PLAYER_MESSAGE_SIGNATURE); - - // Store message signature for last seen - if (!signature.uuid().equals(ZERO_UUID) && signature.signatureBytes().length != 0) { - final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - if (messagesStorage != null) { - messagesStorage.add(signature); - if (messagesStorage.tickUnacknowledged() > 64) { - messagesStorage.resetUnacknowledgedCount(); - - // Send chat acknowledgement - final PacketWrapper chatAckPacket = wrapper.create(ServerboundPackets1_19_1.CHAT_ACK); - chatAckPacket.write(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY, messagesStorage.lastSignatures()); - wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); - - chatAckPacket.sendToServer(Protocol1_19_3To1_19_1.class); - } - } - } - - final String plainMessage = wrapper.read(Type.STRING); - JsonElement decoratedMessage = wrapper.read(Type.OPTIONAL_COMPONENT); - - wrapper.read(Type.LONG); // Timestamp - wrapper.read(Type.LONG); // Salt - wrapper.read(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY); // Last seen - - final JsonElement unsignedMessage = wrapper.read(Type.OPTIONAL_COMPONENT); - if (unsignedMessage != null) { - decoratedMessage = unsignedMessage; - } - if (decoratedMessage == null) { - decoratedMessage = GsonComponentSerializer.gson().serializeToTree(Component.text(plainMessage)); - } - - final int filterMaskType = wrapper.read(Type.VAR_INT); - if (filterMaskType == 2) { // Partially filtered - wrapper.read(Type.LONG_ARRAY_PRIMITIVE); // Mask - } - - wrapper.write(Type.COMPONENT, decoratedMessage); - // Keep chat type at the end - }); } }, true); @@ -190,87 +114,53 @@ public class MixinProtocol1_19_3To1_19_1 extends AbstractProtocol { final int signatures = wrapper.get(Type.VAR_INT, 0); final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); - if (chatSession1192 != null) { - final CommandArgumentsProvider commandArgumentsProvider = Via.getManager().getProviders().get(CommandArgumentsProvider.class); - if (commandArgumentsProvider != null) { - for (int i = 0; i < signatures; i++) { - wrapper.read(Type.STRING); // Argument name - wrapper.read(MESSAGE_SIGNATURE_BYTES_TYPE); // Signature - } - return; - } - } + final CommandArgumentsProvider commandArgumentsProvider = Via.getManager().getProviders().get(CommandArgumentsProvider.class); + + final boolean signingEnabled = chatSession1192 != null && commandArgumentsProvider != null; for (int i = 0; i < signatures; i++) { - wrapper.passthrough(Type.STRING); // Argument name + if (signingEnabled) { + wrapper.read(Type.STRING); // Argument name + wrapper.read(MESSAGE_SIGNATURE_BYTES_TYPE); // Signature + } else { + wrapper.passthrough(Type.STRING); // Argument name - // Signature - wrapper.read(MESSAGE_SIGNATURE_BYTES_TYPE); - wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, new byte[0]); + // Signature + wrapper.read(MESSAGE_SIGNATURE_BYTES_TYPE); + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, new byte[0]); + } } - }); - // Removing new acknowledgement - handler(wrapper -> { - wrapper.read(Type.VAR_INT); // Offset - wrapper.read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged - }); - - // Signing all arguments - handler(wrapper -> { - final UUID sender = wrapper.user().getProtocolInfo().getUuid(); - final String command = wrapper.get(Type.STRING, 0); - final long timestamp = wrapper.get(Type.LONG, 0); - final long salt = wrapper.get(Type.LONG, 1); - - final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); if (chatSession1192 != null) { - if (sender == null) { - throw new IllegalStateException("ViaVersion didn't track the connected UUID correctly, please check your BaseProtocol1_7"); - } - final CommandArgumentsProvider commandArgumentsProvider = Via.getManager().getProviders().get(CommandArgumentsProvider.class); - if (commandArgumentsProvider != null) { - // Signing arguments - { - final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - if (messagesStorage != null) { - for (Pair argument : commandArgumentsProvider.getSignedArguments(command)) { - final byte[] signature = chatSession1192.sign( - sender, - new MessageMetadataModel( - argument.value(), - timestamp, - salt - ), - messagesStorage.lastSignatures() - ); + final UUID sender = wrapper.user().getProtocolInfo().getUuid(); + final String command = wrapper.get(Type.STRING, 0); + final long timestamp = wrapper.get(Type.LONG, 0); + final long salt = wrapper.get(Type.LONG, 1); + final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - wrapper.write(Type.STRING, argument.key()); - wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); - } - } - } + for (Pair argument : commandArgumentsProvider.getSignedArguments(command)) { + final byte[] signature = chatSession1192.sign(sender, new MessageMetadataModel(argument.value(), timestamp, salt), messagesStorage.lastSignatures()); + + wrapper.write(Type.STRING, argument.key()); + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); } } + wrapper.write(Type.BOOLEAN, false); // No signed preview + + final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); + messagesStorage.resetUnacknowledgedCount(); + wrapper.write(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY, messagesStorage.lastSignatures()); + wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); }); - // Adding old acknowledgement - handler(wrapper -> { - final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - if (messagesStorage != null) { - messagesStorage.resetUnacknowledgedCount(); - wrapper.write(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY, messagesStorage.lastSignatures()); - wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); - } - }); + read(Type.VAR_INT); // Offset + read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged } }, true); registerServerbound(ServerboundPackets1_19_3.CHAT_MESSAGE, ServerboundPackets1_19_1.CHAT_MESSAGE, new PacketHandlers() { @@ -279,61 +169,33 @@ public class MixinProtocol1_19_3To1_19_1 extends AbstractProtocol { - wrapper.read(OPTIONAL_MESSAGE_SIGNATURE_BYTES_TYPE); // Signature - final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); - if (chatSession1192 == null) { + final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); + + if (chatSession1192 != null) { + final UUID sender = wrapper.user().getProtocolInfo().getUuid(); + final String message = wrapper.get(Type.STRING, 0); + final long timestamp = wrapper.get(Type.LONG, 0); + final long salt = wrapper.get(Type.LONG, 1); + + final byte[] signature = chatSession1192.sign(sender, new MessageMetadataModel(message, +timestamp, salt), messagesStorage.lastSignatures()); + + wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); + wrapper.write(Type.BOOLEAN, false); // Signed Preview - not implemented yet, but I could do it + } else { wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, new byte[0]); // Signature wrapper.write(Type.BOOLEAN, false); // No signed preview } + + messagesStorage.resetUnacknowledgedCount(); + wrapper.write(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY, messagesStorage.lastSignatures()); + wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); }); - // Emulate old Message chain - handler(wrapper -> { - final UUID sender = wrapper.user().getProtocolInfo().getUuid(); - final String message = wrapper.get(Type.STRING, 0); - final long timestamp = wrapper.get(Type.LONG, 0); - final long salt = wrapper.get(Type.LONG, 1); - - final ChatSession1_19_2 chatSession1192 = wrapper.user().get(ChatSession1_19_2.class); - if (chatSession1192 != null) { - if (sender == null) { - throw new IllegalStateException("ViaVersion didn't track the connected UUID correctly, please check your BaseProtocol1_7"); - } - final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - if (messagesStorage != null) { - final byte[] signature = chatSession1192.sign( - sender, - new MessageMetadataModel( - message, - timestamp, - salt - ), - messagesStorage.lastSignatures() - ); - - wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, signature); - wrapper.write(Type.BOOLEAN, false); // Signed Preview - not implemented yet, but I could do it - } - } - }); - - // Removing new acknowledgement - handler(wrapper -> { - wrapper.read(Type.VAR_INT); // Offset - wrapper.read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged - }); - - // Adding old acknowledgement - handler(wrapper -> { - final ReceivedMessagesStorage messagesStorage = wrapper.user().get(ReceivedMessagesStorage.class); - if (messagesStorage != null) { - messagesStorage.resetUnacknowledgedCount(); - wrapper.write(Type.PLAYER_MESSAGE_SIGNATURE_ARRAY, messagesStorage.lastSignatures()); - wrapper.write(Type.OPTIONAL_PLAYER_MESSAGE_SIGNATURE, null); - } - }); + read(Type.VAR_INT); // Offset + read(ACKNOWLEDGED_BIT_SET_TYPE); // Acknowledged } }, true); }