From 00af00dfe8f988bb9b789e43fca3de0ab5e11fd0 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Mon, 3 Oct 2022 13:09:15 +0200 Subject: [PATCH] Fix fucking bukkit injection --- .../lixfel/altauth/bukkit/AltAuthBukkit.java | 12 +- .../altauth/bukkit/AltAuthSessionService.java | 146 +++++++++++++ .../bukkit/EncryptionRequestInjector.java | 30 --- .../altauth/bukkit/ProtocolInjector.java | 199 ------------------ .../altauth/bukkit/ServerIdInjector.java | 126 +++++++++++ .../bukkit/SessionServiceInjector.java | 56 ----- 6 files changed, 277 insertions(+), 292 deletions(-) create mode 100644 bukkit/src/de/lixfel/altauth/bukkit/AltAuthSessionService.java delete mode 100644 bukkit/src/de/lixfel/altauth/bukkit/EncryptionRequestInjector.java delete mode 100644 bukkit/src/de/lixfel/altauth/bukkit/ProtocolInjector.java create mode 100644 bukkit/src/de/lixfel/altauth/bukkit/ServerIdInjector.java delete mode 100644 bukkit/src/de/lixfel/altauth/bukkit/SessionServiceInjector.java diff --git a/bukkit/src/de/lixfel/altauth/bukkit/AltAuthBukkit.java b/bukkit/src/de/lixfel/altauth/bukkit/AltAuthBukkit.java index 8311c9e..3f97602 100644 --- a/bukkit/src/de/lixfel/altauth/bukkit/AltAuthBukkit.java +++ b/bukkit/src/de/lixfel/altauth/bukkit/AltAuthBukkit.java @@ -13,8 +13,8 @@ public class AltAuthBukkit extends JavaPlugin { @Setter private static JavaPlugin instance; - private SessionServiceInjector serviceInjector; - private EncryptionRequestInjector requestInjector; + private ServerIdInjector serverIdInjector; + private AltAuthSessionService serviceInjector; @Override public void onLoad() { @@ -26,15 +26,13 @@ public class AltAuthBukkit extends JavaPlugin { saveDefaultConfig(); String altAuthServer = getConfig().getString("altauth-proxy"); - ProtocolInjector.init(); - serviceInjector = new SessionServiceInjector(altAuthServer); - requestInjector = new EncryptionRequestInjector(altAuthServer); + serverIdInjector = new ServerIdInjector(this, altAuthServer); + serviceInjector = new AltAuthSessionService(serverIdInjector, altAuthServer); } @Override public void onDisable() { - requestInjector.remove(); serviceInjector.revert(); - ProtocolInjector.instance.close(); + serverIdInjector.close(); } } diff --git a/bukkit/src/de/lixfel/altauth/bukkit/AltAuthSessionService.java b/bukkit/src/de/lixfel/altauth/bukkit/AltAuthSessionService.java new file mode 100644 index 0000000..70c1c8a --- /dev/null +++ b/bukkit/src/de/lixfel/altauth/bukkit/AltAuthSessionService.java @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: MIT + +package de.lixfel.altauth.bukkit; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfileRepository; +import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.exceptions.AuthenticationUnavailableException; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService; +import de.lixfel.ReflectionUtil; + +import javax.crypto.SecretKey; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; + +public class AltAuthSessionService implements MinecraftSessionService { + + private static final ReflectionUtil.FieldWrapper CHECK_URL = ReflectionUtil.getField(YggdrasilMinecraftSessionService.class, URL.class, 1); + private static final boolean URL_STATIC = ReflectionUtil.MINECRAFT_VERSION < 17; //TODO maybe 16 (untested) + + private static final Function swapService; + private static final Consumer revertService; + + static { + if (ReflectionUtil.MINECRAFT_VERSION < 19) { + ReflectionUtil.FieldWrapper getService = ReflectionUtil.getField(ServerIdInjector.minecraftServer, MinecraftSessionService.class, 0); + + swapService = altAuthService -> { + Object minecraftServer = altAuthService.serverIdInjector.minecraftServerInstance(); + YggdrasilMinecraftSessionService service = (YggdrasilMinecraftSessionService) getService.get(minecraftServer); + getService.set(minecraftServer, altAuthService); + return service; + }; + revertService = altAuthService -> getService.set(altAuthService.serverIdInjector.minecraftServerInstance(), altAuthService.service); + } else { + Class services = ReflectionUtil.getClass("net.minecraft.server.Services"); + ReflectionUtil.FieldWrapper getServices = ReflectionUtil.getField(ServerIdInjector.minecraftServer, services, 0); + ReflectionUtil.FieldWrapper getSessionService = ReflectionUtil.getField(services, MinecraftSessionService.class, 0); + Class signatureValidator = ReflectionUtil.getClass("net.minecraft.util.SignatureValidator"); + ReflectionUtil.FieldWrapper getSignatureValidator = ReflectionUtil.getField(services, signatureValidator, 0); + ReflectionUtil.FieldWrapper getGameProfileRepository = ReflectionUtil.getField(services, GameProfileRepository.class, 0); + Class userCache = ReflectionUtil.getClass("net.minecraft.server.players.UserCache"); + ReflectionUtil.FieldWrapper getUserCache = ReflectionUtil.getField(services, userCache, 0); + + Constructor constructor; + try { + constructor = services.getConstructor(MinecraftSessionService.class, signatureValidator, GameProfileRepository.class, userCache); + } catch (NoSuchMethodException e) { + throw new IllegalStateException(e); + } + + swapService = altAuthService -> { + Object servicesInstance = getServices.get(altAuthService.serverIdInjector.minecraftServerInstance()); + + try { + getServices.set( + altAuthService.serverIdInjector.minecraftServerInstance(), + constructor.newInstance(altAuthService, getSignatureValidator.get(servicesInstance), getGameProfileRepository.get(servicesInstance), getUserCache.get(servicesInstance)) + ); + } catch (InstantiationException | IllegalAccessException| InvocationTargetException e) { + throw new IllegalStateException(e); + } + + return (YggdrasilMinecraftSessionService) getSessionService.get(servicesInstance); + }; + revertService = altAuthService -> { + Object servicesInstance = getServices.get(altAuthService.serverIdInjector.minecraftServerInstance()); + + try { + getServices.set( + altAuthService.serverIdInjector.minecraftServerInstance(), + constructor.newInstance(altAuthService.service, getSignatureValidator.get(servicesInstance), getGameProfileRepository.get(servicesInstance), getUserCache.get(servicesInstance)) + ); + } catch (InstantiationException | IllegalAccessException| InvocationTargetException e) { + throw new IllegalStateException(e); + } + }; + } + } + + private static final Class minecraftEncryption = ReflectionUtil.getClass("net.minecraft.util.MinecraftEncryption"); + private static final ReflectionUtil.MethodWrapper getServerHash = ReflectionUtil.getMethod(minecraftEncryption, byte[].class, null, String.class, PublicKey.class, SecretKey.class); + private static final ReflectionUtil.MethodWrapper getSecretKey = ReflectionUtil.getMethod(minecraftEncryption, null, PrivateKey.class, byte[].class); + + private static final ReflectionUtil.FieldWrapper getKeyPair = ReflectionUtil.getField(ServerIdInjector.minecraftServer, KeyPair.class, 0); + + private final YggdrasilMinecraftSessionService service; + private final URL checkUrlBackup; + + private final KeyPair keyPair; + private final ServerIdInjector serverIdInjector; + private final String altAuthServer; + + public AltAuthSessionService(ServerIdInjector serverIdInjector, String altAuthServer) { + this.serverIdInjector = serverIdInjector; + this.altAuthServer = altAuthServer; + this.keyPair = getKeyPair.get(serverIdInjector.minecraftServerInstance()); + + service = swapService.apply(this); + checkUrlBackup = CHECK_URL.get(URL_STATIC ? null : service); + + try { + CHECK_URL.set(URL_STATIC ? null : service, new URL("https://" + altAuthServer + "/session/minecraft/hasJoined")); + } catch (MalformedURLException e) { + AltAuthBukkit.getInstance().getLogger().log(Level.SEVERE, "Could not create AltAuth URLs", e); + } + } + + public void revert() { + CHECK_URL.set(URL_STATIC ? null : service, checkUrlBackup); + revertService.accept(this); + } + + @Override + public void joinServer(GameProfile gameProfile, String s, String s1) throws AuthenticationException { + service.joinServer(gameProfile, s, s1); + } + + @Override + public GameProfile hasJoinedServer(GameProfile gameProfile, String serverId, InetAddress inetAddress) throws AuthenticationUnavailableException { + return service.hasJoinedServer(gameProfile, new BigInteger((byte[]) getServerHash.invoke(null, altAuthServer, keyPair.getPublic(), getSecretKey.invoke(null, keyPair.getPrivate(), serverIdInjector.getEncryptedSecret(gameProfile.getName())))).toString(16), inetAddress); + } + + @Override + public Map getTextures(GameProfile gameProfile, boolean b) { + return service.getTextures(gameProfile, b); + } + + @Override + public GameProfile fillProfileProperties(GameProfile gameProfile, boolean b) { + return service.fillProfileProperties(gameProfile, b); + } +} diff --git a/bukkit/src/de/lixfel/altauth/bukkit/EncryptionRequestInjector.java b/bukkit/src/de/lixfel/altauth/bukkit/EncryptionRequestInjector.java deleted file mode 100644 index a284bcb..0000000 --- a/bukkit/src/de/lixfel/altauth/bukkit/EncryptionRequestInjector.java +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -package de.lixfel.altauth.bukkit; - -import de.lixfel.ReflectionUtil; -import org.bukkit.entity.Player; - -public class EncryptionRequestInjector { - - private static final Class EncryptionRequest = ReflectionUtil.getClass("net.minecraft.network.protocol.login.PacketLoginOutEncryptionBegin"); - private static final ReflectionUtil.FieldWrapper ServerID = ReflectionUtil.getField(EncryptionRequest, String.class, 0); - - private final String altAuthServer; - - public EncryptionRequestInjector(String altAuthServer) { - this.altAuthServer = altAuthServer; - - ProtocolInjector.instance.addFilter(EncryptionRequest, this::handleEncryptionRequest); - } - - public Object handleEncryptionRequest(Player player, Object packet) { - ServerID.set(packet, altAuthServer); - ProtocolInjector.instance.getInterceptor(player).ifPresent(ProtocolInjector.PacketInterceptor::close); - return packet; - } - - public void remove() { - ProtocolInjector.instance.removeFilter(EncryptionRequest, this::handleEncryptionRequest); - } -} diff --git a/bukkit/src/de/lixfel/altauth/bukkit/ProtocolInjector.java b/bukkit/src/de/lixfel/altauth/bukkit/ProtocolInjector.java deleted file mode 100644 index d038ea7..0000000 --- a/bukkit/src/de/lixfel/altauth/bukkit/ProtocolInjector.java +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: MIT - -package de.lixfel.altauth.bukkit; - -import de.lixfel.ReflectionUtil; -import de.lixfel.ReflectionUtil.FieldWrapper; -import io.netty.channel.Channel; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.plugin.Plugin; - -import java.util.*; -import java.util.function.BiFunction; -import java.util.logging.Level; - -// ProtocolInjector heavily inspired by TinyProtocol -public class ProtocolInjector implements Listener { - - private static final Class craftServer = ReflectionUtil.getClass("org.bukkit.craftbukkit.CraftServer"); - private static final Class dedicatedPlayerList = ReflectionUtil.getClass("net.minecraft.server.dedicated.DedicatedPlayerList"); - private static final FieldWrapper getPlayerList = ReflectionUtil.getField(craftServer, dedicatedPlayerList, 0); - private static final Class playerList = ReflectionUtil.getClass("net.minecraft.server.players.PlayerList"); - public static final Class minecraftServer = ReflectionUtil.getClass("net.minecraft.server.MinecraftServer"); - private static final FieldWrapper getMinecraftServer = ReflectionUtil.getField(playerList, minecraftServer, 0); - private static final Class serverConnection = ReflectionUtil.getClass("net.minecraft.server.network.ServerConnection"); - private static final FieldWrapper getServerConnection = ReflectionUtil.getField(minecraftServer, serverConnection, 0); - private static final Class networkManager = ReflectionUtil.getClass("net.minecraft.network.NetworkManager"); - private static final FieldWrapper getConnections = ReflectionUtil.getField(serverConnection, List.class, 0, networkManager); - - public static final ProtocolInjector instance = new ProtocolInjector(AltAuthBukkit.getInstance()); - - public static void init() { - //enforce init - } - - private final Plugin plugin; - private final String handlerName; - private final Object minecraftServerInstance; - private final List connections; - private boolean closed; - - private final Map, List>> packetFilters = new HashMap<>(); - private final Map playerInterceptors = new HashMap<>(); - - private ProtocolInjector(final Plugin plugin) { - this.plugin = plugin; - this.handlerName = "altauth"; - this.minecraftServerInstance = getMinecraftServer.get(getPlayerList.get(plugin.getServer())); - this.connections = getConnections.get(getServerConnection.get(minecraftServerInstance)); - - plugin.getServer().getPluginManager().registerEvents(this, plugin); - - for (Player player : plugin.getServer().getOnlinePlayers()) { - new PacketInterceptor(player); - } - } - - public Object minecraftServer() { - return minecraftServerInstance; - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerLogin(PlayerLoginEvent e) { - if(closed) - return; - new PacketInterceptor(e.getPlayer()); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerDisconnect(PlayerQuitEvent e) { - getInterceptor(e.getPlayer()).ifPresent(PacketInterceptor::close); - } - - @EventHandler - public void onPluginDisable(PluginDisableEvent e) { - if (e.getPlugin().equals(plugin)) { - close(); - } - } - - public void addFilter(Class packetType, BiFunction filter) { - packetFilters.computeIfAbsent(packetType, c -> new ArrayList<>(1)).add(filter); - } - - public void removeFilter(Class packetType, BiFunction filter) { - packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter); - } - - public final void close() { - if(closed) - return; - closed = true; - - HandlerList.unregisterAll(this); - - for (Player player : plugin.getServer().getOnlinePlayers()) { - getInterceptor(player).ifPresent(PacketInterceptor::close); - } - } - - public Optional getInterceptor(Player player) { - synchronized (playerInterceptors) { - return Optional.ofNullable(playerInterceptors.get(player)); - } - } - - private static final FieldWrapper getChannel = ReflectionUtil.getField(networkManager, Channel.class, 0); - private static final FieldWrapper getUUID = ReflectionUtil.getField(networkManager, UUID.class, 0); - - public final class PacketInterceptor extends ChannelDuplexHandler { - private final Player player; - private final Channel channel; - - private PacketInterceptor(Player player) { - this.player = player; - - channel = getChannel.get(connections.stream().filter(connection -> player.getUniqueId().equals(getUUID.get(connection))).findAny().orElseThrow(() -> new SecurityException("Could not find channel for player " + player.getName()))); - - synchronized (playerInterceptors) { - playerInterceptors.put(player, this); - } - - channel.pipeline().addBefore("packet_handler", handlerName, this); - } - - private void sendPacket(Object packet) { - channel.pipeline().writeAndFlush(packet); - } - - private void receivePacket(Object packet) { - channel.pipeline().context("encoder").fireChannelRead(packet); - } - - public void close() { - if(channel.isActive()) { - channel.eventLoop().execute(() -> { - try { - channel.pipeline().remove(handlerName); - } catch (NoSuchElementException e) { - // ignore - } - }); - } - - synchronized (playerInterceptors) { - playerInterceptors.remove(player, this); - } - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - try { - msg = filterPacket(player, msg); - } catch (Exception e) { - plugin.getLogger().log(Level.SEVERE, "Error during incoming packet processing", e); - } - - if (msg != null) { - super.channelRead(ctx, msg); - } - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - try { - msg = filterPacket(player, msg); - } catch (Exception e) { - plugin.getLogger().log(Level.SEVERE, "Error during outgoing packet processing", e); - } - - if (msg != null) { - super.write(ctx, msg, promise); - } - } - - private Object filterPacket(Player player, Object packet) { - List> filters = packetFilters.getOrDefault(packet.getClass(), Collections.emptyList()); - - for(BiFunction filter : filters) { - packet = filter.apply(player, packet); - - if(packet == null) - break; - } - - return packet; - } - } -} diff --git a/bukkit/src/de/lixfel/altauth/bukkit/ServerIdInjector.java b/bukkit/src/de/lixfel/altauth/bukkit/ServerIdInjector.java new file mode 100644 index 0000000..7ca9e4f --- /dev/null +++ b/bukkit/src/de/lixfel/altauth/bukkit/ServerIdInjector.java @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT + +package de.lixfel.altauth.bukkit; + +import com.mojang.authlib.GameProfile; +import de.lixfel.ReflectionUtil; +import de.lixfel.ReflectionUtil.FieldWrapper; +import io.netty.channel.*; +import org.bukkit.plugin.Plugin; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +// ServerIdInjector heavily inspired by TinyProtocol +public class ServerIdInjector { + + private static final Class craftServer = ReflectionUtil.getClass("org.bukkit.craftbukkit.CraftServer"); + private static final Class dedicatedPlayerList = ReflectionUtil.getClass("net.minecraft.server.dedicated.DedicatedPlayerList"); + private static final FieldWrapper getPlayerList = ReflectionUtil.getField(craftServer, dedicatedPlayerList, 0); + private static final Class playerList = ReflectionUtil.getClass("net.minecraft.server.players.PlayerList"); + public static final Class minecraftServer = ReflectionUtil.getClass("net.minecraft.server.MinecraftServer"); + private static final FieldWrapper getMinecraftServer = ReflectionUtil.getField(playerList, minecraftServer, 0); + private static final Class serverConnection = ReflectionUtil.getClass("net.minecraft.server.network.ServerConnection"); + private static final FieldWrapper getServerConnection = ReflectionUtil.getField(minecraftServer, serverConnection, 0); + private static final FieldWrapper getChannelFutures = ReflectionUtil.getField(serverConnection, List.class, 0, ChannelFuture.class); + + private static final Class networkManager = ReflectionUtil.getClass("net.minecraft.network.NetworkManager"); + private static final Class packetListener = ReflectionUtil.getClass("net.minecraft.network.PacketListener"); + private static final FieldWrapper getPacketListener = ReflectionUtil.getField(networkManager, packetListener, 0); + + public static final Class loginListener = ReflectionUtil.getClass("net.minecraft.server.network.LoginListener"); + private static final FieldWrapper getGameProfile = ReflectionUtil.getField(loginListener, GameProfile.class, 0); + + private static final Class packetLoginInEncryptionBegin = ReflectionUtil.getClass("net.minecraft.network.protocol.login.PacketLoginInEncryptionBegin"); + private static final FieldWrapper getEncryptedSecret = ReflectionUtil.getField(packetLoginInEncryptionBegin, byte[].class, 0); + private static final Class packetLoginOutEncryptionBegin = ReflectionUtil.getClass("net.minecraft.network.protocol.login.PacketLoginOutEncryptionBegin"); + private static final FieldWrapper getPacketServerID = ReflectionUtil.getField(packetLoginOutEncryptionBegin, String.class, 0); + + private final String altAuthServer; + private final String handlerName; + private final String initializerName; + private final Object minecraftServerInstance; + private final List channelFutures; + + private final Map encryptedSecrets = new ConcurrentHashMap<>(); + + private boolean closed; + + private final ChannelInitializer initializer = new ChannelInitializer() { + @Override + protected void initChannel(Channel channel) { + if(!closed) + new PacketInterceptor(channel); + } + }; + + public ServerIdInjector(Plugin plugin, String altAuthServer) { + this.altAuthServer = altAuthServer; + this.handlerName = "altauth"; + this.initializerName = "altauth-init"; + this.minecraftServerInstance = getMinecraftServer.get(getPlayerList.get(plugin.getServer())); + this.channelFutures = getChannelFutures.get(getServerConnection.get(minecraftServerInstance)); + + for(ChannelFuture serverChannel : channelFutures) { + serverChannel.channel().pipeline().addFirst(initializerName, new ChannelInboundHandlerAdapter() { + @Override + public void channelRead(ChannelHandlerContext ctx, Object o) throws Exception { + super.channelRead(ctx, o); + + Channel channel = (Channel) o; + channel.pipeline().addLast(initializerName, initializer); + } + }); + } + } + + public Object minecraftServerInstance() { + return minecraftServerInstance; + } + + public byte[] getEncryptedSecret(String name) { + return encryptedSecrets.remove(name); + } + + public final void close() { + if(closed) + return; + closed = true; + + for(ChannelFuture serverChannel : channelFutures) { + serverChannel.channel().pipeline().remove(initializerName); + } + } + + public final class PacketInterceptor extends ChannelDuplexHandler { + private final Channel channel; + + private PacketInterceptor(Channel channel) { + this.channel = channel; + channel.pipeline().addBefore("packet_handler", handlerName, this); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { + if(packetLoginInEncryptionBegin.isInstance(packet)) { + encryptedSecrets.put( + getGameProfile.get(getPacketListener.get(channel.pipeline().get(networkManager))).getName(), + getEncryptedSecret.get(packet) + ); + channel.pipeline().remove(this); + } + + super.channelRead(ctx, packet); + } + + @Override + public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { + if(packetLoginOutEncryptionBegin.isInstance(packet)) { + getPacketServerID.set(packet, altAuthServer); + } + + super.write(ctx, packet, promise); + } + } +} diff --git a/bukkit/src/de/lixfel/altauth/bukkit/SessionServiceInjector.java b/bukkit/src/de/lixfel/altauth/bukkit/SessionServiceInjector.java deleted file mode 100644 index d88b3d0..0000000 --- a/bukkit/src/de/lixfel/altauth/bukkit/SessionServiceInjector.java +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT - -package de.lixfel.altauth.bukkit; - -import de.lixfel.ReflectionUtil; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.logging.Level; - -public class SessionServiceInjector { - - private static final Class MINECRAFT_SESSION_SERVICE = ReflectionUtil.getClass("com.mojang.authlib.minecraft.MinecraftSessionService"); - private static final Class YGGDRASIL_SESSION_SERVICE = ReflectionUtil.getClass("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService"); - - private static final ReflectionUtil.FieldWrapper JOIN_URL = ReflectionUtil.getField(YGGDRASIL_SESSION_SERVICE, URL.class, 0); - private static final ReflectionUtil.FieldWrapper CHECK_URL = ReflectionUtil.getField(YGGDRASIL_SESSION_SERVICE, URL.class, 1); - - private final Object sessionService; - private final URL joinUrlBackup; - private final URL checkUrlBackup; - - public SessionServiceInjector(String altAuthServer) { - altAuthServer = "https://" + altAuthServer + "/session/minecraft/"; - - if(ReflectionUtil.MINECRAFT_VERSION < 17) { //TODO maybe 16 (untested) - sessionService = null; - } else if (ReflectionUtil.MINECRAFT_VERSION < 19) { - sessionService = ReflectionUtil.getField(ProtocolInjector.minecraftServer, MINECRAFT_SESSION_SERVICE, 0).get( - ProtocolInjector.instance.minecraftServer() - ); - } else { - Class services = ReflectionUtil.getClass("net.minecraft.server.Services"); - sessionService = ReflectionUtil.getField(services, MINECRAFT_SESSION_SERVICE, 0).get( - ReflectionUtil.getField(ProtocolInjector.minecraftServer, services, 0).get( - ProtocolInjector.instance.minecraftServer() - ) - ); - } - - joinUrlBackup = JOIN_URL.get(sessionService); - checkUrlBackup = CHECK_URL.get(sessionService); - - try { - JOIN_URL.set(sessionService, new URL(altAuthServer + "join")); - CHECK_URL.set(sessionService, new URL(altAuthServer + "hasJoined")); - } catch (MalformedURLException e) { - AltAuthBukkit.getInstance().getLogger().log(Level.SEVERE, "Could not create AltAuth URLs", e); - } - } - - public void revert() { - JOIN_URL.set(sessionService, joinUrlBackup); - CHECK_URL.set(sessionService, checkUrlBackup); - } -}