implemented more providers, make legacy login possible

This commit is contained in:
FlorianMichael 2023-02-23 20:03:41 +01:00
parent b1b4453d35
commit 20d53342a6
17 changed files with 219 additions and 31 deletions

View File

@ -8,10 +8,10 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemPr
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import de.florianmichael.viafabricplus.definition.ItemReleaseVersionDefinition;
import de.florianmichael.viafabricplus.definition.PackFormatsDefinition;
import de.florianmichael.viafabricplus.definition.v1_19_0.provider.CommandArgumentsProvider;
import de.florianmichael.viafabricplus.platform.ViaAprilFoolsPlatformImpl;
import de.florianmichael.viafabricplus.platform.ViaLegacyPlatformImpl;
import de.florianmichael.viafabricplus.provider.ViaFabricPlusHandItemProvider;
import de.florianmichael.viafabricplus.provider.ViaFabricPlusMovementTransmitterProvider;
import de.florianmichael.viafabricplus.provider.*;
import de.florianmichael.viafabricplus.value.ValueHolder;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import de.florianmichael.vialoadingbase.api.SubPlatform;
@ -23,35 +23,47 @@ import net.fabricmc.loader.api.metadata.Person;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.minecraft.item.Item;
import net.minecraft.network.ClientConnection;
import net.minecraft.registry.Registries;
import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider;
import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ViaFabricPlus {
public final static File RUN_DIRECTORY = new File("ViaFabricPlus");
public final static AttributeKey<UserConnection> LOCAL_USER_CONNECTION = AttributeKey.newInstance("viafabricplus-via-connection");
public final static AttributeKey<UserConnection> LOCAL_VIA_CONNECTION = AttributeKey.newInstance("viafabricplus-via-connection");
public final static AttributeKey<ClientConnection> LOCAL_MINECRAFT_CONNECTION = AttributeKey.newInstance("viafabricplus-minecraft-connection");
private final static ViaFabricPlus self = new ViaFabricPlus();
private final SubPlatform SUB_PLATFORM_VIA_LEGACY = new SubPlatform("ViaLegacy", () -> true, ViaLegacyPlatformImpl::new, protocolVersions -> protocolVersions.addAll(LegacyProtocolVersion.PROTOCOLS));
private final SubPlatform SUB_PLATFORM_VIA_APRIL_FOOLS = new SubPlatform("ViaAprilFools", () -> true, ViaAprilFoolsPlatformImpl::new, this::invokeAprilFoolsProtocols);
private final SubPlatform SUB_PLATFORM_VIA_LEGACY = new SubPlatform("ViaLegacy", () -> true, ViaLegacyPlatformImpl::new, protocolVersions -> {
final List<ProtocolVersion> legacyProtocols = new ArrayList<>(LegacyProtocolVersion.PROTOCOLS);
Collections.reverse(legacyProtocols);
legacyProtocols.remove(LegacyProtocolVersion.c0_30cpe);
final int c0_28toc0_30Index = legacyProtocols.indexOf(LegacyProtocolVersion.c0_28toc0_30);
legacyProtocols.set(c0_28toc0_30Index - 1, LegacyProtocolVersion.c0_30cpe);
protocolVersions.addAll(legacyProtocols);
});
private final SubPlatform SUB_PLATFORM_VIA_APRIL_FOOLS = new SubPlatform("ViaAprilFools", () -> true, ViaAprilFoolsPlatformImpl::new, protocolVersions -> {
final int v1_14Index = protocolVersions.indexOf(ProtocolVersion.v1_14);
final int v1_16Index = protocolVersions.indexOf(ProtocolVersion.v1_16);
final int v1_16_2Index = protocolVersions.indexOf(ProtocolVersion.v1_16_2);
protocolVersions.add(v1_14Index - 1,AprilFoolsProtocolVersion.s3d_shareware);
protocolVersions.add(v1_16Index - 1, AprilFoolsProtocolVersion.s20w14infinite);
protocolVersions.add(v1_16_2Index - 1, AprilFoolsProtocolVersion.sCombatTest8c);
});
private final List<Item> availableItemsInTargetVersion = new ArrayList<>();
protected void invokeAprilFoolsProtocols(List<ProtocolVersion> origin) {
final int v1_14Index = origin.indexOf(ProtocolVersion.v1_14);
final int v1_16Index = origin.indexOf(ProtocolVersion.v1_16);
final int v1_16_2Index = origin.indexOf(ProtocolVersion.v1_16_2);
origin.add(v1_14Index - 1,AprilFoolsProtocolVersion.s3d_shareware);
origin.add(v1_16Index - 1, AprilFoolsProtocolVersion.s20w14infinite);
origin.add(v1_16_2Index - 1, AprilFoolsProtocolVersion.sCombatTest8c);
}
public void preLoad() {
ViaLoadingBase.ViaLoadingBaseBuilder builder = ViaLoadingBase.ViaLoadingBaseBuilder.create();
@ -94,6 +106,13 @@ public class ViaFabricPlus {
builder = builder.viaProviderCreator(providers -> {
providers.use(MovementTransmitterProvider.class, new ViaFabricPlusMovementTransmitterProvider());
providers.use(HandItemProvider.class, new ViaFabricPlusHandItemProvider());
providers.use(CommandArgumentsProvider.class, new ViaFabricPlusCommandArgumentsProvider());
providers.use(OldAuthProvider.class, new ViaFabricPlusOldAuthProvider());
providers.use(ClassicWorldHeightProvider.class, new ViaFabricPlusClassicWorldHeightProvider());
providers.use(EncryptionProvider.class, new ViaFabricPlusEncryptionProvider());
providers.use(GameProfileFetcher.class, new ViaFabricPlusGameProfileFetcher());
});
builder = builder.protocolReloader(protocolVersion -> {
availableItemsInTargetVersion.clear();

View File

@ -1,7 +1,7 @@
package de.florianmichael.viafabricplus.definition.v1_19_0.provider;
import com.viaversion.viaversion.api.platform.providers.Provider;
import net.minecraft.util.Pair;
import com.viaversion.viaversion.util.Pair;
import java.util.List;

View File

@ -47,7 +47,7 @@ public class MixinClientConnection implements IClientConnection {
@Override
public void viafabricplus_setupPreNettyEncryption() {
this.encrypted = true;
this.channel.pipeline().addBefore(PreNettyConstants.DECODER, "decrypt", new PacketDecryptor(this.viafabricplus_decryptionCipher));
this.channel.pipeline().addBefore(PreNettyConstants.ENCODER, "encrypt", new PacketEncryptor(this.viafabricplus_encryptionCipher));
this.channel.pipeline().addBefore(PreNettyConstants.HANDLER_DECODER_NAME, "decrypt", new PacketDecryptor(this.viafabricplus_decryptionCipher));
this.channel.pipeline().addBefore(PreNettyConstants.HANDLER_ENCODER_NAME, "encrypt", new PacketEncryptor(this.viafabricplus_encryptionCipher));
}
}

View File

@ -4,12 +4,18 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.platform.PreNettyConstants;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import de.florianmichael.vialoadingbase.netty.CustomViaDecodeHandler;
import de.florianmichael.vialoadingbase.netty.CustomViaEncodeHandler;
import de.florianmichael.vialoadingbase.netty.NettyConstants;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import net.minecraft.network.ClientConnection;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.netty.PreNettyDecoder;
import net.raphimc.vialegacy.netty.PreNettyEncoder;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.baseprotocols.PreNettyBaseProtocol;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -27,16 +33,21 @@ public class MixinClientConnection_1 {
@Inject(method = "initChannel", at = @At("TAIL"))
public void hackNettyPipeline(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
// Creating the user connection
final UserConnection user = new UserConnectionImpl(channel, true);
channel.attr(ViaFabricPlus.LOCAL_USER_CONNECTION).set(user);
channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).set(user);
channel.attr(ViaFabricPlus.LOCAL_MINECRAFT_CONNECTION).set(field_11663);
// Creating the pipeline
new ProtocolPipelineImpl(user);
// ViaLoadingBase Packet handling
channel.pipeline().addBefore("encoder", NettyConstants.HANDLER_ENCODER_NAME, new CustomViaEncodeHandler(user));
channel.pipeline().addBefore("decoder", NettyConstants.HANDLER_DECODER_NAME, new CustomViaDecodeHandler(user));
if (ViaLoadingBase.getTargetVersion().isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
user.getProtocolInfo().getPipeline().add(PreNettyBaseProtocol.INSTANCE);
channel.pipeline().addBefore("prepender", PreNettyConstants.HANDLER_ENCODER_NAME, new PreNettyEncoder(user));
channel.pipeline().addBefore("splitter", PreNettyConstants.HANDLER_DECODER_NAME, new PreNettyDecoder(user));
}
}
}
}

View File

@ -0,0 +1,31 @@
package de.florianmichael.viafabricplus.injection.mixin.base;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import net.minecraft.client.network.ClientLoginNetworkHandler;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.Text;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.ProtocolMetadataStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("DataFlowIssue")
@Mixin(ClientLoginNetworkHandler.class)
public class MixinClientLoginNetworkHandler {
@Shadow @Final private ClientConnection connection;
@Inject(method = "joinServerSession", at = @At("HEAD"), cancellable = true)
public void dontVerifySessionIfCracked(String serverId, CallbackInfoReturnable<Text> cir) {
if (ViaLoadingBase.getTargetVersion().isOlderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
if (!connection.channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).get().get(ProtocolMetadataStorage.class).authenticate) {
cir.setReturnValue(null);
}
}
}
}

View File

@ -92,7 +92,7 @@ public abstract class MixinClientPlayerInteractionManager {
else
slotItemBeforeModification = protocolhack_oldItems.get(clickSlot.getSlot());
final PacketWrapper clickSlotPacket = PacketWrapper.create(ServerboundPackets1_16_2.CLICK_WINDOW, networkHandler.getConnection().channel.attr(ViaFabricPlus.LOCAL_USER_CONNECTION).get());
final PacketWrapper clickSlotPacket = PacketWrapper.create(ServerboundPackets1_16_2.CLICK_WINDOW, networkHandler.getConnection().channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).get());
clickSlotPacket.write(Type.UNSIGNED_BYTE, (short) clickSlot.getSyncId());
clickSlotPacket.write(Type.SHORT, (short) clickSlot.getSlot());

View File

@ -11,7 +11,6 @@ import de.florianmichael.viafabricplus.value.ValueHolder;
import de.florianmichael.vialoadingbase.ViaLoadingBase;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Mouse;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.item.HeldItemRenderer;
@ -19,7 +18,6 @@ import net.minecraft.item.SwordItem;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@ -104,7 +102,7 @@ public abstract class MixinMinecraftClient implements IMinecraftClient {
@Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasRidingInventory()Z"))
private void onInventoryKeyPressed(CallbackInfo ci) throws Exception {
final UserConnection viaConnection = getNetworkHandler().getConnection().channel.attr(ViaFabricPlus.LOCAL_USER_CONNECTION).get();
final UserConnection viaConnection = getNetworkHandler().getConnection().channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).get();
if (viaConnection != null && ViaLoadingBase.getTargetVersion().isOlderThanOrEqualTo(ProtocolVersion.v1_11_1)) {
final PacketWrapper clientStatus = PacketWrapper.create(ServerboundPackets1_9_3.CLIENT_STATUS, viaConnection);

View File

@ -18,7 +18,7 @@ public class MixinWolfEntity {
public float rewriteHealth(WolfEntity instance) {
float health = instance.getHealth();
if (ViaLoadingBase.getTargetVersion().isOlderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
return MinecraftClient.getInstance().getNetworkHandler().getConnection().channel.attr(ViaFabricPlus.LOCAL_USER_CONNECTION).get().get(Meta18Storage.class).getHealthDataMap().getOrDefault(instance.getId(), health);
return MinecraftClient.getInstance().getNetworkHandler().getConnection().channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).get().get(Meta18Storage.class).getHealthDataMap().getOrDefault(instance.getId(), health);
}
return health;
}

View File

@ -52,7 +52,7 @@ public class MixinConnectScreen_1 {
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/Packet;)V", ordinal = 1, shift = At.Shift.BEFORE))
public void setupConnectionSessions(CallbackInfo ci) {
final UserConnection userConnection = field_2416.connection.channel.attr(ViaFabricPlus.LOCAL_USER_CONNECTION).get();
final UserConnection userConnection = field_2416.connection.channel.attr(ViaFabricPlus.LOCAL_VIA_CONNECTION).get();
if (userConnection == null) {
ViaLoadingBase.LOGGER.log(Level.WARNING, "ViaVersion userConnection is null");

View File

@ -2,6 +2,6 @@ package de.florianmichael.viafabricplus.platform;
public class PreNettyConstants {
public static final String DECODER = "via-legacy-decoder";
public static final String ENCODER = "via-legacy-encoder";
public static final String HANDLER_DECODER_NAME = "via-legacy-decoder";
public static final String HANDLER_ENCODER_NAME = "via-legacy-encoder";
}

View File

@ -0,0 +1,12 @@
package de.florianmichael.viafabricplus.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider;
public class ViaFabricPlusClassicWorldHeightProvider extends ClassicWorldHeightProvider {
@Override
public short getMaxChunkSectionCount(UserConnection user) {
return 64;
}
}

View File

@ -0,0 +1,22 @@
package de.florianmichael.viafabricplus.provider;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viafabricplus.definition.v1_19_0.provider.CommandArgumentsProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.argument.SignedArgumentList;
import java.util.List;
public class ViaFabricPlusCommandArgumentsProvider extends CommandArgumentsProvider {
@Override
public List<Pair<String, String>> getSignedArguments(String command) {
final ClientPlayNetworkHandler clientPlayNetworkHandler = MinecraftClient.getInstance().getNetworkHandler();
if (clientPlayNetworkHandler != null) {
return SignedArgumentList.of(clientPlayNetworkHandler.getCommandDispatcher().parse(command, clientPlayNetworkHandler.getCommandSource())).arguments().stream().map(function -> new Pair<>(function.getNodeName(), function.value())).toList();
}
return super.getSignedArguments(command);
}
}

View File

@ -0,0 +1,18 @@
package de.florianmichael.viafabricplus.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import net.minecraft.network.ClientConnection;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider;
public class ViaFabricPlusEncryptionProvider extends EncryptionProvider {
@Override
public void enableDecryption(UserConnection user) {
final ClientConnection clientConnection = user.getChannel().attr(ViaFabricPlus.LOCAL_MINECRAFT_CONNECTION).get();
if (clientConnection != null) {
((IClientConnection) clientConnection).viafabricplus_setupPreNettyEncryption();
}
}
}

View File

@ -0,0 +1,56 @@
package de.florianmichael.viafabricplus.provider;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.HttpAuthenticationService;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.GameProfile;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher;
import java.net.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class ViaFabricPlusGameProfileFetcher extends GameProfileFetcher {
public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService();
public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository();
@Override
public UUID loadMojangUUID(String playerName) throws Exception {
final CompletableFuture<com.mojang.authlib.GameProfile> future = new CompletableFuture<>();
GAME_PROFILE_REPOSITORY.findProfilesByNames(new String[]{playerName}, Agent.MINECRAFT, new ProfileLookupCallback() {
@Override
public void onProfileLookupSucceeded(com.mojang.authlib.GameProfile profile) {
future.complete(profile);
}
@Override
public void onProfileLookupFailed(com.mojang.authlib.GameProfile profile, Exception exception) {
future.completeExceptionally(exception);
}
});
if (!future.isDone()) {
future.completeExceptionally(new ProfileNotFoundException());
}
return future.get().getId();
}
@Override
public GameProfile loadGameProfile(UUID uuid) throws Exception {
final com.mojang.authlib.GameProfile inProfile = new com.mojang.authlib.GameProfile(uuid, null);
final com.mojang.authlib.GameProfile mojangProfile = SESSION_SERVICE.fillProfileProperties(inProfile, true);
if (mojangProfile.equals(inProfile)) throw new ProfileNotFoundException();
final GameProfile gameProfile = new GameProfile(mojangProfile.getName(), mojangProfile.getId());
for (final var entry : mojangProfile.getProperties().entries()) {
final Property prop = entry.getValue();
gameProfile.addProperty(new GameProfile.Property(prop.getName(), prop.getValue(), prop.getSignature()));
}
return gameProfile;
}
}

View File

@ -0,0 +1,15 @@
package de.florianmichael.viafabricplus.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import net.minecraft.client.MinecraftClient;
import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider;
public class ViaFabricPlusOldAuthProvider extends OldAuthProvider {
@Override
public void sendAuthRequest(UserConnection user, String serverId) throws Throwable {
final MinecraftClient mc = MinecraftClient.getInstance();
mc.getSessionService().joinServer(mc.getSession().getProfile(), mc.getSession().getAccessToken(), serverId);
}
}

View File

@ -41,6 +41,9 @@ public class ValueHolder {
public static final ProtocolSyncBooleanValue replaceSneaking = new ProtocolSyncBooleanValue("Replace sneaking", ProtocolRange.andOlder(ProtocolVersion.v1_7_6));
public static final ProtocolSyncBooleanValue longSneaking = new ProtocolSyncBooleanValue("Long sneaking", ProtocolRange.andOlder(ProtocolVersion.v1_7_6));
// a1_0_15 -> c0_28toc0_30
public static final ProtocolSyncBooleanValue useBetaCraftAuthentication = new ProtocolSyncBooleanValue("Use BetaCraft authentication", ProtocolRange.andOlder(LegacyProtocolVersion.c0_28toc0_30));
public static void setup() throws FileNotFoundException {
if (CONFIG_FILE.exists()) {
final JsonObject parentNode = GSON.fromJson(new FileReader(CONFIG_FILE), JsonObject.class).getAsJsonObject();

View File

@ -120,5 +120,8 @@
],
"injectors": {
"defaultRequire": 1
}
},
"client": [
"base.MixinClientLoginNetworkHandler"
]
}