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 d7c0e2fece
commit 86eb3d54f1
18 changed files with 349 additions and 167 deletions

View File

@ -19,7 +19,7 @@ Note: ViaVersion is designed for Vanilla Minecraft servers. It probably will not
| Dependency | Download | | 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 | | (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 | | (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 | | 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 | | 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 | | (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 | | 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" "unknown"
} }
version = "0.2.12-SNAPSHOT+" + try { version = "0.2.13-SNAPSHOT+" + try {
gitVersion() + "-" + branch gitVersion() + "-" + branch
} catch (e: Exception) { } catch (e: Exception) {
"unknown" "unknown"
@ -65,11 +65,12 @@ dependencies {
// Use 1.16 snapshot, probably intermediary will make it work on further versions // Use 1.16 snapshot, probably intermediary will make it work on further versions
// https://modmuss50.me/fabric.html?&version=1.16 // https://modmuss50.me/fabric.html?&version=1.16
minecraft("com.mojang:minecraft:1.16") minecraft("com.mojang:minecraft:1.16.3")
mappings("net.fabricmc:yarn:1.16+build.1:v2") mappings("net.fabricmc:yarn:1.16.3+build.5:v2")
modImplementation("net.fabricmc:fabric-loader:0.8.8+build.202") modImplementation("net.fabricmc:fabric-loader:0.9.3+build.207")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.13.1+build.370-1.16") modImplementation("net.fabricmc.fabric-api:fabric-api:0.20.2+build.402-1.16")
modImplementation("io.github.prospector:modmenu:1.14.5+build.30")
modImplementation("io.github.cottonmc:cotton-client-commands:1.0.1+1.16-rc1") modImplementation("io.github.cottonmc:cotton-client-commands:1.0.1+1.16-rc1")
include("io.github.cottonmc:cotton-client-commands:1.0.1+1.16-rc1") include("io.github.cottonmc:cotton-client-commands:1.0.1+1.16-rc1")
@ -137,6 +138,7 @@ curseforge {
} }
minecraft { minecraft {
accessWidener("src/main/resources/viafabric.accesswidener")
} }
license { license {

Binary file not shown.

View File

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

2
gradlew vendored
View File

@ -82,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -129,6 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # 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 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @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% "%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 ENABLE_CLIENT_SIDE = "enable-client-side";
public static final String CLIENT_SIDE_VERSION = "client-side-version"; 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 CLIENT_SIDE_FORCE_DISABLE = "client-side-force-disable";
public static final String HIDE_BUTTON = "hide-button";
public VRConfig(File configFile) { public VRConfig(File configFile) {
super(configFile); super(configFile);
@ -79,6 +80,14 @@ public class VRConfig extends Config {
return (List<?>) get(CLIENT_SIDE_FORCE_DISABLE, List.class, Collections.emptyList()); 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) { public boolean isForcedDisable(String line) {
return getClientSideForceDisable().contains(line); return getClientSideForceDisable().contains(line);
} }

View File

@ -0,0 +1,36 @@
/*
* 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.ConfigScreenFactory;
import io.github.prospector.modmenu.api.ModMenuApi;
public class ModMenuConfig implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ViaConfigScreen::new;
}
}

View File

@ -0,0 +1,194 @@
/*
* 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.screen.ScreenTexts;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.util.math.MatrixStack;
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(), this::onClickClientSide));
entries++;
this.addButton(new ButtonWidget(this.width / 2 - 155 + entries % 2 * 160,
this.height / 6 + 24 * (entries >> 1),
150,
20, getHideViaButtonText(), this::onHideViaButton));
entries++;
protocolVersion = new TextFieldWidget(this.textRenderer,
this.width / 2 - 155 + entries % 2 * 160,
this.height / 6 + 24 * (entries >> 1),
150,
20, new TranslatableText("gui.protocol_version_field.name"));
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, ScreenTexts.DONE, (buttonWidget) -> this.client.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());
}
},
new TranslatableText("gui.enable_client_side.question"),
new TranslatableText("gui.enable_client_side.warning"),
new TranslatableText("gui.enable_client_side.enable"),
new TranslatableText("gui.cancel")
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.saveConfig();
}
widget.setMessage(getClientSideText());
}
@Override
public void removed() {
ViaFabric.config.saveConfig();
}
@Override
public void onClose() {
this.client.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());
}
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 20, 16777215);
super.render(matrices, mouseX, mouseY, delta);
protocolVersion.render(matrices, 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 @Mixin(targets = "net/minecraft/client/gui/screen/ConnectScreen$1", priority = 2000) // don't know if it will work with MinerParty mod
public class MixinConnectScreenThread { 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;")) target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException { private InetAddress resolveViaFabricAddr(String address) throws UnknownHostException {
ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address); ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address);

View File

@ -26,45 +26,22 @@
package com.github.creeper123123321.viafabric.mixin.client; package com.github.creeper123123321.viafabric.mixin.client;
import com.github.creeper123123321.viafabric.ViaFabric; 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.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget; 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.gui.widget.TexturedButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 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) @Mixin(MultiplayerScreen.class)
public abstract class MixinMultiplayerScreen extends Screen { 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) { protected MixinMultiplayerScreen(Text title, UnsupportedOperationException e) {
super(title); super(title);
throw e; throw e;
@ -72,104 +49,15 @@ public abstract class MixinMultiplayerScreen extends Screen {
@Inject(method = "init", at = @At("TAIL")) @Inject(method = "init", at = @At("TAIL"))
private void onInit(CallbackInfo ci) { private void onInit(CallbackInfo ci) {
protocolVersion = new TextFieldWidget(this.textRenderer, this.width / 2 + 88, 13, 65, 15, new TranslatableText("gui.protocol_version_field.name")); ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(this.width / 2 + 113, 10,
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,
40, 20, // Size 40, 20, // Size
0, 0, // Start pos of texture 0, 0, // Start pos of texture
20, // v Hover offset 20, // v Hover offset
new Identifier("viafabric:textures/gui/widgets.png"), new Identifier("viafabric:textures/gui/widgets.png"),
256, 256, // Texture size 256, 256, // Texture size
button -> MinecraftClient.getInstance().openScreen(new ConfirmScreen( it -> MinecraftClient.getInstance().openScreen(new ViaConfigScreen(this)),
answer -> { new TranslatableText("gui.via_button"));
MinecraftClient.getInstance().openScreen(this); if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
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"),
new TranslatableText("gui.enable_client_side.enable"),
new TranslatableText("gui.cancel")
)),
new TranslatableText("gui.enable_client_side_button"));
enableClientSideViaVersion.visible = !protocolVersion.isVisible();
addButton(enableClientSideViaVersion); addButton(enableClientSideViaVersion);
} }
@Inject(method = "render", at = {
@At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render" +
"(Lnet/minecraft/client/util/math/MatrixStack;IIF)V"),
})
private void onRender(MatrixStack matrices, int int_1, int int_2, float float_1, CallbackInfo ci) {
protocolVersion.render(matrices, int_1, int_2, float_1);
}
@Inject(method = "tick", at = @At("TAIL"))
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

@ -34,21 +34,14 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ServerAddress.class) @Mixin(ServerAddress.class)
public class MixinServerAddress { public abstract class MixinServerAddress {
@Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveSrv(Ljava/lang/String;)Lcom/mojang/datafixers/util/Pair;")) @Redirect(method = "parse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ServerAddress;resolveServer(Ljava/lang/String;)Lcom/mojang/datafixers/util/Pair;"))
private static Pair<String, Integer> modifySrvAddr(String address) { private static Pair<String, Integer> modifySrvAddr(String address) {
ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address); ViaFabricAddress viaAddr = new ViaFabricAddress().parse(address);
if (viaAddr.viaSuffix == null) { if (viaAddr.viaSuffix == null) {
return resolveSrv(address); return ServerAddress.resolveServer(address);
} }
Pair<String, Integer> resolvedSrv = resolveSrv(viaAddr.realAddress).mapFirst(it -> it.replaceAll("\\.$", "") + "." + viaAddr.viaSuffix); return ServerAddress.resolveServer(viaAddr.realAddress).mapFirst(it -> it.replaceAll("\\.$", "") + "." + viaAddr.viaSuffix);
return resolvedSrv;
}
@Shadow
private static Pair<String, Integer> 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.ViaFabric;
import com.github.creeper123123321.viafabric.ViaFabricAddress; import com.github.creeper123123321.viafabric.ViaFabricAddress;
import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection;
import com.github.creeper123123321.viafabric.util.ProtocolUtils;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.ClientConnection; import net.minecraft.network.ClientConnection;
@ -83,44 +84,52 @@ public class VRVersionProvider extends VersionProvider {
@Override @Override
public int getServerProtocol(UserConnection connection) throws Exception { public int getServerProtocol(UserConnection connection) throws Exception {
if (connection instanceof VRClientSideUserConnection) { if (connection instanceof VRClientSideUserConnection) {
int clientSideVersion = ViaFabric.config.getClientSideVersion(); int serverVer = ViaFabric.config.getClientSideVersion();
SocketAddress addr = connection.getChannel().remoteAddress(); SocketAddress addr = connection.getChannel().remoteAddress();
if (addr instanceof InetSocketAddress && ViaFabric.config.isClientSideEnabled()) { if (addr instanceof InetSocketAddress && ViaFabric.config.isClientSideEnabled()) {
int addrVersion = new ViaFabricAddress().parse(((InetSocketAddress) addr).getHostName()).protocol; 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) { if (connection.getChannel() != null) {
ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo()); ProtocolInfo info = Objects.requireNonNull(connection.getProtocolInfo());
if (addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) boolean blocked = checkAddressBlocked(addr);
|| ((((InetSocketAddress) addr).getAddress() != null) && boolean supported = ProtocolUtils.isSupported(serverVer, info.getProtocolVersion());
(isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress())
|| isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))))) {
blocked = true;
}
if (info.getState() == State.STATUS && info.getProtocolVersion() == -1 handleMulticonnectPing(connection, info, blocked, supported, serverVer);
&& (clientSideVersion != -1 || blocked)
&& connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener() if (serverVer == -1 || blocked) return info.getProtocolVersion();
.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();
} }
return clientSideVersion; return serverVer;
} }
return super.getServerProtocol(connection); 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) { private int getVersionForMulticonnect(int clientSideVersion) {
// https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java // https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java
// multiconnect supports it // multiconnect supports it

View File

@ -25,15 +25,24 @@
package com.github.creeper123123321.viafabric.util; package com.github.creeper123123321.viafabric.util;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
public class VersionFormatFilter implements Predicate<String> { public class ProtocolUtils {
@Override public static boolean isSupported(int server, int client) {
public boolean test(String s) { 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 { try {
Integer.parseInt(s); Integer.parseInt(s);
return true; 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 enable-client-side: false
# This option sets the protocol version to be used when connection to the server (can also be changed in-game) # This option sets the protocol version to be used when connection to the server (can also be changed in-game)
client-side-version: -1 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. # 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.*) # 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"] 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_button": "Enable ViaVersion",
"gui.enable_client_side.question": "Are you sure you want to enable client-side mode?", "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.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": [ "cotton-client-commands": [
"com.github.creeper123123321.viafabric.commands.VRClientCommands" "com.github.creeper123123321.viafabric.commands.VRClientCommands"
],
"modmenu": [
"com.github.creeper123123321.viafabric.gui.ModMenuConfig"
] ]
}, },
"depends": { "depends": {
@ -81,5 +84,6 @@
"icon": "assets/viafabric/textures/logo.png", "icon": "assets/viafabric/textures/logo.png",
"mixins": [ "mixins": [
"mixins.viafabric.json" "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 resolveServer (Ljava/lang/String;)Lcom/mojang/datafixers/util/Pair;