mirror of
https://github.com/ViaVersion/ViaFabric.git
synced 2024-11-21 11:35:16 +01:00
update 1.17 snapshot, cleanup VersionProvider
This commit is contained in:
parent
4bbd683382
commit
105e64b11a
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@ -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/
|
||||||
|
11
build.gradle
11
build.gradle
@ -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}:")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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": {
|
||||||
|
@ -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
|
||||||
|
@ -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": [
|
||||||
],
|
],
|
||||||
|
@ -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": [
|
||||||
],
|
],
|
||||||
|
@ -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",
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user