diff --git a/README.md b/README.md index f678ddb..81eeccc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ViaForge -Client-side Implementation of ViaVersion, ViaBackwards and ViaRewind for Legacy Minecraft Forge +Client-side Implementation of the Via* projects for Minecraft Forge ## Contact If you encounter any issues, please report them on the diff --git a/buildSrc/src/main/groovy/viaforge.base-conventions.gradle b/buildSrc/src/main/groovy/viaforge.base-conventions.gradle index b01dc3e..742bb14 100644 --- a/buildSrc/src/main/groovy/viaforge.base-conventions.gradle +++ b/buildSrc/src/main/groovy/viaforge.base-conventions.gradle @@ -24,8 +24,11 @@ dependencies { include "com.viaversion:viaversion:${project.viaversion_version}" include "com.viaversion:viabackwards:${project.viabackwards_version}" include "com.viaversion:viarewind-universal:${project.viarewind_version}" + include ("net.raphimc:ViaLegacy:${project.vialegacy_version}") { + exclude group: "com.google.code.gson", module: "gson" + } + include "net.raphimc:ViaAprilFools:${project.viaaprilfools_version}" + include "net.raphimc:ViaLoader:${project.vialoader_version}" include "org.yaml:snakeyaml:${project.snake_yml_version}" - - include "net.raphimc:ViaLoader:${project.vialoader_version}" } diff --git a/gradle.properties b/gradle.properties index 5aca323..0f7cba5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,11 +8,12 @@ maven_version=3.5.0-SNAPSHOT maven_group=de.florianmichael # ViaVersion -vialoader_version=2.2.11-SNAPSHOT - viaversion_version=4.9.0-23w42a-SNAPSHOT viabackwards_version=4.9.0-23w42a-SNAPSHOT viarewind_version=3.0.3-SNAPSHOT +vialegacy_version=2.2.21-SNAPSHOT +viaaprilfools_version=2.0.10-SNAPSHOT +vialoader_version=2.2.11-SNAPSHOT snake_yml_version=2.2 diff --git a/src/main/java/de/florianmichael/viaforge/common/ViaForgeCommon.java b/src/main/java/de/florianmichael/viaforge/common/ViaForgeCommon.java index 71876fe..d7b97f3 100644 --- a/src/main/java/de/florianmichael/viaforge/common/ViaForgeCommon.java +++ b/src/main/java/de/florianmichael/viaforge/common/ViaForgeCommon.java @@ -23,14 +23,14 @@ import com.viaversion.viaversion.protocol.ProtocolPipelineImpl; import de.florianmichael.viaforge.common.platform.VFPlatform; import de.florianmichael.viaforge.common.platform.ViaForgeConfig; import de.florianmichael.viaforge.common.protocolhack.ViaForgeVLInjector; +import de.florianmichael.viaforge.common.protocolhack.netty.IEncryptionSetup; import de.florianmichael.viaforge.common.protocolhack.netty.ViaForgeVLLegacyPipeline; import de.florianmichael.viaforge.common.protocolhack.ViaForgeVLLoader; import io.netty.channel.Channel; import io.netty.channel.socket.SocketChannel; +import io.netty.util.AttributeKey; import net.raphimc.vialoader.ViaLoader; -import net.raphimc.vialoader.impl.platform.ViaBackwardsPlatformImpl; -import net.raphimc.vialoader.impl.platform.ViaRewindPlatformImpl; -import net.raphimc.vialoader.impl.platform.ViaVersionPlatformImpl; +import net.raphimc.vialoader.impl.platform.*; import net.raphimc.vialoader.netty.CompressionReorderEvent; import net.raphimc.vialoader.util.VersionEnum; @@ -41,6 +41,9 @@ import java.io.File; * It is used to inject the ViaVersion pipeline into the netty pipeline. It also manages the target version. */ public class ViaForgeCommon { + public final static AttributeKey LOCAL_VIA_USER = AttributeKey.valueOf("local_via_user"); + public final static AttributeKey ENCRYPTION_SETUP = AttributeKey.valueOf("encryption_setup"); + private static ViaForgeCommon manager; private final VFPlatform platform; @@ -70,7 +73,7 @@ public class ViaForgeCommon { final File mainFolder = new File(platform.getLeadingDirectory(), "ViaForge"); - ViaLoader.init(new ViaVersionPlatformImpl(mainFolder), new ViaForgeVLLoader(), new ViaForgeVLInjector(), null, ViaBackwardsPlatformImpl::new, ViaRewindPlatformImpl::new); + ViaLoader.init(new ViaVersionPlatformImpl(mainFolder), new ViaForgeVLLoader(platform), new ViaForgeVLInjector(), null, ViaBackwardsPlatformImpl::new, ViaRewindPlatformImpl::new, ViaLegacyPlatformImpl::new, ViaAprilFoolsPlatformImpl::new); manager.config = new ViaForgeConfig(new File(mainFolder, "viaforge.yml")); final VersionEnum configVersion = VersionEnum.fromProtocolId(manager.config.getClientSideVersion()); @@ -91,6 +94,8 @@ public class ViaForgeCommon { final UserConnection user = new UserConnectionImpl(channel, true); new ProtocolPipelineImpl(user); + channel.attr(LOCAL_VIA_USER).set(user); + channel.pipeline().addLast(new ViaForgeVLLegacyPipeline(user, targetVersion)); } } diff --git a/src/main/java/de/florianmichael/viaforge/common/platform/VFPlatform.java b/src/main/java/de/florianmichael/viaforge/common/platform/VFPlatform.java index dc07ff9..0a2f8f9 100644 --- a/src/main/java/de/florianmichael/viaforge/common/platform/VFPlatform.java +++ b/src/main/java/de/florianmichael/viaforge/common/platform/VFPlatform.java @@ -17,6 +17,8 @@ */ package de.florianmichael.viaforge.common.platform; +import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher; + import java.io.File; import java.util.function.Supplier; @@ -39,4 +41,16 @@ public interface VFPlatform { * @return the leading directory of the platform */ File getLeadingDirectory(); + + /** + * Sends the joinServer API request to Mojang's authentication servers. + * + * @param serverId the server id of the server + */ + void joinServer(final String serverId) throws Throwable; + + /** + * @return the game profile fetcher of the platform for ViaLegacy + */ + GameProfileFetcher getGameProfileFetcher(); } diff --git a/src/main/java/de/florianmichael/viaforge/common/platform/ViaForgeConfig.java b/src/main/java/de/florianmichael/viaforge/common/platform/ViaForgeConfig.java index 75df388..0cee451 100644 --- a/src/main/java/de/florianmichael/viaforge/common/platform/ViaForgeConfig.java +++ b/src/main/java/de/florianmichael/viaforge/common/platform/ViaForgeConfig.java @@ -15,6 +15,8 @@ public class ViaForgeConfig extends Config { public final static String SHOW_MULTIPLAYER_BUTTON = "show-multiplayer-button"; public final static String SHOW_DIRECT_CONNECT_BUTTON = "show-direct-connect-button"; + public final static String VERIFY_SESSION_IN_OLD_VERSIONS = "verify-session-in-old-versions"; + /** * @param configFile The location of where the config is loaded/saved. */ @@ -62,4 +64,8 @@ public class ViaForgeConfig extends Config { public boolean isShowDirectConnectButton() { return getBoolean(SHOW_DIRECT_CONNECT_BUTTON, true); } + + public boolean isVerifySessionInOldVersions() { + return getBoolean(VERIFY_SESSION_IN_OLD_VERSIONS, true); + } } diff --git a/src/main/java/de/florianmichael/viaforge/common/protocolhack/ViaForgeVLLoader.java b/src/main/java/de/florianmichael/viaforge/common/protocolhack/ViaForgeVLLoader.java index 2826e17..700e379 100644 --- a/src/main/java/de/florianmichael/viaforge/common/protocolhack/ViaForgeVLLoader.java +++ b/src/main/java/de/florianmichael/viaforge/common/protocolhack/ViaForgeVLLoader.java @@ -21,12 +21,24 @@ import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.platform.providers.ViaProviders; import com.viaversion.viaversion.api.protocol.version.VersionProvider; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import de.florianmichael.viaforge.common.platform.VFPlatform; import de.florianmichael.viaforge.common.protocolhack.provider.DummyMovementTransmitter; +import de.florianmichael.viaforge.common.protocolhack.provider.ViaForgeEncryptionProvider; +import de.florianmichael.viaforge.common.protocolhack.provider.ViaForgeOldAuthProvider; import de.florianmichael.viaforge.common.protocolhack.provider.ViaForgeVersionProvider; +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 net.raphimc.vialoader.impl.viaversion.VLLoader; public class ViaForgeVLLoader extends VLLoader { + private final VFPlatform platform; + + public ViaForgeVLLoader(VFPlatform platform) { + this.platform = platform; + } + @Override public void load() { super.load(); @@ -35,5 +47,8 @@ public class ViaForgeVLLoader extends VLLoader { providers.use(VersionProvider.class, new ViaForgeVersionProvider()); providers.use(MovementTransmitterProvider.class, new DummyMovementTransmitter()); + providers.use(OldAuthProvider.class, new ViaForgeOldAuthProvider()); + providers.use(GameProfileFetcher.class, platform.getGameProfileFetcher()); + providers.use(EncryptionProvider.class, new ViaForgeEncryptionProvider()); } } diff --git a/src/main/java/de/florianmichael/viaforge/common/protocolhack/netty/IEncryptionSetup.java b/src/main/java/de/florianmichael/viaforge/common/protocolhack/netty/IEncryptionSetup.java new file mode 100644 index 0000000..72ed16a --- /dev/null +++ b/src/main/java/de/florianmichael/viaforge/common/protocolhack/netty/IEncryptionSetup.java @@ -0,0 +1,10 @@ +package de.florianmichael.viaforge.common.protocolhack.netty; + +public interface IEncryptionSetup { + + /** + * API method to setup the decryption side of the pipeline. + * This method is called by the {@link de.florianmichael.viaforge.common.protocolhack.provider.ViaForgeEncryptionProvider} class. + */ + void viaforge_setupPreNettyDecryption(); +} diff --git a/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeEncryptionProvider.java b/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeEncryptionProvider.java new file mode 100644 index 0000000..c4b5630 --- /dev/null +++ b/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeEncryptionProvider.java @@ -0,0 +1,13 @@ +package de.florianmichael.viaforge.common.protocolhack.provider; + +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider; + +public class ViaForgeEncryptionProvider extends EncryptionProvider { + + @Override + public void enableDecryption(UserConnection user) { + user.getChannel().attr(ViaForgeCommon.ENCRYPTION_SETUP).getAndRemove().viaforge_setupPreNettyDecryption(); + } +} diff --git a/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeOldAuthProvider.java b/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeOldAuthProvider.java new file mode 100644 index 0000000..a075758 --- /dev/null +++ b/src/main/java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeOldAuthProvider.java @@ -0,0 +1,18 @@ +package de.florianmichael.viaforge.common.protocolhack.provider; + +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider; + +public class ViaForgeOldAuthProvider extends OldAuthProvider { + + @Override + public void sendAuthRequest(UserConnection user, String serverId) throws Throwable { + final ViaForgeCommon common = ViaForgeCommon.getManager(); + if (!common.getConfig().isVerifySessionInOldVersions()) { + return; + } + + common.getPlatform().joinServer(serverId); + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index b5beba3..620259d 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -13,5 +13,5 @@ displayURL="https://github.com/FlorianMichael" credits="FlorianMichael/EnZaXD and all ViaVersion/ViaForge contributors" authors="FlorianMichael/EnZaXD" description=''' - Client-side Implementation of ViaVersion, ViaBackwards and ViaRewind for Legacy Minecraft Forge + Client-side Implementation of the Via* projects for Minecraft Forge ''' \ No newline at end of file diff --git a/src/main/resources/assets/viaforge/config.yml b/src/main/resources/assets/viaforge/config.yml index 849d67e..6e5d972 100644 --- a/src/main/resources/assets/viaforge/config.yml +++ b/src/main/resources/assets/viaforge/config.yml @@ -12,3 +12,6 @@ show-multiplayer-button: true # # This option indicates if the ViaForge button should be shown in the direct connect screen. show-direct-connect-button: true +# +# Manually sends the joinServer request when connecting to <= 1.2.5 servers. +verify-session-in-old-versions: true diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 4c11457..3d21428 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -2,7 +2,7 @@ { "modid": "viaforge", "name": "ViaForge", - "description": "Client-side Implementation of ViaVersion, ViaBackwards and ViaRewind for Legacy Minecraft Forge", + "description": "Client-side Implementation of the Via* projects for Minecraft Forge", "version": "${version}", "mcversion": "[1.12.2]", "url": "https://github.com/ViaVersion/ViaForge", diff --git a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/ViaForge112.java b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/ViaForge112.java index d75cf01..c4390b6 100644 --- a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/ViaForge112.java +++ b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/ViaForge112.java @@ -18,9 +18,12 @@ package de.florianmichael.viaforge; import de.florianmichael.viaforge.common.platform.VFPlatform; +import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher; import net.minecraft.client.Minecraft; import net.minecraft.realms.RealmsSharedConstants; +import net.minecraft.util.Session; import net.minecraftforge.fml.common.Mod; +import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher; import java.io.File; import java.util.function.Supplier; @@ -43,4 +46,16 @@ public class ViaForge112 implements VFPlatform { public File getLeadingDirectory() { return Minecraft.getMinecraft().gameDir; } + + @Override + public void joinServer(String serverId) throws Throwable { + final Session session = Minecraft.getMinecraft().getSession(); + + Minecraft.getMinecraft().getSessionService().joinServer(session.getProfile(), session.getToken(), serverId); + } + + @Override + public GameProfileFetcher getGameProfileFetcher() { + return new ViaForgeGameProfileFetcher(); + } } diff --git a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetHandlerLoginClient.java b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetHandlerLoginClient.java new file mode 100644 index 0000000..19610fc --- /dev/null +++ b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetHandlerLoginClient.java @@ -0,0 +1,37 @@ +package de.florianmichael.viaforge.mixin.impl; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.viaforge.common.ViaForgeCommon; +import net.minecraft.client.network.NetHandlerLoginClient; +import net.minecraft.network.NetworkManager; +import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.ProtocolMetadataStorage; +import net.raphimc.vialoader.util.VersionEnum; +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.Redirect; + +@SuppressWarnings("DataFlowIssue") +@Mixin(NetHandlerLoginClient.class) +public class MixinNetHandlerLoginClient { + + @Shadow @Final private NetworkManager networkManager; + + @Redirect(method = "handleEncryptionRequest", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/minecraft/MinecraftSessionService;joinServer(Lcom/mojang/authlib/GameProfile;Ljava/lang/String;Ljava/lang/String;)V")) + public void onlyJoinServerIfPremium(MinecraftSessionService instance, GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException { + if (ViaForgeCommon.getManager().getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_6_4)) { + final UserConnection user = networkManager.channel().attr(ViaForgeCommon.LOCAL_VIA_USER).get(); + if (user != null && user.has(ProtocolMetadataStorage.class) && !user.get(ProtocolMetadataStorage.class).authenticate) { + // We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call + // if the server is in offline mode, due the packet changes <-> networking changes + // Minecraft's networking code is bad for us. + return; + } + } + instance.joinServer(profile, authenticationToken, serverId); + } +} diff --git a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetworkManager.java b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetworkManager.java index 687b54a..34a53a2 100644 --- a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetworkManager.java +++ b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/mixin/impl/MixinNetworkManager.java @@ -18,21 +18,68 @@ package de.florianmichael.viaforge.mixin.impl; import de.florianmichael.viaforge.common.ViaForgeCommon; +import de.florianmichael.viaforge.common.protocolhack.netty.IEncryptionSetup; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.network.NettyEncryptingDecoder; +import net.minecraft.network.NettyEncryptingEncoder; import net.minecraft.network.NetworkManager; +import net.minecraft.util.CryptManager; +import net.raphimc.vialoader.netty.VLLegacyPipeline; +import net.raphimc.vialoader.util.VersionEnum; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + @Mixin(NetworkManager.class) -public class MixinNetworkManager { +public class MixinNetworkManager implements IEncryptionSetup { @Shadow private Channel channel; + @Unique + private Cipher viaforge_decryptionCipher; + + @Inject(method = "channelActive", at = @At("RETURN")) + public void trackThisClass(ChannelHandlerContext p_channelActive_1_, CallbackInfo ci) { + // We need to access this class later to call the viaforge_setupPreNettyDecryption method. + // In one of the ViaLegacy's required providers, so we track this class instance as an own + // attribute in the connection and later access it from there and remove it. + // Counterpart in {@link java/de/florianmichael/viaforge/common/protocolhack/provider/ViaForgeEncryptionProvider.java} + channel.attr(ViaForgeCommon.ENCRYPTION_SETUP).set(this); + } + + @Inject(method = "enableEncryption", at = @At("HEAD"), cancellable = true) + private void storeEncryptionCiphers(SecretKey key, CallbackInfo ci) { + if (ViaForgeCommon.getManager().getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_6_4)) { + // Minecraft's encryption code is bad for us, we need to reorder the pipeline + ci.cancel(); + + // Minecraft 1.6.4 supports tile encryption which means the server can only disable one side of the encryption + // So we only enable the encryption side and later enable the decryption side if the 1.7 -> 1.6 protocol + // tells us to do, therefore we need to store the cipher instance. + this.viaforge_decryptionCipher = CryptManager.createNetCipherInstance(2, key); + + // Enabling the encryption side + this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new NettyEncryptingEncoder(CryptManager.createNetCipherInstance(1, key))); + } + } + @Inject(method = "setCompressionThreshold", at = @At("RETURN")) public void reorderPipeline(int p_setCompressionTreshold_1_, CallbackInfo ci) { + // When Minecraft enables compression, we need to reorder the pipeline + // to match the counterparts of via-decoder <-> encoder and via-encoder <-> encoder ViaForgeCommon.getManager().reorderCompression(channel); } + + @Override + public void viaforge_setupPreNettyDecryption() { + // Enabling the decryption side for 1.6.4 if the 1.7 -> 1.6 protocol tells us to do + this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "decrypt", new NettyEncryptingDecoder(this.viaforge_decryptionCipher)); + } } diff --git a/viaforge-mc112/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java new file mode 100644 index 0000000..2d06f53 --- /dev/null +++ b/viaforge-mc112/src/main/java/de/florianmichael/viaforge/provider/ViaForgeGameProfileFetcher.java @@ -0,0 +1,57 @@ +package de.florianmichael.viaforge.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 ViaForgeGameProfileFetcher extends GameProfileFetcher { + public final static HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY, ""); + public final static MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService(); + public final static GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository(); + + @Override + public UUID loadMojangUUID(String playerName) throws Exception { + final CompletableFuture 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 java.util.Map.Entry entry : mojangProfile.getProperties().entries()) { + final Property prop = entry.getValue(); + gameProfile.addProperty(new GameProfile.Property(prop.getName(), prop.getValue(), prop.getSignature())); + } + + return gameProfile; + } +} diff --git a/viaforge-mc112/src/main/resources/mixins.viaforge-mc112.json b/viaforge-mc112/src/main/resources/mixins.viaforge-mc112.json index 2d2de04..f927439 100644 --- a/viaforge-mc112/src/main/resources/mixins.viaforge-mc112.json +++ b/viaforge-mc112/src/main/resources/mixins.viaforge-mc112.json @@ -8,6 +8,7 @@ "MixinGuiMainMenu", "MixinGuiMultiplayer", "MixinGuiScreenServerList", + "MixinNetHandlerLoginClient", "MixinNetworkManager", "MixinNetworkManager_5", "fixes.MixinEntityPlayerSP"