From fad8151ca18354d61ac2f4b67f7760fb2e65e2ed Mon Sep 17 00:00:00 2001 From: creeper123123321 <7974274+creeper123123321@users.noreply.github.com> Date: Tue, 25 Aug 2020 09:35:40 -0300 Subject: [PATCH] Daemon thread, implement per server version fixes #45 and implements #34 --- .../viafabric/ProtocolViaFabricHostname.java | 53 +++++++++ .../creeper123123321/viafabric/ViaFabric.java | 2 +- .../viafabric/ViaFabricAddress.java | 102 ++++++++++++++++++ .../client/MixinClientConnectionChInit.java | 3 +- .../client/MixinConnectScreenThread.java | 50 +++++++++ .../mixin/client/MixinServerAddress.java | 56 ++++++++++ .../mixin/client/MixinServerPinger.java | 50 +++++++++ .../providers/VRVersionProvider.java | 9 +- src/main/resources/mixins.viafabric.json | 5 +- 9 files changed, 326 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/github/creeper123123321/viafabric/ProtocolViaFabricHostname.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/ViaFabricAddress.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinConnectScreenThread.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerAddress.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerPinger.java diff --git a/src/main/java/com/github/creeper123123321/viafabric/ProtocolViaFabricHostname.java b/src/main/java/com/github/creeper123123321/viafabric/ProtocolViaFabricHostname.java new file mode 100644 index 0000000..38a533d --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/ProtocolViaFabricHostname.java @@ -0,0 +1,53 @@ +/* + * MIT License + * + * Copyright (c) 2018- creeper123123321 + * Copyright (c) 2019- contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.creeper123123321.viafabric; + +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.protocol.SimpleProtocol; +import us.myles.ViaVersion.api.remapper.PacketRemapper; +import us.myles.ViaVersion.api.remapper.ValueTransformer; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.packets.State; + +public class ProtocolViaFabricHostname extends SimpleProtocol { + public static final ProtocolViaFabricHostname INSTANCE = new ProtocolViaFabricHostname(); + + @Override + protected void registerPackets() { + registerIncoming(State.HANDSHAKE, 0, 0, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); // Protocol version + map(Type.STRING, new ValueTransformer(Type.STRING) { + @Override + public String transform(PacketWrapper packetWrapper, String s) { + return new ViaFabricAddress().parse(s).realAddress; + } + }); + } + }); + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java b/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java index e8760b5..97b258d 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java +++ b/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java @@ -59,7 +59,7 @@ public class ViaFabric implements ModInitializer { public static VRConfig config; static { - ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("ViaFabric-%d").build(); + ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ViaFabric-%d").build(); ASYNC_EXECUTOR = Executors.newFixedThreadPool(8, factory); EVENT_LOOP = new DefaultEventLoop(factory); } diff --git a/src/main/java/com/github/creeper123123321/viafabric/ViaFabricAddress.java b/src/main/java/com/github/creeper123123321/viafabric/ViaFabricAddress.java new file mode 100644 index 0000000..92ff3ee --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/ViaFabricAddress.java @@ -0,0 +1,102 @@ +/* + * MIT License + * + * Copyright (c) 2018- creeper123123321 + * Copyright (c) 2019- contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.creeper123123321.viafabric; + +import us.myles.ViaVersion.api.protocol.ProtocolVersion; + +import java.util.Locale; + +public class ViaFabricAddress { + public int protocol = 0; + public String viaSuffix = null; + public String realAddress = null; + + public ViaFabricAddress parse(String address) { + if (address == null) return null; + String[] parts = address.split("\\."); + + boolean foundDomain = false; + boolean foundOptions = false; + + StringBuilder ourParts = new StringBuilder(); + StringBuilder realAddrBuilder = new StringBuilder(); + + for (int i = parts.length - 1; i >= 0; i--) { + String part = parts[i]; + boolean realAddrPart = false; + if (foundDomain) { + if (!foundOptions) { + if (part.startsWith("_")) { + String arg = part.substring(2); + if (part.toLowerCase(Locale.ROOT).startsWith("_v")) { + try { + protocol = Integer.parseInt(arg); + } catch (NumberFormatException e) { + ProtocolVersion closest = ProtocolVersion.getClosest(arg.replace("_", ".")); + if (closest != null) { + protocol = closest.getId(); + } + } + } + } else { + foundOptions = true; + } + } + if (foundOptions) { + realAddrPart = true; + } + } else if (part.equalsIgnoreCase("viafabric")) { + foundDomain = true; + } + if (realAddrPart) { + realAddrBuilder.insert(0, part + "."); + } else { + ourParts.insert(0, part + "."); + } + } + + String realAddr = realAddrBuilder.toString().replaceAll("\\.$", ""); + String suffix = ourParts.toString().replaceAll("\\.$", ""); + + if (realAddr.isEmpty()) { + this.realAddress = address; + } else { + this.realAddress = realAddr; + this.viaSuffix = suffix; + } + + return this; + } + + @Override + public String toString() { + return "ViaFabricAddress{" + + "protocol=" + protocol + + ", viaSuffix='" + viaSuffix + '\'' + + ", realAddress='" + realAddress + '\'' + + '}'; + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java index 0851b80..613c563 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java @@ -25,6 +25,7 @@ package com.github.creeper123123321.viafabric.mixin.client; +import com.github.creeper123123321.viafabric.ProtocolViaFabricHostname; import com.github.creeper123123321.viafabric.handler.CommonTransformer; import com.github.creeper123123321.viafabric.handler.clientside.VRDecodeHandler; import com.github.creeper123123321.viafabric.handler.clientside.VREncodeHandler; @@ -44,7 +45,7 @@ public class MixinClientConnectionChInit { private void onInitChannel(Channel channel, CallbackInfo ci) { if (channel instanceof SocketChannel) { UserConnection user = new VRClientSideUserConnection(channel); - new ProtocolPipeline(user); + new ProtocolPipeline(user).add(ProtocolViaFabricHostname.INSTANCE); channel.pipeline().addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new VREncodeHandler(user)); channel.pipeline().addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new VRDecodeHandler(user)); diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinConnectScreenThread.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinConnectScreenThread.java new file mode 100644 index 0000000..896dcd3 --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinConnectScreenThread.java @@ -0,0 +1,50 @@ +/* + * MIT License + * + * Copyright (c) 2018- creeper123123321 + * Copyright (c) 2019- contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.creeper123123321.viafabric.mixin.client; + +import com.github.creeper123123321.viafabric.ViaFabricAddress; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +@Mixin(targets = "net/minecraft/client/gui/screen/ConnectScreen$1", priority = 2000) // don't know if it will work with MinerParty mod +public class MixinConnectScreenThread { + @Redirect(method = "run", at = @At(value = "INVOKE", + target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;")) + private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException { + ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address); + if (viaAddr.viaSuffix == null) { + return InetAddress.getByName(address); + } + + InetAddress resolved = InetAddress.getByName(viaAddr.realAddress); + return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.viaSuffix, resolved.getAddress()); + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerAddress.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerAddress.java new file mode 100644 index 0000000..e2a13e9 --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerAddress.java @@ -0,0 +1,56 @@ +/* + * MIT License + * + * Copyright (c) 2018- creeper123123321 + * Copyright (c) 2019- contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.creeper123123321.viafabric.mixin.client; + +import com.github.creeper123123321.viafabric.ViaFabricAddress; +import net.minecraft.network.ServerAddress; +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; + +import java.util.Arrays; + +@Mixin(ServerAddress.class) +public class MixinServerAddress { + @Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveSrv(Ljava/lang/String;)[Ljava/lang/String;")) + private static String[] modifySrvAddr(String address) { + ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address); + if (viaAddr.viaSuffix == null) { + return resolveSrv(address); + } + + String[] resolvedSrv = resolveSrv(viaAddr.realAddress); + resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.viaSuffix; + + return resolvedSrv; + } + + @Shadow + private static String[] resolveSrv(String address) { + throw new IllegalStateException(); + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerPinger.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerPinger.java new file mode 100644 index 0000000..707129a --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinServerPinger.java @@ -0,0 +1,50 @@ +/* + * MIT License + * + * Copyright (c) 2018- creeper123123321 + * Copyright (c) 2019- contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.github.creeper123123321.viafabric.mixin.client; + +import com.github.creeper123123321.viafabric.ViaFabricAddress; +import net.minecraft.client.network.MultiplayerServerListPinger; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +@Mixin(MultiplayerServerListPinger.class) +public class MixinServerPinger { + @Redirect(method = "add", at = @At(value = "INVOKE", + target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;")) + private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException { + ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address); + if (viaAddr.viaSuffix == null) { + return InetAddress.getByName(address); + } + + InetAddress resolved = InetAddress.getByName(viaAddr.realAddress); + return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.viaSuffix, resolved.getAddress()); + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java b/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java index 0126398..e1311cf 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java +++ b/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java @@ -26,6 +26,7 @@ package com.github.creeper123123321.viafabric.providers; import com.github.creeper123123321.viafabric.ViaFabric; +import com.github.creeper123123321.viafabric.ViaFabricAddress; import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; import com.google.common.primitives.Ints; import net.fabricmc.loader.api.FabricLoader; @@ -83,11 +84,17 @@ public class VRVersionProvider extends VersionProvider { public int getServerProtocol(UserConnection connection) throws Exception { if (connection instanceof VRClientSideUserConnection) { int clientSideVersion = ViaFabric.config.getClientSideVersion(); + SocketAddress addr = connection.getChannel().remoteAddress(); + + if (addr instanceof InetSocketAddress && ViaFabric.config.isClientSideEnabled()) { + int addrVersion = new ViaFabricAddress().parse(((InetSocketAddress) addr).getHostName()).protocol; + if (addrVersion != 0) clientSideVersion = addrVersion; + } + boolean blocked = false; if (connection.getChannel() != null) { ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo()); - SocketAddress addr = connection.getChannel().remoteAddress(); if (addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) || ((((InetSocketAddress) addr).getAddress() != null) && (isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress()) diff --git a/src/main/resources/mixins.viafabric.json b/src/main/resources/mixins.viafabric.json index b104f0a..dea369c 100644 --- a/src/main/resources/mixins.viafabric.json +++ b/src/main/resources/mixins.viafabric.json @@ -9,8 +9,11 @@ "client": [ "client.MixinClientConnectionAccessor", "client.MixinClientConnectionChInit", + "client.MixinConnectScreenThread", "client.MixinDebugHud", - "client.MixinMultiplayerScreen" + "client.MixinMultiplayerScreen", + "client.MixinServerAddress", + "client.MixinServerPinger" ], "injectors": { "defaultRequire": 1