workaround FabricMC/fabric-loom#279, implement #52, update gradle and fabric, update README.md

This commit is contained in:
creeper123123321 2020-09-16 10:19:51 -03:00
parent 29630db0f9
commit 4f1c9ac5b7
18 changed files with 348 additions and 162 deletions

View File

@ -19,7 +19,7 @@ Note: ViaVersion is designed for Vanilla Minecraft servers. It probably will not
| Dependency | Download |
| ----------------------------------------- | ------------------------------------------------------------------------------------------ |
| (Bundled 3.1.0 release) ViaVersion 3.0.2+ | https://ci.viaversion.com/job/ViaVersion/ or https://ci.viaversion.com/job/ViaVersion-DEV/ |
| (Bundled 3.1.1 release) ViaVersion 3.0.2+ | https://ci.viaversion.com/job/ViaVersion/ or https://ci.viaversion.com/job/ViaVersion-DEV/ |
| (Bundled) Cotton Client Commands | https://www.curseforge.com/minecraft/mc-mods/cotton-client-commands |
| (Optional) Fabric Command API v1/v0 | https://www.curseforge.com/minecraft/mc-mods/fabric-api |
| Fabric Resource Loader v0 | https://www.curseforge.com/minecraft/mc-mods/fabric-api |
@ -28,7 +28,7 @@ Note: ViaVersion is designed for Vanilla Minecraft servers. It probably will not
| Dependency | Download |
| ----------------------------------------- | ------------------------------------------------------------------------------------------ |
| (Bundled 3.1.0 release) ViaVersion 3.0.2+ | https://ci.viaversion.com/job/ViaVersion/ or https://ci.viaversion.com/job/ViaVersion-DEV/ |
| (Bundled 3.1.1 release) ViaVersion 3.0.2+ | https://ci.viaversion.com/job/ViaVersion/ or https://ci.viaversion.com/job/ViaVersion-DEV/ |
| (Optional) Fabric Commands v0 | https://www.curseforge.com/minecraft/mc-mods/legacy-fabric-api |
| Fabric Resource Loader v0 | https://www.curseforge.com/minecraft/mc-mods/legacy-fabric-api |

View File

@ -20,7 +20,7 @@ val branch = if (!travisBranch.isNullOrBlank()) travisBranch else try {
"unknown"
}
version = "0.2.12-SNAPSHOT+" + try {
version = "0.2.13-SNAPSHOT+" + try {
gitVersion() + "-" + branch
} catch (e: Exception) {
"unknown"
@ -70,6 +70,7 @@ dependencies {
modImplementation("net.fabricmc:fabric-loader:0.8.2+build.194")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.13.1+build.257-1.14")
modImplementation("io.github.prospector:modmenu:1.7.16.1.14.4+build.128")
modImplementation("io.github.cottonmc:cotton-client-commands:1.0.0+1.15.2")
include("io.github.cottonmc:cotton-client-commands:1.0.0+1.15.2")
@ -137,6 +138,7 @@ curseforge {
}
minecraft {
accessWidener("src/main/resources/viafabric.accesswidener")
}
license {

Binary file not shown.

View File

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

2
gradlew vendored
View File

@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath

1
gradlew.bat vendored
View File

@ -84,6 +84,7 @@ set CMD_LINE_ARGS=%*
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

View File

@ -38,6 +38,7 @@ public class VRConfig extends Config {
public static final String ENABLE_CLIENT_SIDE = "enable-client-side";
public static final String CLIENT_SIDE_VERSION = "client-side-version";
public static final String CLIENT_SIDE_FORCE_DISABLE = "client-side-force-disable";
public static final String HIDE_BUTTON = "hide-button";
public VRConfig(File configFile) {
super(configFile);
@ -79,6 +80,14 @@ public class VRConfig extends Config {
return (List<?>) get(CLIENT_SIDE_FORCE_DISABLE, List.class, Collections.emptyList());
}
public void setHideButton(boolean val) {
set(HIDE_BUTTON, val);
}
public boolean isHideButton() {
return getBoolean(HIDE_BUTTON, false);
}
public boolean isForcedDisable(String line) {
return getClientSideForceDisable().contains(line);
}

View File

@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2018- creeper123123321 <https://creeper123123321.keybase.pub/>
* Copyright (c) 2019- contributors <https://github.com/ViaVersion/ViaFabric/graphs/contributors>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.creeper123123321.viafabric.gui;
import io.github.prospector.modmenu.api.ModMenuApi;
import net.minecraft.client.gui.screen.Screen;
import java.util.function.Function;
public class ModMenuConfig implements ModMenuApi {
@Override
public String getModId() {
return "viafabric";
}
@Override
public Function<Screen, ? extends Screen> getConfigScreenFactory() {
return ViaConfigScreen::new;
}
}

View File

@ -0,0 +1,192 @@
/*
* MIT License
*
* Copyright (c) 2018- creeper123123321 <https://creeper123123321.keybase.pub/>
* Copyright (c) 2019- contributors <https://github.com/ViaVersion/ViaFabric/graphs/contributors>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.creeper123123321.viafabric.gui;
import com.github.creeper123123321.viafabric.ViaFabric;
import com.github.creeper123123321.viafabric.util.ProtocolUtils;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.TranslatableText;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class ViaConfigScreen extends Screen {
private static CompletableFuture<Void> latestProtocolSave;
private final Screen parent;
private TextFieldWidget protocolVersion;
public ViaConfigScreen(Screen parent) {
super(new TranslatableText("gui.viafabric_config.title"));
this.parent = parent;
}
private static int getProtocolTextColor(boolean valid, boolean supported) {
if (!valid) {
return 0xff0000; // Red
} else if (!supported) {
return 0xFFA500; // Orange
}
return 0xE0E0E0; // Default
}
protected void init() {
int entries = 0;
this.addButton(new ButtonWidget(this.width / 2 - 155 + entries % 2 * 160,
this.height / 6 + 24 * (entries >> 1),
150,
20, getClientSideText().asString(), this::onClickClientSide));
entries++;
this.addButton(new ButtonWidget(this.width / 2 - 155 + entries % 2 * 160,
this.height / 6 + 24 * (entries >> 1),
150,
20, getHideViaButtonText().asString(), this::onHideViaButton));
entries++;
protocolVersion = new TextFieldWidget(this.font,
this.width / 2 - 155 + entries % 2 * 160,
this.height / 6 + 24 * (entries >> 1),
150,
20, new TranslatableText("gui.protocol_version_field.name").asString());
entries++;
protocolVersion.setTextPredicate(ProtocolUtils::isStartOfProtocolText);
protocolVersion.setChangedListener(this::onChangeVersionField);
int clientSideVersion = ViaFabric.config.getClientSideVersion();
protocolVersion.setText(ProtocolUtils.getProtocolName(clientSideVersion));
this.children.add(protocolVersion);
//noinspection ConstantConditions
if (entries % 2 == 1) {
entries++;
}
this.addButton(new ButtonWidget(this.width / 2 - 100, this.height / 6 + 24 * (entries >> 1), 200, 20, new TranslatableText("gui.done").asString(), (buttonWidget) -> MinecraftClient.getInstance().openScreen(this.parent)));
}
private void onChangeVersionField(String text) {
protocolVersion.setSuggestion(null);
int newVersion = ViaFabric.config.getClientSideVersion();
Integer parsed = ProtocolUtils.parseProtocolId(text);
boolean validProtocol;
if (parsed != null) {
newVersion = parsed;
validProtocol = true;
} else {
validProtocol = false;
String[] suggestions = ProtocolUtils.getProtocolSuggestions(text);
if (suggestions.length == 1) {
protocolVersion.setSuggestion(suggestions[0].substring(text.length()));
}
}
protocolVersion.setEditableColor(
getProtocolTextColor(ProtocolUtils.isSupported(newVersion, ProtocolRegistry.SERVER_PROTOCOL),
validProtocol));
int finalNewVersion = newVersion;
if (latestProtocolSave == null) latestProtocolSave = CompletableFuture.completedFuture(null);
ViaFabric.config.setClientSideVersion(finalNewVersion);
latestProtocolSave = latestProtocolSave.thenRunAsync(ViaFabric.config::saveConfig, ViaFabric.ASYNC_EXECUTOR);
}
private void onClickClientSide(ButtonWidget widget) {
if (!ViaFabric.config.isClientSideEnabled()) {
MinecraftClient.getInstance().openScreen(new ConfirmScreen(
answer -> {
MinecraftClient.getInstance().openScreen(this);
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.saveConfig();
widget.setMessage(getClientSideText().asString());
}
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
new TranslatableText("gui.enable_client_side.enable").asString(),
new TranslatableText("gui.cancel").asString()
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.saveConfig();
}
widget.setMessage(getClientSideText().asString());
}
@Override
public void removed() {
ViaFabric.config.saveConfig();
}
@Override
public void onClose() {
MinecraftClient.getInstance().openScreen(this.parent);
}
private TranslatableText getClientSideText() {
return ViaFabric.config.isClientSideEnabled() ?
new TranslatableText("gui.client_side.disable")
: new TranslatableText("gui.client_side.enable");
}
private TranslatableText getHideViaButtonText() {
return ViaFabric.config.isHideButton() ?
new TranslatableText("gui.hide_via_button.disable") : new TranslatableText("gui.hide_via_button.enable");
}
private void onHideViaButton(ButtonWidget widget) {
ViaFabric.config.setHideButton(!ViaFabric.config.isHideButton());
ViaFabric.config.saveConfig();
widget.setMessage(getHideViaButtonText().asString());
}
public void render(int mouseX, int mouseY, float delta) {
this.renderBackground();
drawCenteredString(this.font, this.title.asString(), this.width / 2, 20, 16777215);
super.render(mouseX, mouseY, delta);
protocolVersion.render(mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
protocolVersion.tick();
}
}

View File

@ -35,7 +35,7 @@ import java.net.UnknownHostException;
@Mixin(targets = "net/minecraft/client/gui/screen/ConnectScreen$1", priority = 2000) // don't know if it will work with MinerParty mod
public class MixinConnectScreenThread {
@Redirect(method = "run", at = @At(value = "INVOKE",
@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 {
ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address);

View File

@ -26,45 +26,22 @@
package com.github.creeper123123321.viafabric.mixin.client;
import com.github.creeper123123321.viafabric.ViaFabric;
import com.github.creeper123123321.viafabric.util.VersionFormatFilter;
import com.github.creeper123123321.viafabric.gui.ViaConfigScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Mixin(MultiplayerScreen.class)
public abstract class MixinMultiplayerScreen extends Screen {
@Unique
private TextFieldWidget protocolVersion;
@Unique
private ButtonWidget enableClientSideViaVersion;
@Unique
private boolean validProtocol;
@Unique
private boolean supportedProtocol;
@Unique
private CompletableFuture<Void> latestProtocolSave;
protected MixinMultiplayerScreen(Text title, UnsupportedOperationException e) {
super(title);
throw e;
@ -72,104 +49,15 @@ public abstract class MixinMultiplayerScreen extends Screen {
@Inject(method = "init", at = @At("TAIL"), remap = false)
private void onInit(CallbackInfo ci) {
protocolVersion = new TextFieldWidget(font, this.width / 2 + 88, 13, 65, 15, I18n.translate("gui.protocol_version_field.name"));
protocolVersion.setTextPredicate(new VersionFormatFilter());
protocolVersion.setChangedListener((text) -> {
protocolVersion.setSuggestion(null);
int newVersion = ViaFabric.config.getClientSideVersion();
validProtocol = true;
try {
newVersion = Integer.parseInt(text);
} catch (NumberFormatException e) {
ProtocolVersion closest = ProtocolVersion.getClosest(text);
if (closest != null) {
newVersion = closest.getId();
} else {
validProtocol = false;
List<String> completions = ProtocolVersion.getProtocols().stream()
.map(ProtocolVersion::getName)
.flatMap(str -> Stream.concat(
Arrays.stream(str.split("-")),
Arrays.stream(new String[]{str})
))
.distinct()
.filter(ver -> ver.startsWith(text))
.collect(Collectors.toList());
if (completions.size() == 1) {
protocolVersion.setSuggestion(completions.get(0).substring(text.length()));
}
}
}
supportedProtocol = isSupported(newVersion);
protocolVersion.setEditableColor(getTextColor());
int finalNewVersion = newVersion;
if (latestProtocolSave == null) latestProtocolSave = CompletableFuture.completedFuture(null);
latestProtocolSave = latestProtocolSave.thenRunAsync(() -> {
ViaFabric.config.setClientSideVersion(finalNewVersion);
ViaFabric.config.saveConfig();
}, ViaFabric.ASYNC_EXECUTOR);
});
int clientSideVersion = ViaFabric.config.getClientSideVersion();
protocolVersion.setVisible(ViaFabric.config.isClientSideEnabled());
protocolVersion.setText(ProtocolVersion.isRegistered(clientSideVersion)
? ProtocolVersion.getProtocol(clientSideVersion).getName()
: Integer.toString(clientSideVersion));
this.children.add(protocolVersion);
enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
40, 20, // Size
0, 0, // Start pos of texture
20, // v Hover offset
new Identifier("viafabric:textures/gui/widgets.png"),
256, 256, // Texture size
button -> MinecraftClient.getInstance().openScreen(new ConfirmScreen(
answer -> {
MinecraftClient.getInstance().openScreen(this);
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.saveConfig();
protocolVersion.setVisible(true);
enableClientSideViaVersion.visible = false;
}
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
I18n.translate("gui.enable_client_side.enable"),
I18n.translate("gui.cancel")
)),
I18n.translate("gui.enable_client_side_button"));
enableClientSideViaVersion.visible = !protocolVersion.isVisible();
it -> MinecraftClient.getInstance().openScreen(new ViaConfigScreen(this)),
new TranslatableText("gui.via_button").asString());
if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
addButton(enableClientSideViaVersion);
}
@Inject(method = "render", at = {
@At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(IIF)V"),
@At(value = "INVOKE", target = "Lnet/minecraft/class_437;render(IIF)V") // todo check if refmap was fixed
}, remap = false)
private void onRender(int int_1, int int_2, float float_1, CallbackInfo ci) {
protocolVersion.render(int_1, int_2, float_1);
}
@Inject(method = "tick", at = @At("TAIL"), remap = false)
private void onTick(CallbackInfo ci) {
protocolVersion.tick();
}
@Unique
private int getTextColor() {
if (!validProtocol) {
return 0xff0000; // Red
} else if (!supportedProtocol) {
return 0xFFA500; // Orange
}
return 0xE0E0E0; // Default
}
@Unique
private boolean isSupported(int protocol) {
return ProtocolRegistry.getProtocolPath(ProtocolRegistry.SERVER_PROTOCOL, protocol) != null
|| ProtocolRegistry.SERVER_PROTOCOL == protocol;
}
}

View File

@ -28,29 +28,21 @@ package com.github.creeper123123321.viafabric.mixin.client;
import com.github.creeper123123321.viafabric.ViaFabricAddress;
import net.minecraft.network.ServerAddress;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Arrays;
@Mixin(ServerAddress.class)
public class MixinServerAddress {
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveSrv(Ljava/lang/String;)[Ljava/lang/String;"))
private static String[] modifySrvAddr(String address) {
ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address);
if (viaAddr.viaSuffix == null) {
return resolveSrv(address);
return ServerAddress.resolveSrv(address);
}
String[] resolvedSrv = resolveSrv(viaAddr.realAddress);
String[] resolvedSrv = ServerAddress.resolveSrv(viaAddr.realAddress);
resolvedSrv[0] = resolvedSrv[0].replaceAll("\\.$", "") + "." + viaAddr.viaSuffix;
return resolvedSrv;
}
@Shadow
private static String[] resolveSrv(String address) {
throw new IllegalStateException();
}
}

View File

@ -28,6 +28,7 @@ package com.github.creeper123123321.viafabric.providers;
import com.github.creeper123123321.viafabric.ViaFabric;
import com.github.creeper123123321.viafabric.ViaFabricAddress;
import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection;
import com.github.creeper123123321.viafabric.util.ProtocolUtils;
import com.google.common.primitives.Ints;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection;
@ -83,44 +84,52 @@ public class VRVersionProvider extends VersionProvider {
@Override
public int getServerProtocol(UserConnection connection) throws Exception {
if (connection instanceof VRClientSideUserConnection) {
int clientSideVersion = ViaFabric.config.getClientSideVersion();
int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress && ViaFabric.config.isClientSideEnabled()) {
int addrVersion = new ViaFabricAddress().parse(((InetSocketAddress) addr).getHostName()).protocol;
if (addrVersion != 0) clientSideVersion = addrVersion;
if (addrVersion != 0) serverVer = addrVersion;
}
boolean blocked = false;
if (connection.getChannel() != null) {
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString())
|| ((((InetSocketAddress) addr).getAddress() != null) &&
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))))) {
blocked = true;
}
boolean blocked = checkAddressBlocked(addr);
boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
if (info.getState() == State.STATUS && info.getProtocolVersion() == -1
&& (clientSideVersion != -1 || blocked)
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener()
.getClass().getName().startsWith("net.earthcomputer.multiconnect")) { // multiconnect version detector
int multiconnectSuggestion = getVersionForMulticonnect(clientSideVersion);
if (blocked) multiconnectSuggestion = -1;
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = new PacketWrapper(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);
throw CancelException.generate();
}
if (clientSideVersion == -1 || blocked) return info.getProtocolVersion();
handleMulticonnectPing(connection, info, blocked, supported, serverVer);
if (serverVer == -1 || blocked) return info.getProtocolVersion();
}
return clientSideVersion;
return serverVer;
}
return super.getServerProtocol(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, boolean supported, 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") // multiconnect version detector
&& (supported || blocked)) { // Intercept the connection
int multiconnectSuggestion = getVersionForMulticonnect(serverVer);
if (blocked) multiconnectSuggestion = -1;
ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector");
PacketWrapper newAnswer = new PacketWrapper(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);
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
// multiconnect supports it

View File

@ -25,15 +25,24 @@
package com.github.creeper123123321.viafabric.util;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class VersionFormatFilter implements Predicate<String> {
@Override
public boolean test(String s) {
public class ProtocolUtils {
public static boolean isSupported(int server, int client) {
return server == client || ProtocolRegistry.getProtocolPath(client, server) != null;
}
public static String getProtocolName(int id) {
ProtocolVersion ver = ProtocolVersion.getProtocol(id);
if (ver == null) return Integer.toString(id);
return ver.getName();
}
public static boolean isStartOfProtocolText(String s) {
try {
Integer.parseInt(s);
return true;
@ -52,4 +61,26 @@ public class VersionFormatFilter implements Predicate<String> {
}
}
}
public static Integer parseProtocolId(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException ignored) {
ProtocolVersion closest = ProtocolVersion.getClosest(s);
if (closest == null) return null;
return closest.getId();
}
}
public static String[] getProtocolSuggestions(String text) {
return ProtocolVersion.getProtocols().stream()
.map(ProtocolVersion::getName)
.flatMap(str -> Stream.concat(
Arrays.stream(str.split("-")),
Arrays.stream(new String[]{str})
))
.distinct()
.filter(ver -> ver.startsWith(text))
.toArray(String[]::new);
}
}

View File

@ -4,7 +4,9 @@
enable-client-side: false
# This option sets the protocol version to be used when connection to the server (can also be changed in-game)
client-side-version: -1
# List of servers which ViaFabric will force disabling transforming on client-side.
# Hides VIA button from multiplayer menu.
hide-button: false
# List of servers which ViaFabric will force disabling transforming on client-side. It can be overwritten by setting per-server version.
# This isn't always the address in multiplayer GUI. It will use the SRV record pointer when present. Check the game log for the address.
# Uses https://wiki.vg/Mojang_API#Blocked_Servers format (mc.example.com, *.example.com, 192.168.0.1, 192.168.*)
client-side-force-disable: ["hypixel.net", "*.hypixel.net", "hivemc.com", "*.hivemc.com", "hivemc.eu", "*.hivemc.eu"]

View File

@ -3,5 +3,12 @@
"gui.enable_client_side_button": "Enable ViaVersion",
"gui.enable_client_side.question": "Are you sure you want to enable client-side mode?",
"gui.enable_client_side.warning": "I cannot guarantee that this mod is allowed on every (or even any) server. This mod may cause problems with anti-cheat plugins. USE AT OWN RISK.",
"gui.enable_client_side.enable": "Enable"
"gui.enable_client_side.enable": "Enable",
"gui.viafabric_config.title": "ViaFabric Configurations",
"gui.client_side.enable": "Enable client-side",
"gui.client_side.disable": "Disable client-side",
"gui.ping_version.translated": "VIA: %s",
"gui.hide_via_button.enable": "Hide VIA button",
"gui.hide_via_button.disable": "Show VIA button",
"gui.via_button": "VIA"
}

View File

@ -63,6 +63,9 @@
],
"cotton-client-commands": [
"com.github.creeper123123321.viafabric.commands.VRClientCommands"
],
"modmenu": [
"com.github.creeper123123321.viafabric.gui.ModMenuConfig"
]
},
"depends": {
@ -81,5 +84,6 @@
"icon": "assets/viafabric/textures/logo.png",
"mixins": [
"mixins.viafabric.json"
]
],
"accessWidener": "viafabric.accesswidener"
}

View File

@ -0,0 +1,4 @@
accessWidener v1 named
# @Shadow bug workaround https://github.com/FabricMC/fabric-loom/issues/279
accessible method net/minecraft/network/ServerAddress resolveSrv (Ljava/lang/String;)[Ljava/lang/String;