Rewrite AddressParser

- Port support
- Prefix support to allow IPv6 usage in modern versions
This commit is contained in:
Ampflower 🌺 2024-08-18 19:56:02 -07:00
parent a5c47ec762
commit 6d2620520e
No known key found for this signature in database
GPG Key ID: FC0397C90D508D7F
45 changed files with 1123 additions and 251 deletions

View File

@ -142,6 +142,8 @@ dependencies {
includeJ8("com.viaversion:viaversion:${rootProject.viaver_version}")
include("com.github.TinfoilMC:ClientCommands:1.1.0")
testImplementation("org.testng:testng:6.13.1")
}
remapJar {
@ -169,6 +171,11 @@ processResources {
}
}
test {
// Minimal insurance to make sure we get expected results.
useTestNG()
}
List<String> mcReleases = Arrays.stream(rootProject.publish_mc_versions.toString().split(","))
.map({ it -> it.trim() })
.collect(Collectors.toList())

View File

@ -20,85 +20,286 @@ package com.viaversion.fabric.common;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.libs.fastutil.ints.IntArrayList;
import com.viaversion.viaversion.libs.fastutil.ints.IntImmutableList;
import com.viaversion.viaversion.libs.fastutil.ints.IntList;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
// Based on VIAaaS parser
public class AddressParser {
public Integer protocol;
public String viaSuffix;
public String serverAddress;
public String viaOptions;
private static final String VIA = "viafabric";
private static final Pattern DOT_SUFFIX = Pattern.compile("\\.$");
public AddressParser parse(String address) {
return parse(address, "viafabric");
// Retaining a list for now; not exposing it to the end consumer.
// An idea tossed about is to retry the server for the given protocols.
@Nullable
@VisibleForTesting
final IntList protocols;
@NotNull
private final String serverAddress;
@Nullable
private final Integer port;
private AddressParser(@NotNull String address, @Nullable Integer port) {
this(address, null, port);
}
public String getSuffixWithOptions() {
if (viaOptions != null && !viaOptions.isEmpty()) {
return viaOptions + "." + viaSuffix;
private AddressParser(@NotNull String address, @Nullable IntList protocols, @Nullable Integer port) {
this.serverAddress = address;
this.port = port;
this.protocols = protocols;
}
@NotNull
public static AddressParser parse(String address) {
return parse(address, VIA);
}
@NotNull
private static AddressParser parse(String address, String viaHostName) {
int portIndex = address.lastIndexOf(':');
Integer port = portIndex >= 0 ? Ints.tryParse(address.substring(portIndex + 1)) : null;
if (port != null && port >= 0 && port < 65536) {
if (address.charAt(portIndex - 1) == '.') {
// Let's not allocate an intermediate string.
portIndex -= 1;
} else if (port < 10000 &&
// I don't like this but there's not really a better way of doing this
address.lastIndexOf(':', portIndex - 1) > Math.max(
address.lastIndexOf(']', portIndex - 1),
address.lastIndexOf('.', portIndex - 1)
)) {
// We parsed an IPv6, a port isn't ideal here.
port = null;
}
// Keeping a sane flow control.
if (port != null) {
// Truncate the port off, as that interferes.
address = address.substring(0, portIndex);
}
}
return viaSuffix;
}
public AddressParser parse(String address, String viaHostName) {
address = StringUtils.removeEnd(address, ".");
String suffixRemoved = StringUtils.removeEnd(address, "." + viaHostName);
if (suffixRemoved.equals(address)) {
serverAddress = address;
return this;
String truncated = StringUtils.removeEnd(address, '.' + viaHostName);
if (!address.equals(truncated)) {
return parseSuffix(truncated, port);
}
truncated = StringUtils.removeStart(address, viaHostName + '.');
if (!address.equals(truncated)) {
final AddressParser addr = parsePrefix(truncated, port);
if (addr != null) {
return addr;
}
}
return new AddressParser(address, port);
}
@NotNull
private static AddressParser parseSuffix(String address, Integer port) {
boolean stopOptions = false;
List<String> optionsParts = new ArrayList<>();
IntList protocolParts = new IntArrayList();
List<String> serverParts = new ArrayList<>();
for (String part : Lists.reverse(Arrays.asList(suffixRemoved.split(Pattern.quote("."))))) {
if (!stopOptions && parseOption(part)) {
optionsParts.add(part);
Integer protocol;
for (String part : Lists.reverse(Arrays.asList(address.split("\\.")))) {
if (!stopOptions && (protocol = parseSuffixOption(part)) != null) {
protocolParts.add(protocol.intValue());
continue;
}
stopOptions = true;
serverParts.add(part);
}
serverAddress = String.join(".", Lists.reverse(serverParts));
viaOptions = String.join(".", Lists.reverse(optionsParts));
viaSuffix = viaHostName;
return this;
return new AddressParser(
String.join(".", Lists.reverse(serverParts)),
new IntImmutableList(Lists.reverse(protocolParts)),
port
);
}
public boolean parseOption(String part) {
// Fail condition = returns null; caller must fall through.
@Nullable
private static AddressParser parsePrefix(String address, Integer port) {
IntList protocols = new IntArrayList();
int index = 0, lastIndex, colonIndex = address.indexOf(';');
if (colonIndex < 0) {
return null;
}
while ((index = address.indexOf('+', lastIndex = index)) >= 0 && index < colonIndex) {
parseAndAdd(address.substring(lastIndex, index), protocols);
index++;
}
parseAndAdd(address.substring(lastIndex, colonIndex), protocols);
return new AddressParser(
address.substring(colonIndex + 1),
new IntImmutableList(protocols),
port
);
}
private static void parseAndAdd(String part, IntList protocols) {
final Integer protocol = parseSchemeOption(part);
if (protocol != null) {
protocols.add(protocol.intValue());
}
}
public String getSuffixWithOptions() {
if (protocols == null) {
return "";
}
if (protocols.isEmpty()) {
return VIA;
}
return protocols.intStream()
.mapToObj(AddressParser::toProtocolName)
.map(str -> str.replace('.', '_'))
.collect(Collectors.joining("._v", "_v", "." + VIA));
}
public String getPrefixWithOptions() {
if (protocols == null) {
return "";
}
if (protocols.isEmpty()) {
return VIA;
}
return protocols.intStream()
.mapToObj(AddressParser::toProtocolName)
.collect(Collectors.joining("+v", VIA + ".v", ""));
}
public boolean hasViaMetadata() {
return protocols != null;
}
public boolean hasProtocol() {
return protocols != null && !protocols.isEmpty();
}
public Integer protocol() {
if (protocols != null && !protocols.isEmpty()) {
return protocols.getInt(0);
}
return null;
}
@NotNull
public String serverAddress() {
return this.serverAddress;
}
@Nullable
public Integer port() {
return this.port;
}
public String toAddress() {
if (port != null) {
return serverAddress + ':' + port;
}
return serverAddress;
}
public String toSuffixedViaAddress() {
final String address = addAddressSuffix(serverAddress);
if (port != null) {
return address + ':' + port;
}
return address;
}
public InetAddress resolve() throws UnknownHostException {
return this.addAddressSuffix(InetAddress.getByName(serverAddress));
}
public InetSocketAddress addAddressSuffix(InetSocketAddress address) throws UnknownHostException {
return new InetSocketAddress(addAddressSuffix(address.getAddress()), address.getPort());
}
public InetAddress addAddressSuffix(InetAddress address) throws UnknownHostException {
return InetAddress.getByAddress(addAddressSuffix(address.getHostName()), address.getAddress());
}
public String addAddressSuffix(String input) {
if (!this.hasViaMetadata()) {
return input;
}
return DOT_SUFFIX.matcher(input).replaceAll("") + '.' + this.getSuffixWithOptions();
}
private static Integer parseSuffixOption(String part) {
String option;
if (part.length() < 2) {
return false;
return null;
} else if (part.startsWith("_")) {
option = String.valueOf(part.charAt(1));
} else if (part.charAt(1) == '_') {
option = String.valueOf(part.charAt(0));
} else {
return false;
return null;
}
String arg = part.substring(2);
if ("v".equals(option)) {
parseProtocol(arg);
return parseProtocol(arg);
}
return true;
return null;
}
public void parseProtocol(String arg) {
protocol = Ints.tryParse(arg);
if (protocol == null) {
ProtocolVersion ver = ProtocolVersion.getClosest(arg.replace("_", "."));
if (ver != null) protocol = ver.getVersion();
private static Integer parseSchemeOption(String part) {
if (part.length() < 2) {
return null;
}
if (!part.startsWith("v")) {
return null;
}
return parseProtocol(part.substring(1));
}
private static Integer parseProtocol(String arg) {
final Integer protocol = Ints.tryParse(arg);
if (protocol != null) {
return protocol;
}
ProtocolVersion ver = ProtocolVersion.getClosest(arg.replace('_', '.'));
if (ver != null) {
return ver.getVersion();
}
return null;
}
private static String toProtocolName(int protocol) {
if (protocol < 0 || !ProtocolVersion.isRegistered(protocol)) {
return Integer.toString(protocol);
}
return ProtocolVersion.getProtocol(protocol).getIncludedVersions().iterator().next();
}
@Override
public String toString() {
return "AddressParser{" + this.toSuffixedViaAddress() + '}';
}
}

View File

@ -20,10 +20,9 @@ package com.viaversion.fabric.common.protocol;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.viaversion.api.protocol.AbstractSimpleProtocol;
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.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.base.ServerboundHandshakePackets;
@ -39,7 +38,7 @@ public class HostnameParserProtocol extends AbstractSimpleProtocol {
map(Types.STRING, new ValueTransformer<String, String>(Types.STRING) {
@Override
public String transform(PacketWrapper packetWrapper, String s) {
return new AddressParser().parse(s).serverAddress;
return AddressParser.parse(s).serverAddress();
}
});
}

View File

@ -28,7 +28,6 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.protocol.version.BaseVersionProvider;
@ -42,7 +41,11 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
import java.util.stream.IntStream;
@ -93,8 +96,8 @@ public abstract class AbstractFabricVersionProvider extends BaseVersionProvider
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
AddressParser parser = new AddressParser();
Integer addrVersion = parser.parse(((InetSocketAddress) addr).getHostName()).protocol;
AddressParser parser = AddressParser.parse(((InetSocketAddress) addr).getHostName());
Integer addrVersion = parser.protocol();
if (addrVersion != null) {
serverVer = addrVersion;
}

View File

@ -0,0 +1,253 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.common;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.libs.fastutil.ints.IntArrayList;
import com.viaversion.viaversion.libs.fastutil.ints.IntList;
import org.jetbrains.annotations.CheckReturnValue;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
/**
* Tests AddressParser's capability to parse addresses into a useful form,
* extracting Via metadata and providing addresses Minecraft and Guava can parse.
* <p>
* Test cases include seemingly malformed data that previous versions of ViaFabric
* would accept as valid, and asserting that it would parse and treat it the same way.
*
* @author Ampflower
**/
public class AddressParserTest {
private static IntList of(ProtocolVersion... versions) {
return Arrays.stream(versions).mapToInt(ProtocolVersion::getVersion)
.collect(IntArrayList::new, IntList::add, IntList::addAll);
}
/**
* Ensures that:
* <ul>
* <li>{@link AddressParser#hasViaMetadata()} returns true, as via metadata is provided.</li>
* <li>{@link AddressParser#hasProtocol()} returns false when {@code versions} is empty, true otherwise.</li>
* <li>{@link AddressParser#protocols} returns all parsed protocols and matches {@code versions}</li>
* <li>{@link AddressParser#protocol()} matches the first protocol listed. Subject to change.</li>
* </ul>
*/
@Test(dataProvider = "viaAddrProvider", timeOut = 1000L)
public void viaAddrHarness(String rawAddress, String address, Integer port, ProtocolVersion... versions) {
final AddressParser viaAddr = AddressParser.parse(rawAddress);
assertFundamentals(viaAddr, address, port);
assertTrue(viaAddr.hasViaMetadata(), "hasViaMetadata");
// Tests protocol parsing to ensure it is returning expected values.
assertEquals(viaAddr.protocols, of(versions));
if (versions.length == 0) {
assertFalse(viaAddr.hasProtocol(), "hasProtocol");
assertNull(viaAddr.protocol());
} else {
assertTrue(viaAddr.hasProtocol(), "hasProtocol");
assertNotNull(viaAddr.protocol(), "protocol");
assertEquals((int) viaAddr.protocol(), versions[0].getVersion());
}
}
/**
* Ensures that:
* <ul>
* <li>{@link AddressParser#hasViaMetadata()} returns false, as via metadata is <em>not</em> provided.</li>
* <li>{@link AddressParser#hasProtocol()} returns false.</li>
* <li>{@link AddressParser#protocols} is null. Subject to change.</li>
* <li>{@link AddressParser#protocol()} is null.</li>
* </ul>
*/
@Test(dataProvider = "addrProvider", timeOut = 1000L)
public void addrHarness(String rawAddress, String address, Integer port) {
final AddressParser viaAddr = AddressParser.parse(rawAddress);
assertFundamentals(viaAddr, address, port);
assertFalse(viaAddr.hasViaMetadata(), "hasViaMetadata");
assertFalse(viaAddr.hasProtocol(), "hasProtocol");
assertNull(viaAddr.protocols, "protocols");
assertNull(viaAddr.protocol(), "protocol");
}
/**
* Ensures that:
* <ul>
* <li>{@link AddressParser#serverAddress()} is the address valid for DNS, matching {@code address}</li>
* <li>{@link AddressParser#port()} is a valid port matching {@code port}, should there be one declared.</li>
* <li>{@link AddressParser#toAddress()} matches the expected address <em>without</em> Via metadata.</li>
* </ul>
*/
private static void assertFundamentals(AddressParser viaAddr, String address, Integer port) {
assertEquals(viaAddr.serverAddress(), address);
assertEquals(viaAddr.port(), port);
// Tests toAddress to ensure it is returning the port as expected for Minecraft's parser.
if (port == null) {
assertEquals(viaAddr.toAddress(), address);
} else {
assertEquals(viaAddr.toAddress(), address + ':' + port);
}
}
@CheckReturnValue
private static Object[] params(String address, String expected, Integer port, ProtocolVersion... versions) {
return new Object[]{address, expected, port, versions};
}
@DataProvider
public static Object[][] viaAddrProvider() {
// NOTE: Before touching values in here, consider making sure that the parser is functioning as expected.
// If the semantic change is expected, carry on. Otherwise, fix the parser, not the test.
return new Object[][]{
// == Suffixes ==
params("[::]._v1_8.viafabric", "[::]", null,
ProtocolVersion.v1_8),
params("localhost._v1_7_2._v1_16_5.viafabric", "localhost", null,
ProtocolVersion.v1_7_2, ProtocolVersion.v1_16_4),
params("0.0.0.0._v1_8._v1_9.v_1_21.viafabric", "0.0.0.0", null,
ProtocolVersion.v1_8, ProtocolVersion.v1_9, ProtocolVersion.v1_21),
params("[::1]._v-2.viafabric", "[::1]", null,
ProtocolVersion.getProtocol(-2)),
params("127.0.0.1.viafabric", "127.0.0.1", null),
// Ports
params("[::].v_1_8.viafabric:25565", "[::]", 25565,
ProtocolVersion.v1_8),
params("0.0.0.0.v_-2.viafabric:53", "0.0.0.0", 53,
ProtocolVersion.getProtocol(-2)),
params("localhost.viafabric:853", "localhost", 853),
// IPv6
params("[fe80::1]._v-2.viafabric:8192", "[fe80::1]", 8192,
ProtocolVersion.getProtocol(-2)),
params("::.v_-2.viafabric", "::", null,
ProtocolVersion.getProtocol(-2)),
params("fe80::1._v-2.viafabric", "fe80::1", null,
ProtocolVersion.getProtocol(-2)),
// == Prefixes ==
params("viafabric.v1.8;[::]", "[::]", null,
ProtocolVersion.v1_8),
params("viafabric.v1.7.2+v1.16.5;localhost", "localhost", null,
ProtocolVersion.v1_7_2, ProtocolVersion.v1_16_4),
params("viafabric.v1.8+v1.9+v1.21;0.0.0.0", "0.0.0.0", null,
ProtocolVersion.v1_8, ProtocolVersion.v1_9, ProtocolVersion.v1_21),
params("viafabric.v-2;[::1]", "[::1]", null,
ProtocolVersion.getProtocol(-2)),
// Ports
params("viafabric.v1.8;[::]:25565", "[::]", 25565,
ProtocolVersion.v1_8),
params("viafabric.v-2;0.0.0.0:53", "0.0.0.0", 53,
ProtocolVersion.getProtocol(-2)),
params("viafabric.;localhost.:853", "localhost", 853),
// IPv6
params("viafabric.v-2;[fe80::1]:8192", "[fe80::1]", 8192,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;::", "::", null,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;fe80::1", "fe80::1", null,
ProtocolVersion.getProtocol(-2)),
// == Malformed ==
params("viafabric.v-2;[::]+:25565", "[::]+", 25565,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;0.0.0.0+:25565", "0.0.0.0+", 25565,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;localhost+:25565", "localhost+", 25565,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;[::]+", "[::]+", null,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;0.0.0.0+", "0.0.0.0+", null,
ProtocolVersion.getProtocol(-2)),
params("viafabric.v-2;localhost+", "localhost+", null,
ProtocolVersion.getProtocol(-2)),
};
}
@CheckReturnValue
private static Object[] addrParams(String address, String expected, Integer port) {
return new Object[]{address, expected, port};
}
@DataProvider
public static Object[][] addrProvider() {
return new Object[][]{
// Port
addrParams("[::]:25565", "[::]", 25565),
addrParams("[fe80::1]:25565", "[fe80::1]", 25565),
addrParams("localhost:53", "localhost", 53),
addrParams("0.0.0.0:853", "0.0.0.0", 853),
// No port
addrParams("[::1]", "[::1]", null),
addrParams("[fe80::1]", "[fe80::1]", null),
addrParams("localhost.", "localhost", null),
addrParams("127.0.0.1", "127.0.0.1", null),
// IPv6
addrParams("::", "::", null),
addrParams("fe80::1", "fe80::1", null),
// Malformed
addrParams("viafabric.v-2:[::]:25565", "viafabric.v-2:[::]", 25565),
addrParams("viafabric.v-2:0.0.0.0:25565", "viafabric.v-2:0.0.0.0", 25565),
addrParams("viafabric.v-2:localhost:25565", "viafabric.v-2:localhost", 25565),
addrParams("viafabric.v-2:[::]", "viafabric.v-2:[::]", null),
addrParams("viafabric.v-2:0.0.0.0", "viafabric.v-2:0.0.0.0", null),
addrParams("viafabric.v-2:localhost", "viafabric.v-2:localhost", null),
addrParams("viafabric.v-2:[::]+:25565", "viafabric.v-2:[::]+", 25565),
addrParams("viafabric.v-2:0.0.0.0+:25565", "viafabric.v-2:0.0.0.0+", 25565),
addrParams("viafabric.v-2:localhost+:25565", "viafabric.v-2:localhost+", 25565),
addrParams("viafabric.v-2:[::]+", "viafabric.v-2:[::]+", null),
addrParams("viafabric.v-2:0.0.0.0+", "viafabric.v-2:0.0.0.0+", null),
addrParams("viafabric.v-2:localhost+", "viafabric.v-2:localhost+", null),
};
}
}

View File

@ -29,13 +29,12 @@ import java.net.UnknownHostException;
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,30 +17,31 @@
*/
package com.viaversion.fabric.mc1144.mixin.address.client;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
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 org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static String[] resolveSrv(String address) {
throw new AssertionError();
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@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) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveSrv(address);
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;<init>(Ljava/lang/String;I)V"))
private static String injectViaMetadata(String original, int port, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
String[] resolvedSrv = resolveSrv(viaAddr.serverAddress);
resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions();
return resolvedSrv;
return parser.addAddressSuffix(original);
}
}

View File

@ -30,13 +30,12 @@ import java.net.UnknownHostException;
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 {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1144.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1144.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -37,7 +48,6 @@ import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -131,7 +141,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -29,13 +29,12 @@ import java.net.UnknownHostException;
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,30 +17,31 @@
*/
package com.viaversion.fabric.mc1152.mixin.address.client;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
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 org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static String[] resolveSrv(String address) {
throw new AssertionError();
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@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) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveSrv(address);
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;<init>(Ljava/lang/String;I)V"))
private static String injectViaMetadata(String original, int port, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
String[] resolvedSrv = resolveSrv(viaAddr.serverAddress);
resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions();
return resolvedSrv;
return parser.addAddressSuffix(original);
}
}

View File

@ -30,13 +30,12 @@ import java.net.UnknownHostException;
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 {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1152.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1152.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -37,7 +48,6 @@ import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -131,7 +141,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -29,13 +29,12 @@ import java.net.UnknownHostException;
public class MixinConnectScreenThread {
@Redirect(method = "run()V", at = @At(value = "INVOKE",
target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,28 +17,31 @@
*/
package com.viaversion.fabric.mc1165.mixin.address.client;
import com.mojang.datafixers.util.Pair;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.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 org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static Pair<String, Integer> resolveServer(String address) {
throw new AssertionError();
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;resolveServer(Ljava/lang/String;)Lcom/mojang/datafixers/util/Pair;"))
private static Pair<String, Integer> modifySrvAddr(String address) {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveServer(address);
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Ljava/lang/String;I)V"))
private static String injectViaMetadata(String original, int port, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return resolveServer(viaAddr.serverAddress).mapFirst(it -> it.replaceAll("\\.$", "") + "." + viaAddr.getSuffixWithOptions());
return parser.addAddressSuffix(original);
}
}

View File

@ -30,13 +30,12 @@ import java.net.UnknownHostException;
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 {
AddressParser viaAddr = new AddressParser().parse(address);
if (viaAddr.viaSuffix == null) {
private static InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
AddressParser viaAddr = AddressParser.parse(address);
if (!viaAddr.hasViaMetadata()) {
return InetAddress.getByName(address);
}
InetAddress resolved = InetAddress.getByName(viaAddr.serverAddress);
return InetAddress.getByAddress(resolved.getHostName() + "." + viaAddr.getSuffixWithOptions(), resolved.getAddress());
return viaAddr.resolve();
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1165.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1165.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -37,7 +48,6 @@ import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -131,7 +141,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1171.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1171.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1171.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1171.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -37,7 +48,6 @@ import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -131,7 +141,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1182.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1182.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1182.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1182.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -37,7 +48,6 @@ import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -131,7 +141,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1194.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1194.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1194.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1194.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -36,7 +47,6 @@ import net.minecraft.network.packet.s2c.query.QueryPongS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -130,7 +140,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1201.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,18 +17,29 @@
*/
package com.viaversion.fabric.mc1201.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1201.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1201.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.network.SizePrepender;
import net.minecraft.network.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
@ -36,7 +47,6 @@ import net.minecraft.network.packet.s2c.query.QueryPongS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -130,7 +140,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1204.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,19 +17,26 @@
*/
package com.viaversion.fabric.mc1204.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1204.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1204.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.SharedConstants;
import net.minecraft.network.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.handler.DecoderHandler;
import net.minecraft.network.handler.PacketEncoder;
import net.minecraft.network.handler.SizePrepender;
@ -42,7 +49,7 @@ import net.minecraft.network.packet.s2c.query.PingResultS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.jetbrains.annotations.NotNull;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -51,7 +58,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.jetbrains.annotations.NotNull;
@Environment(EnvType.CLIENT)
public class ProtocolAutoDetector {
@ -149,7 +155,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc1206.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -17,20 +17,29 @@
*/
package com.viaversion.fabric.mc1206.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1206.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1206.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.SharedConstants;
import net.minecraft.network.*;
import net.minecraft.network.handler.*;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.handler.EncoderHandler;
import net.minecraft.network.handler.NetworkStateTransitions;
import net.minecraft.network.handler.SizePrepender;
import net.minecraft.network.handler.SplitterHandler;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.ConnectionIntent;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
@ -41,7 +50,7 @@ import net.minecraft.network.state.HandshakeStates;
import net.minecraft.network.state.QueryStates;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.jetbrains.annotations.NotNull;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@ -50,7 +59,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.jetbrains.annotations.NotNull;
@Environment(EnvType.CLIENT)
public class ProtocolAutoDetector {
@ -144,7 +152,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0

View File

@ -28,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@ -40,22 +38,20 @@ public abstract class MixinAllowedAddressResolver {
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
AddressParser viaAddr = AddressParser.parse(address.getAddress());
if (!viaAddr.hasViaMetadata()) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress(), address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr.getSuffixWithOptions())));
cir.setReturnValue(resolve(realAddress).map(it -> viaFabric$addSuffix(it, viaAddr)));
}
@Unique
private Address viaFabric$addSuffix(Address it, String viaSuffix) {
private static Address viaFabric$addSuffix(Address it, AddressParser viaAddr) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
return Address.create(viaAddr.addAddressSuffix(it.getInetSocketAddress()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ViaFabric - https://github.com/ViaVersion/ViaFabric
* Copyright (C) 2018-2024 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.fabric.mc121.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@ModifyVariable(method = "parse", at = @At("HEAD"), argsOnly = true)
private static String modifyAddress(String address, @Share("via") LocalRef<AddressParser> via) {
AddressParser parser = AddressParser.parse(address);
via.set(parser);
return parser.toAddress();
}
@ModifyArg(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;<init>(Lcom/google/common/net/HostAndPort;)V"))
private static HostAndPort injectViaMetadata(HostAndPort original, @Share("via") LocalRef<AddressParser> via) {
final AddressParser parser = via.get();
if (parser == null) {
return original;
}
return HostAndPort.fromParts(parser.addAddressSuffix(original.getHost()), original.getPort());
}
}

View File

@ -24,7 +24,11 @@ import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc1211.ViaFabric;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
@ -149,7 +153,7 @@ public class ProtocolAutoDetector {
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
(AddressParser.parse(address.getHostString()).serverAddress(),
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {

View File

@ -5,7 +5,8 @@
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
"client.MixinAllowedAddressResolver",
"client.MixinServerAddress"
],
"injectors": {
"defaultRequire": 0