update 1.17 snapshot, cleanup VersionProvider

This commit is contained in:
creeper123123321 2021-05-13 21:05:30 -03:00
parent 4bbd683382
commit 105e64b11a
19 changed files with 318 additions and 863 deletions

View File

@ -10,14 +10,11 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout repository - uses: actions/checkout@v2
uses: actions/checkout@v2 - uses: actions/setup-java@v1
- name: setup jdk 11
uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 16
- name: Cache - uses: actions/cache@v2
uses: actions/cache@v2
with: with:
path: ~/.gradle/ path: ~/.gradle/
key: ${{ runner.os }}-via-cache key: ${{ runner.os }}-via-cache
@ -25,8 +22,7 @@ jobs:
env: env:
CURSEFORGE_API_KEY: ${{ secrets.CREEPER_CF }} CURSEFORGE_API_KEY: ${{ secrets.CREEPER_CF }}
run: ./gradlew run: ./gradlew
- name: capture build artifacts - uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v2
with: with:
name: Artifacts name: Artifacts
path: build/libs/ path: build/libs/

View File

@ -1,8 +1,10 @@
import org.apache.tools.ant.filters.ReplaceTokens
// Stolen https://github.com/FabricMC/fabric/blob/1.17/build.gradle // Stolen https://github.com/FabricMC/fabric/blob/1.17/build.gradle
plugins { plugins {
id "java" id "java"
id "maven-publish" id "maven-publish"
id "fabric-loom" version "0.7-SNAPSHOT" apply false id "fabric-loom" version "0.8-SNAPSHOT" apply false
id "org.ajoberstar.grgit" version "3.1.1" id "org.ajoberstar.grgit" version "3.1.1"
id "com.matthewprenger.cursegradle" version "1.4.0" id "com.matthewprenger.cursegradle" version "1.4.0"
} }
@ -11,8 +13,8 @@ def ENV = System.getenv()
def vvVer = "4.0.0-21w19a" def vvVer = "4.0.0-21w19a"
description = "Client-side and server-side ViaVersion implementation for Fabric" description = "Client-side and server-side ViaVersion implementation for Fabric"
version = "0.4.0" + "+" + ENV.GITHUB_RUN_NUMBER + "-" + getBranch() version = "0.4.0+" + ENV.GITHUB_RUN_NUMBER + "-" + getBranch()
logger.lifecycle("Building ViaFabric: " + version) logger.lifecycle("Building ViaFabric: $version")
def getBranch() { def getBranch() {
def ENV = System.getenv() def ENV = System.getenv()
@ -85,7 +87,7 @@ allprojects {
processResources { processResources {
filesMatching("fabric.mod.json") { filesMatching("fabric.mod.json") {
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [ filter(ReplaceTokens, tokens: [
version : rootProject.version, version : rootProject.version,
description: rootProject.description description: rootProject.description
]) ])
@ -196,7 +198,6 @@ dependencies {
include("org.yaml:snakeyaml:1.28") include("org.yaml:snakeyaml:1.28")
subprojects.each { subprojects.each {
//implementation project(path: ":${it.name}", configuration: "dev")
include project("${it.name}:") include project("${it.name}:")
} }
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -0,0 +1,174 @@
package com.viaversion.fabric.common.provider;
import com.google.common.primitives.Ints;
import com.viaversion.fabric.common.VFAddressParser;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
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.exception.CancelException;
import com.viaversion.viaversion.protocols.base.BaseProtocol1_16;
import com.viaversion.viaversion.protocols.base.BaseProtocol1_7;
import com.viaversion.viaversion.protocols.base.BaseVersionProvider;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
import java.util.stream.IntStream;
public abstract class VFVersionProvider extends BaseVersionProvider {
private int[] multiconnectSupportedVersions = null;
{
try {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) {
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
getLogger().info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
}
@Override
public int getClosestServerProtocol(UserConnection connection) throws Exception {
if (connection.isClientSide()) {
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!getConfig().isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = getConfig().getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
getLogger().warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
}
private boolean checkAddressBlocked(SocketAddress addr) {
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString())
|| ((((InetSocketAddress) addr).getAddress() != null) &&
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
getLogger().info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
getLogger().severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (getConfig().isForcedDisable(query)) {
getLogger().info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
}
protected abstract Logger getLogger();
protected abstract VFConfig getConfig();
protected abstract CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address);
}

View File

@ -1,166 +1,28 @@
package com.viaversion.fabric.mc114.providers; package com.viaversion.fabric.mc114.providers;
import com.viaversion.fabric.common.VFAddressParser; import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.VFVersionProvider;
import com.viaversion.fabric.mc114.ViaFabric; import com.viaversion.fabric.mc114.ViaFabric;
import com.viaversion.fabric.mc114.service.ProtocolAutoDetector; import com.viaversion.fabric.mc114.service.ProtocolAutoDetector;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.google.common.primitives.Ints;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.base.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.util.concurrent.CompletableFuture;
import java.util.*; import java.util.logging.Logger;
import java.util.stream.IntStream;
public class VRVersionProvider extends BaseVersionProvider { public class VRVersionProvider extends VFVersionProvider {
private int[] multiconnectSupportedVersions = null; @Override
protected Logger getLogger() {
{ return ViaFabric.JLOGGER;
try {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) {
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
} }
@Override @Override
public int getClosestServerProtocol(UserConnection connection) throws Exception { protected VFConfig getConfig() {
if (connection.isClientSide()) { return ViaFabric.config;
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!ViaFabric.config.isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
ProtocolAutoDetector.detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
ViaFabric.JLOGGER.warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
} }
private boolean checkAddressBlocked(SocketAddress addr) { @Override
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
|| ((((InetSocketAddress) addr).getAddress() != null) && return ProtocolAutoDetector.detectVersion(address);
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (ViaFabric.config.isForcedDisable(query)) {
ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
} }
} }

View File

@ -1,168 +1,29 @@
package com.viaversion.fabric.mc115.providers; package com.viaversion.fabric.mc115.providers;
import com.google.common.primitives.Ints; import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.VFAddressParser; import com.viaversion.fabric.common.provider.VFVersionProvider;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.viaversion.fabric.mc115.ViaFabric; import com.viaversion.fabric.mc115.ViaFabric;
import com.viaversion.fabric.mc115.service.ProtocolAutoDetector; import com.viaversion.fabric.mc115.service.ProtocolAutoDetector;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
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.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.protocols.base.BaseProtocol1_16;
import com.viaversion.viaversion.protocols.base.BaseProtocol1_7;
import com.viaversion.viaversion.protocols.base.BaseVersionProvider;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.util.concurrent.CompletableFuture;
import java.util.*; import java.util.logging.Logger;
import java.util.stream.IntStream;
public class VRVersionProvider extends BaseVersionProvider { public class VRVersionProvider extends VFVersionProvider {
private int[] multiconnectSupportedVersions = null;
{ @Override
try { protected Logger getLogger() {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) { return ViaFabric.JLOGGER;
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
} }
@Override @Override
public int getClosestServerProtocol(UserConnection connection) throws Exception { protected VFConfig getConfig() {
if (connection.isClientSide()) { return ViaFabric.config;
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!ViaFabric.config.isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
ProtocolAutoDetector.detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
ViaFabric.JLOGGER.warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
} }
private boolean checkAddressBlocked(SocketAddress addr) { @Override
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
|| ((((InetSocketAddress) addr).getAddress() != null) && return ProtocolAutoDetector.detectVersion(address);
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
} }
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (ViaFabric.config.isForcedDisable(query)) {
ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
}
}

View File

@ -1,166 +1,29 @@
package com.viaversion.fabric.mc116.providers; package com.viaversion.fabric.mc116.providers;
import com.viaversion.fabric.common.VFAddressParser; import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.VFVersionProvider;
import com.viaversion.fabric.mc116.ViaFabric; import com.viaversion.fabric.mc116.ViaFabric;
import com.viaversion.fabric.mc116.service.ProtocolAutoDetector; import com.viaversion.fabric.mc116.service.ProtocolAutoDetector;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.google.common.primitives.Ints;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.base.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.util.concurrent.CompletableFuture;
import java.util.*; import java.util.logging.Logger;
import java.util.stream.IntStream;
public class VRVersionProvider extends BaseVersionProvider { public class VRVersionProvider extends VFVersionProvider {
private int[] multiconnectSupportedVersions = null;
{ @Override
try { protected Logger getLogger() {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) { return ViaFabric.JLOGGER;
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
} }
@Override @Override
public int getClosestServerProtocol(UserConnection connection) throws Exception { protected VFConfig getConfig() {
if (connection.isClientSide()) { return ViaFabric.config;
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!ViaFabric.config.isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
ProtocolAutoDetector.detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
ViaFabric.JLOGGER.warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
} }
private boolean checkAddressBlocked(SocketAddress addr) { @Override
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
|| ((((InetSocketAddress) addr).getAddress() != null) && return ProtocolAutoDetector.detectVersion(address);
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
} }
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (ViaFabric.config.isForcedDisable(query)) {
ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
}
}

View File

@ -1,9 +1,9 @@
version = rootProject.version version = rootProject.version
dependencies { dependencies {
minecraft("com.mojang:minecraft:21w15a") minecraft("com.mojang:minecraft:21w19a")
mappings("net.fabricmc:yarn:21w15a+build.16:v2") mappings("net.fabricmc:yarn:21w19a+build.9:v2")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.33.0+1.17") modImplementation("net.fabricmc.fabric-api:fabric-api:0.34.4+1.17")
modImplementation("com.terraformersmc:modmenu:1.16.9") modImplementation("com.terraformersmc:modmenu:1.16.9")
} }

View File

@ -0,0 +1,54 @@
package com.viaversion.fabric.mc117.mixin.address.client;
import com.viaversion.fabric.common.VFAddressParser;
import net.minecraft.client.network.Address;
import net.minecraft.client.network.AllowedAddressResolver;
import net.minecraft.client.network.RedirectResolver;
import net.minecraft.client.network.ServerAddress;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Optional;
@Mixin(AllowedAddressResolver.class)
public abstract class MixinAllowedAddressResolver {
@Shadow
@Final
private RedirectResolver redirectResolver;
@Shadow
protected abstract Optional<Address> getAllowedAddress(ServerAddress address);
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) throws UnknownHostException {
VFAddressParser viaAddr = new VFAddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.realAddress, address.getPort());
cir.setReturnValue(getAllowedAddress(realAddress)
.map(it -> redirectResolver.lookupRedirect(realAddress)
.flatMap(this::getAllowedAddress)
.orElse(it))
.map(it -> {
try {
return Address.create(new InetSocketAddress(InetAddress.getByAddress(
it.getHostName() + "." + viaAddr.viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()
));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
})
);
}
}

View File

@ -1,24 +0,0 @@
package com.viaversion.fabric.mc117.mixin.address.client;
import com.viaversion.fabric.common.VFAddressParser;
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)
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 {
VFAddressParser viaAddr = new VFAddressParser().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());
}
}

View File

@ -1,29 +0,0 @@
package com.viaversion.fabric.mc117.mixin.address.client;
import com.google.common.net.HostAndPort;
import com.viaversion.fabric.common.VFAddressParser;
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;
@Mixin(ServerAddress.class)
public abstract class MixinServerAddress {
@Shadow
private static HostAndPort resolveServer(HostAndPort address) {
throw new AssertionError();
}
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;resolveServer(Lcom/google/common/net/HostAndPort;)Lcom/google/common/net/HostAndPort;"))
private static HostAndPort modifySrvAddr(HostAndPort address) {
VFAddressParser viaAddr = new VFAddressParser().parse(address.getHost());
if (viaAddr.viaSuffix == null) {
return resolveServer(address);
}
HostAndPort resolved = resolveServer(HostAndPort.fromParts(viaAddr.realAddress, address.getPort()));
return HostAndPort.fromParts(
resolved.getHost().replaceAll("\\.$", "") + "." + viaAddr.viaSuffix, resolved.getPort());
}
}

View File

@ -1,25 +0,0 @@
package com.viaversion.fabric.mc117.mixin.address.client;
import com.viaversion.fabric.common.VFAddressParser;
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 {
VFAddressParser viaAddr = new VFAddressParser().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());
}
}

View File

@ -1,166 +1,28 @@
package com.viaversion.fabric.mc117.providers; package com.viaversion.fabric.mc117.providers;
import com.viaversion.fabric.common.VFAddressParser; import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.VFVersionProvider;
import com.viaversion.fabric.mc117.ViaFabric; import com.viaversion.fabric.mc117.ViaFabric;
import com.viaversion.fabric.mc117.service.ProtocolAutoDetector; import com.viaversion.fabric.mc117.service.ProtocolAutoDetector;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.google.common.primitives.Ints;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.base.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.util.concurrent.CompletableFuture;
import java.util.*; import java.util.logging.Logger;
import java.util.stream.IntStream;
public class VRVersionProvider extends BaseVersionProvider { public class VRVersionProvider extends VFVersionProvider {
private int[] multiconnectSupportedVersions = null; @Override
protected Logger getLogger() {
{ return ViaFabric.JLOGGER;
try {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) {
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
} }
@Override @Override
public int getClosestServerProtocol(UserConnection connection) throws Exception { protected VFConfig getConfig() {
if (connection.isClientSide()) { return ViaFabric.config;
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!ViaFabric.config.isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
ProtocolAutoDetector.detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
ViaFabric.JLOGGER.warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
} }
private boolean checkAddressBlocked(SocketAddress addr) { @Override
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
|| ((((InetSocketAddress) addr).getAddress() != null) && return ProtocolAutoDetector.detectVersion(address);
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (ViaFabric.config.isForcedDisable(query)) {
ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
} }
} }

View File

@ -37,7 +37,7 @@
}, },
"depends": { "depends": {
"fabric-resource-loader-v0": "*", "fabric-resource-loader-v0": "*",
"minecraft": ">1.16.50", "minecraft": "1.17.x",
"viafabric": "*" "viafabric": "*"
}, },
"recommends": { "recommends": {

View File

@ -1,13 +1,11 @@
{ {
"required": true, "required": true,
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc117.mixin.address", "package": "com.viaversion.fabric.mc117.mixin.address",
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"client.MixinConnectScreenThread", "client.MixinAllowedAddressResolver"
"client.MixinServerAddress",
"client.MixinServerPinger"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View File

@ -1,6 +1,6 @@
{ {
"required": true, "required": true,
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc117.mixin.debug", "package": "com.viaversion.fabric.mc117.mixin.debug",
"mixins": [ "mixins": [
], ],

View File

@ -1,6 +1,6 @@
{ {
"required": true, "required": true,
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc117.mixin.gui", "package": "com.viaversion.fabric.mc117.mixin.gui",
"mixins": [ "mixins": [
], ],

View File

@ -1,6 +1,6 @@
{ {
"required": true, "required": true,
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc117.mixin.pipeline", "package": "com.viaversion.fabric.mc117.mixin.pipeline",
"mixins": [ "mixins": [
"MixinClientConnection", "MixinClientConnection",

View File

@ -1,166 +1,28 @@
package com.viaversion.fabric.mc18.providers; package com.viaversion.fabric.mc18.providers;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.VFVersionProvider;
import com.viaversion.fabric.mc18.ViaFabric; import com.viaversion.fabric.mc18.ViaFabric;
import com.viaversion.fabric.common.VFAddressParser;
import com.viaversion.fabric.mc18.service.ProtocolAutoDetector; import com.viaversion.fabric.mc18.service.ProtocolAutoDetector;
import com.viaversion.fabric.common.util.ProtocolUtils;
import com.google.common.primitives.Ints;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocols.base.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.util.concurrent.CompletableFuture;
import java.util.*; import java.util.logging.Logger;
import java.util.stream.IntStream;
public class VRVersionProvider extends BaseVersionProvider { public class VRVersionProvider extends VFVersionProvider {
private int[] multiconnectSupportedVersions = null; @Override
protected Logger getLogger() {
{ return ViaFabric.JLOGGER;
try {
if (FabricLoader.getInstance().isModLoaded("multiconnect")) {
Class<?> mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI");
Class<?> iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol");
Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null);
List<?> protocols = (List<?>) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance);
Method getValue = iProtocolClass.getMethod("getValue");
Method isMulticonnectBeta;
try {
isMulticonnectBeta = iProtocolClass.getMethod("isMulticonnectBeta");
} catch (NoSuchMethodException e) {
isMulticonnectBeta = null;
}
Set<Integer> vers = new TreeSet<>();
for (Object protocol : protocols) {
// Do not use versions with beta multiconnect support, which may have stability issues
if (isMulticonnectBeta == null || !(Boolean) isMulticonnectBeta.invoke(protocol)) {
vers.add((Integer) getValue.invoke(protocol));
}
}
multiconnectSupportedVersions = vers.stream().mapToInt(Integer::intValue).toArray();
ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect");
}
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| ClassCastException ignored) {
}
} }
@Override @Override
public int getClosestServerProtocol(UserConnection connection) throws Exception { protected VFConfig getConfig() {
if (connection.isClientSide()) { return ViaFabric.config;
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (!ViaFabric.config.isClientSideEnabled()) {
return info.getProtocolVersion();
}
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress) {
int addrVersion = new VFAddressParser().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) serverVer = addrVersion;
try {
if (serverVer == -2) {
// Hope protocol was autodetected
ProtocolVersion autoVer =
ProtocolAutoDetector.detectVersion((InetSocketAddress) addr).getNow(null);
if (autoVer != null) {
serverVer = autoVer.getVersion();
}
}
} catch (Exception e) {
ViaFabric.JLOGGER.warning("Couldn't auto detect: " + e);
}
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
handleMulticonnectPing(connection, info, blocked, serverVer);
if (blocked || !supported) serverVer = info.getProtocolVersion();
return serverVer;
}
return super.getClosestServerProtocol(connection);
} }
private boolean checkAddressBlocked(SocketAddress addr) { @Override
return addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
|| ((((InetSocketAddress) addr).getAddress() != null) && return ProtocolAutoDetector.detectVersion(address);
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))));
} }
}
private void handleMulticonnectPing(UserConnection connection, ProtocolInfo info, boolean blocked, int serverVer) throws Exception {
if (info.getState() == State.STATUS
&& info.getProtocolVersion() == -1
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")
&& (blocked || ProtocolUtils.isSupported(serverVer, getVersionForMulticonnect(serverVer)))) { // Intercept the connection
int multiconnectSuggestion = blocked ? -1 : getVersionForMulticonnect(serverVer);
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = PacketWrapper.create(0x00, null, connection);
newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}");
newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class, true, true);
throw CancelException.generate();
}
}
private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
int[] compatibleProtocols = multiconnectSupportedVersions;
if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) {
return clientSideVersion;
}
if (clientSideVersion < compatibleProtocols[0]) {
return compatibleProtocols[0];
}
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion);
return clientSideVersion;
}
private boolean isDisabled(String addr) {
String[] parts = addr.split("\\.");
boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull);
return IntStream.range(0, parts.length).anyMatch(i -> {
String query;
if (isNumericIp) {
query = String.join(".", Arrays.stream(parts, 0, i + 1)
.toArray(String[]::new)) + ((i != 3) ? ".*" : "");
} else {
query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length)
.toArray(String[]::new));
}
if (ViaFabric.config.isForcedDisable(query)) {
ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")");
return true;
} else {
return false;
}
});
}
}