Merge dev branch

merge branch dev into main #253
This commit is contained in:
creeper123123321 2023-06-08 03:50:39 -03:00 committed by GitHub
commit 73bb621462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
102 changed files with 2043 additions and 127 deletions

View File

@ -2,15 +2,15 @@
[![ViaVersion Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)
[![CurseForge Downloads](http://cf.way2muchnoise.eu/full_viafabric_downloads.svg)](https://viaversion.com/fabric)
[![Modrinth Downloads](https://img.shields.io/modrinth/dt/ViaFabric?label=Modrinth&logo=Modrinth&style=flat-square)](https://modrinth.com/mod/ViaFabric)
[![CurseForge Versions](http://cf.way2muchnoise.eu/versions/viafabric.svg)](https://viaversion.com/fabric)
[![Download on Modrinth](https://img.shields.io/badge/download-modrinth-green)](https://modrinth.com/mod/viafabric)
<!-- ^ GitHub seems to not like this https -->
### Client-side and server-side ViaVersion implementation for Fabric
Allows the connection to/from different Minecraft versions on your Minecraft client/server (LAN worlds too)
This mod can be installed on 1.8.9, 1.14.4, 1.15.2, 1.16.5, 1.17.1, 1.18.2 with Fabric Loader.
This mod can be installed on 1.8.9, 1.14.4, 1.15.2, 1.16.5, 1.17.1, 1.18.2, 1.19.4, 1.20 with Fabric Loader.
## Dependencies
@ -18,8 +18,8 @@ This mod can be installed on 1.8.9, 1.14.4, 1.15.2, 1.16.5, 1.17.1, 1.18.2 with
|-----------------------------------------------|----------------------------------------------------------------|
| (Bundled) ViaVersion | https://viaversion.com/ |
| (Bundled) Cotton Client Commands (MC 1.14-15) | https://jitpack.io/#TinfoilMC/ClientCommands |
| Fabric API (MC 1.14+) | https://www.curseforge.com/minecraft/mc-mods/fabric-api |
| Legacy Fabric API (MC 1.8.9) | https://www.curseforge.com/minecraft/mc-mods/legacy-fabric-api |
| Fabric API (MC 1.14+) | https://modrinth.com/mod/fabric-api |
| Legacy Fabric API (MC 1.8.9) | https://modrinth.com/mod/legacy-fabric-api |
Note: ViaVersion is designed for Vanilla Minecraft servers. It probably will not work with modded registry entries or
registry synchronization (fabric-registry-sync mod).
@ -47,15 +47,16 @@ registry synchronization (fabric-registry-sync mod).
- Client-side:
| | 1.8.x | 1.9.x | 1.10-1.14.4 | 1.15.x | 1.16.x | 1.17.x | 1.18.x | 1.19.x |
|---------------|-------|-------|-------------|--------|--------|--------|--------|--------|
| 1.8.9 client | ✓ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ |
| 1.14.x client | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ | ⟲ | ⟲ |
| 1.15.x client | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ | ⟲ |
| 1.16.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ |
| 1.17.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ |
| 1.18.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ |
| 1.19.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| | 1.8.x | 1.9.x | 1.10-1.14.4 | 1.15.x | 1.16.x | 1.17.x | 1.18.x | 1.19.x | 1.20.x |
|---------------|-------|-------|-------------|--------|--------|--------|--------|--------|--------|
| 1.8.9 client | ✓ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ | ⏪ |
| 1.14.x client | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ | ⟲ | ⟲ | ⟲ |
| 1.15.x client | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ | ⟲ | ⟲ |
| 1.16.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ | ⟲ |
| 1.17.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ | ⟲ |
| 1.18.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ | ⟲ |
| 1.19.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ⟲ |
| 1.20.x client | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
✓ = [ViaVersion](https://viaversion.com) ⟲ = [ViaBackwards](https://viaversion.com/backwards) ⏪
= [ViaRewind](https://viaversion.com/rewind)
@ -71,8 +72,8 @@ registry synchronization (fabric-registry-sync mod).
- [ClientViaVersion](https://github.com/Gerrygames/ClientViaVersion): Discontinued 5zig plugin.
- [multiconnect](https://www.curseforge.com/minecraft/mc-mods/multiconnect): Fabric mod for connecting to older
versions: down to 1.11 (stable) and 1.8 (experimental).
- [ViaForge](https://www.curseforge.com/minecraft/mc-mods/viaforge): Fork of ViaFabric porting it to Forge.
- [ViaFabricPlus](https://www.curseforge.com/minecraft/mc-mods/viafabricplus): Fabric ViaVersion/ViaLegacy/ViaAprilFools implementation with clientside fixes
- [ViaForge](https://www.modrinth.com/mod/viaforge): Fork of ViaFabric porting it to Forge.
- [ViaFabricPlus](https://www.modrinth.com/mod/viafabricplus): Fabric ViaVersion/ViaLegacy/ViaAprilFools implementation with client-side fixes.
### Server-side:
@ -128,22 +129,20 @@ registry synchronization (fabric-registry-sync mod).
- Examples: ``minigame.example.com._v1_8.viafabric``, ``native.example.com._v-1.viafabric``
, ``auto.example.com._v-2.viafabric``
## multiconnect
## ViaFabricPlus
### Does it work with multiconnect at same time on client?:
### Does it work with ViaFabric:
- Yes, ViaFabric can be used with multiconnect. ViaFabric will send to its version auto detector the closest non-beta
supported version. (multiconnect beta-supported versions are currently < 1.11))
- No, ViaFabric cannot be used with ViaFabricPlus.
### Differences with multiconnect:
### Differences with ViaFabricPlus:
| | ViaVersion | multiconnect |
|------------------------|-----------------------------------|-----------------------------------------------|
| Designed for | servers | clients |
| Can be installed on | multiple client/server versions | latest client version |
| Objectives | simply implement ViaVersion | version support with fixes to version changes |
| How does it work? | modifying packets at network code | modifying client code more deeply |
| Triggering anti-cheats | very likely | less likely |
| | ViaFabric | ViaFabricPlus |
|----------------------------------|-------------------------------------------------|-----------------------------------------------------------------|
| Can be installed on | Multiple client/server versions with fabric | Latest client-side version with fabric |
| Objectives | Simply implement ViaVersion | Implements ViaVersion with client-side fixes to version changes |
| How does it work? | Modifying packets at network code | Modifying client code more deeply |
| Triggering anti-cheats | Very likely | Mostly not |
## Disclaimer

View File

@ -9,18 +9,18 @@ import java.util.stream.IntStream
plugins {
id "java"
id "maven-publish"
id "org.ajoberstar.grgit" version "3.1.1"
id "org.ajoberstar.grgit" version "5.2.0"
id "com.matthewprenger.cursegradle" version "1.4.0"
id "com.modrinth.minotaur" version "2.2.0"
id "fabric-loom" version "1.1-SNAPSHOT" apply false
id "com.github.ben-manes.versions" version "0.42.0"
id "com.modrinth.minotaur" version "2.7.5"
id "fabric-loom" version "1.2-SNAPSHOT" apply false
id "com.github.ben-manes.versions" version "0.46.0"
}
def ENV = System.getenv()
group = "com.viaversion.fabric"
description = "Client-side and server-side ViaVersion implementation for Fabric"
version = "0.4.9+" + ENV.GITHUB_RUN_NUMBER + "-" + getBranch()
version = "0.4.10+" + ENV.GITHUB_RUN_NUMBER + "-" + getBranch()
logger.lifecycle("Building ViaFabric: $version")
def getBranch() {

View File

@ -2,12 +2,12 @@
# rip my ram
org.gradle.jvmargs=-Xms32M -Xmx4G -XX:+UseG1GC -XX:+UseStringDeduplication
loader_version=0.14.14
viaver_version=4.6.3-SNAPSHOT
loader_version=0.14.21
viaver_version=4.7.0
yaml_version=2.0
publish_mc_versions=1.19.4, 1.18.2, 1.17.1, 1.16.5, 1.15.2, 1.14.4, 1.8.9
# example: 1.19.1-rc2
publish_mc_versions=1.20, 1.19.4, 1.18.2, 1.17.1, 1.16.5, 1.15.2, 1.14.4, 1.8.9
# example: 1.19.1-rc1. Can be a blank value
modrinth_mc_snapshot=
# example: 1.19-Snapshot
# example: 1.19-Snapshot. Can be a blank value
curseforge_mc_snapshot=

Binary file not shown.

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

12
gradlew vendored
View File

@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -133,10 +130,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@ -197,6 +197,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in

2
gradlew.bat vendored
View File

@ -34,7 +34,7 @@ set APP_HOME=%DIRNAME%
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

View File

@ -1,5 +1,5 @@
before_install:
- curl -s "https://get.sdkman.io" | bash
- source "$HOME/.sdkman/bin/sdkman-init.sh"
- sdk install java 17.0.5+8-tem
- sdk use java 17.0.5+8-tem
- sdk install java 17.0.7+7-tem
- sdk use java 17.0.7+7-tem

View File

@ -14,8 +14,8 @@ include("viafabric-mc116")
include("viafabric-mc117")
include("viafabric-mc118")
include("viafabric-mc119")
include("viafabric-mc120")
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}

View File

@ -49,15 +49,15 @@ public class FabricDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
int decoderIndex = ctx.pipeline().names().indexOf("decompress");
if (decoderIndex == -1) return;
if (decoderIndex > ctx.pipeline().names().indexOf("via-decoder")) {
ChannelHandler encoder = ctx.pipeline().get("via-encoder");
ChannelHandler decoder = ctx.pipeline().get("via-decoder");
if (decoderIndex > ctx.pipeline().names().indexOf(CommonTransformer.HANDLER_DECODER_NAME)) {
ChannelHandler encoder = ctx.pipeline().get(CommonTransformer.HANDLER_ENCODER_NAME);
ChannelHandler decoder = ctx.pipeline().get(CommonTransformer.HANDLER_DECODER_NAME);
ctx.pipeline().remove(encoder);
ctx.pipeline().remove(decoder);
ctx.pipeline().addAfter("compress", "via-encoder", encoder);
ctx.pipeline().addAfter("decompress", "via-decoder", decoder);
ctx.pipeline().addAfter("compress", CommonTransformer.HANDLER_ENCODER_NAME, encoder);
ctx.pipeline().addAfter("decompress", CommonTransformer.HANDLER_DECODER_NAME, decoder);
}
}

View File

@ -7,7 +7,7 @@
"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.ping_version.translated": "VIA: %s (%s)",
"gui.hide_via_button.enable": "Hide VIA button",
"gui.hide_via_button.disable": "Show VIA button",
"gui.via_button": "VIA"

View File

@ -13,9 +13,12 @@
},
"depends": {
"fabricloader": ">=0.10.0",
"minecraft": ["1.8.x", "1.14.4", "1.15.2", "~1.16.4", "1.17.1", "1.18.2", "~1.19.4-alpha.23.7.a"],
"minecraft": ["1.8.x", "1.14.4", "1.15.2", "~1.16.4", "1.17.1", "1.18.2", "~1.19.4", "1.20.x"],
"viaversion": ">=4.0.0"
},
"breaks": {
"viafabricplus": "*"
},
"environment": "*",
"authors": [
{

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc114.commands.VRCommandHandler;
import com.viaversion.fabric.mc114.commands.VFCommandHandler;
import com.viaversion.fabric.mc114.platform.FabricPlatform;
import com.viaversion.fabric.mc114.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -48,10 +48,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -61,7 +61,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -11,6 +11,7 @@ import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -49,7 +50,7 @@ public class NMSCommandSender implements ViaCommandSender {
&& source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -0,0 +1,34 @@
package com.viaversion.fabric.mc114.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc114.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).setViaTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).setViaServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -0,0 +1,43 @@
package com.viaversion.fabric.mc114.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
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.Redirect;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_LOCATION) && ((ViaServerInfo) this.server).isViaTranslating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/lang/String;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, String text) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
StringBuilder builder = new StringBuilder(text);
builder.append("\n");
builder.append((new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion())).asString());
builder.append("\n");
builder.append(this.server.version);
multiplayerScreen.setTooltip(builder.toString());
}
}

View File

@ -0,0 +1,30 @@
package com.viaversion.fabric.mc114.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
private boolean viaTranslating;
private int viaServerVer;
public int getViaServerVer() {
return viaServerVer;
}
public void setViaServerVer(int viaServerVer) {
this.viaServerVer = viaServerVer;
}
@Override
public boolean isViaTranslating() {
return viaTranslating;
}
@Override
public void setViaTranslating(boolean via) {
this.viaTranslating = via;
}
}

View File

@ -1,7 +1,9 @@
package com.viaversion.fabric.mc114.platform;
import com.viaversion.fabric.mc114.providers.VRHandItemProvider;
import com.viaversion.fabric.mc114.providers.VFHandItemProvider;
import com.viaversion.fabric.mc114.providers.FabricVersionProvider;
import com.viaversion.fabric.mc114.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +20,14 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,24 @@
package com.viaversion.fabric.mc114.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -3,9 +3,12 @@
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc114.mixin.gui",
"mixins": [
"client.MixinMultiplayerServerListPingerListener"
],
"client": [
"client.MixinMultiplayerScreen"
"client.MixinMultiplayerScreen",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc115.commands.VRCommandHandler;
import com.viaversion.fabric.mc115.commands.VFCommandHandler;
import com.viaversion.fabric.mc115.platform.FabricPlatform;
import com.viaversion.fabric.mc115.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -48,10 +48,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -61,7 +61,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -11,6 +11,7 @@ import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -47,7 +48,7 @@ public class NMSCommandSender implements ViaCommandSender {
} else if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) {
return MinecraftClient.getInstance().player.getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -0,0 +1,34 @@
package com.viaversion.fabric.mc115.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc115.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).setViaTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).setViaServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -0,0 +1,43 @@
package com.viaversion.fabric.mc115.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
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.Redirect;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_LOCATION) && ((ViaServerInfo) this.server).isViaTranslating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/lang/String;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, String text) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
StringBuilder builder = new StringBuilder(text);
builder.append("\n");
builder.append((new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion())).asString());
builder.append("\n");
builder.append(this.server.version);
multiplayerScreen.setTooltip(builder.toString());
}
}

View File

@ -0,0 +1,30 @@
package com.viaversion.fabric.mc115.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
private boolean viaTranslating;
private int viaServerVer;
public int getViaServerVer() {
return viaServerVer;
}
public void setViaServerVer(int viaServerVer) {
this.viaServerVer = viaServerVer;
}
@Override
public boolean isViaTranslating() {
return viaTranslating;
}
@Override
public void setViaTranslating(boolean via) {
this.viaTranslating = via;
}
}

View File

@ -1,7 +1,9 @@
package com.viaversion.fabric.mc115.platform;
import com.viaversion.fabric.mc115.providers.VRHandItemProvider;
import com.viaversion.fabric.mc115.providers.VFHandItemProvider;
import com.viaversion.fabric.mc115.providers.FabricVersionProvider;
import com.viaversion.fabric.mc115.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +20,14 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,24 @@
package com.viaversion.fabric.mc115.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -3,9 +3,12 @@
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc115.mixin.gui",
"mixins": [
"client.MixinMultiplayerServerListPingerListener"
],
"client": [
"client.MixinMultiplayerScreen"
"client.MixinMultiplayerScreen",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc116.commands.VRCommandHandler;
import com.viaversion.fabric.mc116.commands.VFCommandHandler;
import com.viaversion.fabric.mc116.platform.FabricPlatform;
import com.viaversion.fabric.mc116.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -50,10 +50,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -63,7 +63,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -8,6 +8,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -44,7 +45,7 @@ public class NMSCommandSender implements ViaCommandSender {
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -0,0 +1,34 @@
package com.viaversion.fabric.mc116.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc116.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).setViaTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).setViaServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -0,0 +1,45 @@
package com.viaversion.fabric.mc116.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
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.Redirect;
import java.util.ArrayList;
import java.util.List;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/texture/TextureManager;bindTexture(Lnet/minecraft/util/Identifier;)V"))
private void redirectPingIcon(TextureManager textureManager, Identifier identifier) {
if (identifier.equals(DrawableHelper.GUI_ICONS_TEXTURE) && ((ViaServerInfo) this.server).isViaTranslating()) {
textureManager.bindTexture(new Identifier("viafabric:textures/gui/icons.png"));
return;
}
textureManager.bindTexture(identifier);
}
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/util/List;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion()));
lines.add(this.server.version.copy());
multiplayerScreen.setTooltip(lines);
}
}

View File

@ -0,0 +1,30 @@
package com.viaversion.fabric.mc116.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
private boolean viaTranslating;
private int viaServerVer;
public int getViaServerVer() {
return viaServerVer;
}
public void setViaServerVer(int viaServerVer) {
this.viaServerVer = viaServerVer;
}
@Override
public boolean isViaTranslating() {
return viaTranslating;
}
@Override
public void setViaTranslating(boolean via) {
this.viaTranslating = via;
}
}

View File

@ -1,7 +1,11 @@
package com.viaversion.fabric.mc116.platform;
import com.viaversion.fabric.mc116.providers.VRHandItemProvider;
import com.viaversion.fabric.mc116.providers.VFHandItemProvider;
import com.viaversion.fabric.mc116.providers.FabricVersionProvider;
import com.viaversion.fabric.mc116.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc116.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +22,15 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc116.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.abilities.getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.abilities.getWalkSpeed();
}
}

View File

@ -0,0 +1,24 @@
package com.viaversion.fabric.mc116.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -3,9 +3,12 @@
"compatibilityLevel": "JAVA_8",
"package": "com.viaversion.fabric.mc116.mixin.gui",
"mixins": [
"client.MixinMultiplayerServerListPingerListener"
],
"client": [
"client.MixinMultiplayerScreen"
"client.MixinMultiplayerScreen",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc117.commands.VRCommandHandler;
import com.viaversion.fabric.mc117.commands.VFCommandHandler;
import com.viaversion.fabric.mc117.platform.FabricPlatform;
import com.viaversion.fabric.mc117.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -50,10 +50,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -63,7 +63,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -9,6 +9,7 @@ import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -45,7 +46,7 @@ public class NMSCommandSender implements ViaCommandSender {
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -40,7 +40,8 @@ public class MixinServerEntry {
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName()));
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion()));
lines.add(this.server.version.copy());
multiplayerScreen.setTooltip(lines);
}
}

View File

@ -1,7 +1,11 @@
package com.viaversion.fabric.mc117.platform;
import com.viaversion.fabric.mc117.providers.VRHandItemProvider;
import com.viaversion.fabric.mc117.providers.VFHandItemProvider;
import com.viaversion.fabric.mc117.providers.FabricVersionProvider;
import com.viaversion.fabric.mc117.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc117.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +22,15 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc117.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getWalkSpeed();
}
}

View File

@ -0,0 +1,24 @@
package com.viaversion.fabric.mc117.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc118.commands.VRCommandHandler;
import com.viaversion.fabric.mc118.commands.VFCommandHandler;
import com.viaversion.fabric.mc118.platform.FabricPlatform;
import com.viaversion.fabric.mc118.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -50,10 +50,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -63,7 +63,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -8,6 +8,7 @@ import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -44,7 +45,7 @@ public class NMSCommandSender implements ViaCommandSender {
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -40,7 +40,8 @@ public class MixinServerEntry {
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName()));
lines.add(new TranslatableText("gui.ping_version.translated", proto.getName(), proto.getVersion()));
lines.add(this.server.version.copy());
multiplayerScreen.setTooltip(lines);
}
}

View File

@ -1,7 +1,11 @@
package com.viaversion.fabric.mc118.platform;
import com.viaversion.fabric.mc118.providers.VRHandItemProvider;
import com.viaversion.fabric.mc118.providers.VFHandItemProvider;
import com.viaversion.fabric.mc118.providers.FabricVersionProvider;
import com.viaversion.fabric.mc118.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc118.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +22,15 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc118.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getWalkSpeed();
}
}

View File

@ -0,0 +1,24 @@
package com.viaversion.fabric.mc118.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
final HitResult crosshairTarget = MinecraftClient.getInstance().crosshairTarget;
if (crosshairTarget instanceof BlockHitResult) {
final BlockPos pos = ((BlockHitResult) crosshairTarget).getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -9,7 +9,7 @@ import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc119.commands.VRCommandHandler;
import com.viaversion.fabric.mc119.commands.VFCommandHandler;
import com.viaversion.fabric.mc119.platform.FabricPlatform;
import com.viaversion.fabric.mc119.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -50,10 +50,10 @@ public class ViaFabric implements ModInitializer {
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VRCommandHandler) Via.getManager().getCommandHandler())::suggestion)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VRCommandHandler) Via.getManager().getCommandHandler())::execute);
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
@ -63,7 +63,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -9,6 +9,7 @@ import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -45,7 +46,7 @@ public class NMSCommandSender implements ViaCommandSender {
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -10,7 +10,7 @@ import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

View File

@ -38,7 +38,8 @@ public class MixinServerEntry {
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(Text.translatable("gui.ping_version.translated", proto.getName()));
lines.add(Text.translatable("gui.ping_version.translated", proto.getName(), proto.getVersion()));
lines.add(this.server.version.copy());
multiplayerScreen.setMultiplayerScreenTooltip(lines);
}
}

View File

@ -1,7 +1,11 @@
package com.viaversion.fabric.mc119.platform;
import com.viaversion.fabric.mc119.providers.VRHandItemProvider;
import com.viaversion.fabric.mc119.providers.VFHandItemProvider;
import com.viaversion.fabric.mc119.providers.FabricVersionProvider;
import com.viaversion.fabric.mc119.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc119.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
@ -18,12 +22,15 @@ public class VFLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VRHandItemProvider handProvider = new VRHandItemProvider();
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override

View File

@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
public class VRHandItemProvider extends HandItemProvider {
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc119.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getWalkSpeed();
}
}

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc119.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult blockHitResult) {
final BlockPos pos = blockHitResult.getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -0,0 +1,11 @@
dependencies {
minecraft("com.mojang:minecraft:1.20")
mappings("net.fabricmc:yarn:1.20+build.1:v2")
modImplementation("net.fabricmc.fabric-api:fabric-api:0.83.0+1.20")
modImplementation("com.terraformersmc:modmenu:7.0.0")
}
tasks.compileJava {
options.release.set(17)
}

View File

@ -0,0 +1,102 @@
package com.viaversion.fabric.mc120;
import com.google.common.collect.Range;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc120.commands.VFCommandHandler;
import com.viaversion.fabric.mc120.platform.FabricPlatform;
import com.viaversion.fabric.mc120.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.DefaultEventLoop;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.command.CommandSource;
import org.apache.logging.log4j.LogManager;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Logger;
public class ViaFabric implements ModInitializer {
public static final Logger JLOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaFabric"));
public static final ExecutorService ASYNC_EXECUTOR;
public static final EventLoop EVENT_LOOP;
public static final CompletableFuture<Void> INIT_FUTURE = new CompletableFuture<>();
public static VFConfig config;
static {
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ViaFabric-%d").build();
ASYNC_EXECUTOR = Executors.newFixedThreadPool(8, factory);
EVENT_LOOP = new DefaultEventLoop(factory);
EVENT_LOOP.submit(INIT_FUTURE::join); // https://github.com/ViaVersion/ViaFabric/issues/53 ugly workaround code but works tm
}
public static <S extends CommandSource> LiteralArgumentBuilder<S> command(String commandName) {
return LiteralArgumentBuilder.<S>literal(commandName)
.then(
RequiredArgumentBuilder
.<S, String>argument("args", StringArgumentType.greedyString())
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute)
.suggests(((VFCommandHandler) Via.getManager().getCommandHandler())::suggestion)
)
.executes(((VFCommandHandler) Via.getManager().getCommandHandler())::execute);
}
@Override
public void onInitialize() {
FabricPlatform platform = new FabricPlatform();
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();
ViaManagerImpl manager = (ViaManagerImpl) Via.getManager();
manager.init();
Via.getManager().getProtocolManager().registerBaseProtocol(HostnameParserProtocol.INSTANCE, Range.lessThan(Integer.MIN_VALUE));
ProtocolVersion.register(-2, "AUTO");
FabricLoader.getInstance().getEntrypoints("viafabric:via_api_initialized", Runnable.class).forEach(Runnable::run);
registerCommandsV1();
config = new VFConfig(FabricLoader.getInstance().getConfigDir().resolve("ViaFabric")
.resolve("viafabric.yml").toFile());
manager.onServerLoaded();
INIT_FUTURE.complete(null);
}
private void registerCommandsV1() {
try {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, env) -> dispatcher.register(command("viaversion")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, env) -> dispatcher.register(command("viaver")));
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, env) -> dispatcher.register(command("vvfabric")));
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(command("viafabricclient")));
}
} catch (NoClassDefFoundError ignored) {
JLOGGER.info("Couldn't register command as Fabric Commands V1 isn't installed");
}
}
}

View File

@ -0,0 +1,39 @@
package com.viaversion.fabric.mc120;
import com.viaversion.fabric.mc120.gui.ViaConfigScreen;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.Screens;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class ViaFabricClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
registerGui();
}
private void registerGui() {
try {
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (!(screen instanceof MultiplayerScreen)) return;
ButtonWidget enableClientSideViaVersion = new TexturedButtonWidget(scaledWidth / 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
it -> MinecraftClient.getInstance().setScreen(new ViaConfigScreen(screen)),
Text.translatable("gui.via_button"));
if (ViaFabric.config.isHideButton()) enableClientSideViaVersion.visible = false;
Screens.getButtons(screen).add(enableClientSideViaVersion);
});
} catch (NoClassDefFoundError ignored) {
ViaFabric.JLOGGER.info("Couldn't register screen handler as Fabric Screen isn't installed");
}
}
}

View File

@ -0,0 +1,61 @@
package com.viaversion.fabric.mc120.commands;
import com.viaversion.fabric.common.util.RemappingUtil;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
private final CommandSource source;
public NMSCommandSender(CommandSource source) {
this.source = source;
}
@Override
public boolean hasPermission(String s) {
// https://gaming.stackexchange.com/questions/138602/what-does-op-permission-level-do
return source.hasPermissionLevel(3);
}
public static MutableText fromLegacy(String legacy) {
return Text.Serializer.fromJson(RemappingUtil.legacyToJson(legacy));
}
@Override
public void sendMessage(String s) {
if (source instanceof ServerCommandSource) {
((ServerCommandSource) source).sendFeedback(() -> fromLegacy(s), false);
} else if (source instanceof FabricClientCommandSource) {
((FabricClientCommandSource) source).sendFeedback(fromLegacy(s));
}
}
@Override
public UUID getUUID() {
if (source instanceof ServerCommandSource) {
Entity entity = ((ServerCommandSource) source).getEntity();
if (entity != null) return entity.getUuid();
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getUuid();
}
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override
public String getName() {
if (source instanceof ServerCommandSource) {
return ((ServerCommandSource) source).getName();
} else if (source instanceof FabricClientCommandSource) {
return ((FabricClientCommandSource) source).getPlayer().getEntityName();
}
return "?";
}
}

View File

@ -0,0 +1,55 @@
package com.viaversion.fabric.mc120.commands;
import com.viaversion.fabric.common.commands.subs.LeakDetectSubCommand;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.CommandSource;
import com.viaversion.viaversion.commands.ViaCommandHandler;
import java.util.concurrent.CompletableFuture;
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());
} catch (Exception e) {
e.printStackTrace();
}
}
public int execute(CommandContext<? extends CommandSource> ctx) {
String[] args = new String[0];
try {
args = StringArgumentType.getString(ctx, "args").split(" ");
} catch (IllegalArgumentException ignored) {
}
onCommand(
new NMSCommandSender(ctx.getSource()),
args
);
return 1;
}
public CompletableFuture<Suggestions> suggestion(CommandContext<? extends CommandSource> ctx, SuggestionsBuilder builder) {
String[] args;
try {
args = StringArgumentType.getString(ctx, "args").split(" ", -1);
} catch (IllegalArgumentException ignored) {
args = new String[]{""};
}
String[] pref = args.clone();
pref[pref.length - 1] = "";
String prefix = String.join(" ", pref);
onTabComplete(new NMSCommandSender(ctx.getSource()), args)
.stream()
.map(it -> {
SuggestionsBuilder b = new SuggestionsBuilder(builder.getInput(), prefix.length() + builder.getStart());
b.suggest(it);
return b;
})
.forEach(builder::add);
return builder.buildFuture();
}
}

View File

@ -0,0 +1,19 @@
package com.viaversion.fabric.mc120.gui;
import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import java.util.Map;
public class ModMenuConfig implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ViaConfigScreen::new;
}
@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
return ImmutableMap.of("viafabric", getModConfigScreenFactory());
}
}

View File

@ -0,0 +1,156 @@
package com.viaversion.fabric.mc120.gui;
import com.viaversion.fabric.common.config.AbstractViaConfigScreen;
import com.viaversion.fabric.mc120.ViaFabric;
import com.viaversion.fabric.common.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.client.gui.DrawContext;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
public class ViaConfigScreen extends Screen implements AbstractViaConfigScreen {
private static CompletableFuture<Void> latestProtocolSave;
private final Screen parent;
private TextFieldWidget protocolVersion;
public ViaConfigScreen(Screen parent) {
super(Text.translatable(TITLE_TRANSLATE_ID));
this.parent = parent;
}
@Override
protected void init() {
int entries = 0;
this.addDrawableChild(ButtonWidget
.builder(getClientSideText(), this::onClickClientSide)
.dimensions(calculatePosX(this.width, entries),
calculatePosY(this.height, entries), 150, 20)
.build());
entries++;
this.addDrawableChild(ButtonWidget
.builder(getHideViaButtonText(), this::onHideViaButton)
.dimensions(calculatePosX(this.width, entries),
calculatePosY(this.height, entries), 150, 20)
.build());
entries++;
protocolVersion = new TextFieldWidget(this.textRenderer,
calculatePosX(this.width, entries),
calculatePosY(this.height, entries),
150, 20, Text.translatable("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.addDrawableChild(protocolVersion);
this.addDrawableChild(ButtonWidget
.builder(ScreenTexts.DONE, (it) -> close())
.dimensions(this.width / 2 - 100, this.height - 40, 200, 20)
.build());
}
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(newVersion, 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().setScreen(new ConfirmScreen(
answer -> {
if (answer) {
ViaFabric.config.setClientSideEnabled(true);
ViaFabric.config.setClientSideVersion(-2); // AUTO
ViaFabric.config.saveConfig();
widget.setMessage(getClientSideText());
}
MinecraftClient.getInstance().setScreen(this);
},
Text.translatable("gui.enable_client_side.question"),
Text.translatable("gui.enable_client_side.warning"),
Text.translatable("gui.enable_client_side.enable"),
Text.translatable("gui.cancel")
));
} else {
ViaFabric.config.setClientSideEnabled(false);
ViaFabric.config.saveConfig();
}
widget.setMessage(getClientSideText());
}
@Override
public void removed() {
ViaFabric.config.saveConfig();
}
@Override
public void close() {
this.client.setScreen(this.parent);
}
private Text getClientSideText() {
return ViaFabric.config.isClientSideEnabled() ?
Text.translatable("gui.client_side.disable")
: Text.translatable("gui.client_side.enable");
}
private Text getHideViaButtonText() {
return ViaFabric.config.isHideButton() ?
Text.translatable("gui.hide_via_button.disable") : Text.translatable("gui.hide_via_button.enable");
}
private void onHideViaButton(ButtonWidget widget) {
ViaFabric.config.setHideButton(!ViaFabric.config.isHideButton());
ViaFabric.config.saveConfig();
widget.setMessage(getHideViaButtonText());
}
@Override
public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) {
this.renderBackground(drawContext);
drawContext.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 20, 16777215);
super.render(drawContext, mouseX, mouseY, delta);
}
@Override
public void tick() {
super.tick();
protocolVersion.tick();
}
}

View File

@ -0,0 +1,44 @@
package com.viaversion.fabric.mc120.mixin.address.client;
import com.viaversion.fabric.common.AddressParser;
import net.minecraft.client.network.Address;
import net.minecraft.client.network.AllowedAddressResolver;
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.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
public abstract Optional<Address> resolve(ServerAddress address);
@Inject(method = "resolve", at = @At(value = "HEAD"), cancellable = true)
private void resolveVF(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
AddressParser viaAddr = new AddressParser().parse(address.getAddress());
if (viaAddr.viaSuffix == null) {
return;
}
ServerAddress realAddress = new ServerAddress(viaAddr.serverAddress, address.getPort());
cir.setReturnValue(resolve(realAddress).map(it -> viaFabricAddSuffix(it, viaAddr.getSuffixWithOptions())));
}
private Address viaFabricAddSuffix(Address it, String viaSuffix) {
try {
return Address.create(new InetSocketAddress(
InetAddress.getByAddress(it.getHostName() + "." + viaSuffix,
it.getInetSocketAddress().getAddress().getAddress()), it.getPort()));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,12 @@
package com.viaversion.fabric.mc120.mixin.debug.client;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientConnection.class)
public interface MixinClientConnectionAccessor {
@Accessor
Channel getChannel();
}

View File

@ -0,0 +1,37 @@
package com.viaversion.fabric.mc120.mixin.debug.client;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import io.netty.channel.ChannelHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.List;
@Mixin(DebugHud.class)
public class MixinDebugHud {
@Inject(at = @At("RETURN"), method = "getLeftText")
protected void getLeftText(CallbackInfoReturnable<List<String>> info) {
String line = "[ViaFabric] I: " + Via.getManager().getConnectionManager().getConnections().size() + " (F: "
+ Via.getManager().getConnectionManager().getConnectedClients().size() + ")";
@SuppressWarnings("ConstantConditions") ChannelHandler viaDecoder = ((MixinClientConnectionAccessor) MinecraftClient.getInstance().getNetworkHandler()
.getConnection()).getChannel().pipeline().get(CommonTransformer.HANDLER_DECODER_NAME);
if (viaDecoder instanceof FabricDecodeHandler) {
ProtocolInfo protocol = ((FabricDecodeHandler) viaDecoder).getInfo().getProtocolInfo();
if (protocol != null) {
ProtocolVersion serverVer = ProtocolVersion.getProtocol(protocol.getServerProtocolVersion());
ProtocolVersion clientVer = ProtocolVersion.getProtocol(protocol.getProtocolVersion());
line += " / C: " + clientVer + " S: " + serverVer + " A: " + protocol.getUser().isActive();
}
}
info.getReturnValue().add(line);
}
}

View File

@ -0,0 +1,33 @@
package com.viaversion.fabric.mc120.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.mc120.mixin.debug.client.MixinClientConnectionAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.client.network.MultiplayerServerListPinger$1")
public abstract class MixinMultiplayerServerListPingerListener implements ClientQueryPacketListener {
@Accessor
abstract ClientConnection getField_3774(); // Synthetic
@Accessor
abstract ServerInfo getField_3776(); // Synthetic
@Inject(method = "onResponse(Lnet/minecraft/network/packet/s2c/query/QueryResponseS2CPacket;)V", at = @At(value = "HEAD"))
private void onResponseCaptureServerInfo(QueryResponseS2CPacket packet, CallbackInfo ci) {
FabricDecodeHandler decoder = ((MixinClientConnectionAccessor) this.getField_3774()).getChannel()
.pipeline().get(FabricDecodeHandler.class);
if (decoder != null) {
((ViaServerInfo) getField_3776()).setViaTranslating(decoder.getInfo().isActive());
((ViaServerInfo) getField_3776()).setViaServerVer(decoder.getInfo().getProtocolInfo().getServerProtocolVersion());
}
}
}

View File

@ -0,0 +1,46 @@
package com.viaversion.fabric.mc120.mixin.gui.client;
import com.mojang.blaze3d.systems.RenderSystem;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
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.Redirect;
import java.util.ArrayList;
import java.util.List;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
public class MixinServerEntry {
@Shadow
@Final
private ServerInfo server;
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0,
target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Lnet/minecraft/util/Identifier;IIFFIIII)V"))
private void redirectPingIcon(DrawContext instance, Identifier texture, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
if (texture.equals(GUI_ICONS_TEXTURES) && ((ViaServerInfo) this.server).isViaTranslating()) {
instance.drawTexture(new Identifier("viafabric:textures/gui/icons.png"), x, y, u, v, width, height, textureWidth, textureHeight);
return;
}
instance.drawTexture(texture, x, y, u, v, width, height, textureWidth, textureHeight);
}
private static final Identifier GUI_ICONS_TEXTURES = new Identifier("textures/gui/icons.png");
@Redirect(method = "render", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setMultiplayerScreenTooltip(Ljava/util/List;)V"))
private void addServerVer(MultiplayerScreen multiplayerScreen, List<Text> tooltipText) {
ProtocolVersion proto = ProtocolVersion.getProtocol(((ViaServerInfo) this.server).getViaServerVer());
List<Text> lines = new ArrayList<>(tooltipText);
lines.add(Text.translatable("gui.ping_version.translated", proto.getName(), proto.getVersion()));
multiplayerScreen.setMultiplayerScreenTooltip(lines);
}
}

View File

@ -0,0 +1,29 @@
package com.viaversion.fabric.mc120.mixin.gui.client;
import com.viaversion.fabric.common.gui.ViaServerInfo;
import net.minecraft.client.network.ServerInfo;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ServerInfo.class)
public class MixinServerInfo implements ViaServerInfo {
private boolean viaTranslating;
private int viaServerVer;
public int getViaServerVer() {
return viaServerVer;
}
public void setViaServerVer(int viaServerVer) {
this.viaServerVer = viaServerVer;
}
@Override
public boolean isViaTranslating() {
return viaTranslating;
}
@Override
public void setViaTranslating(boolean via) {
this.viaTranslating = via;
}
}

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc120.mixin.pipeline;
import com.viaversion.fabric.common.handler.PipelineReorderEvent;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
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.CallbackInfo;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Shadow
private Channel channel;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
private void reorderCompression(int compressionThreshold, boolean rejectBad, CallbackInfo ci) {
channel.pipeline().fireUserEventTriggered(new PipelineReorderEvent());
}
}

View File

@ -0,0 +1,28 @@
package com.viaversion.fabric.mc120.mixin.pipeline;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.server.ServerNetworkIo$1")
public class MixinServerNetworkIoChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel);
new ProtocolPipelineImpl(user);
channel.pipeline().addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user));
channel.pipeline().addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -0,0 +1,26 @@
package com.viaversion.fabric.mc120.mixin.pipeline.client;
import com.viaversion.fabric.mc120.ViaFabric;
import com.viaversion.fabric.mc120.service.ProtocolAutoDetector;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
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.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Mixin(ClientConnection.class)
public class MixinClientConnection {
@Inject(method = "connect", at = @At("HEAD"))
private static void onConnect(InetSocketAddress address, boolean useEpoll, CallbackInfoReturnable<ClientConnection> cir) {
try {
if (!ViaFabric.config.isClientSideEnabled()) return;
ProtocolAutoDetector.detectVersion(address).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Could not auto-detect protocol for " + address + " " + e);
}
}
}

View File

@ -0,0 +1,30 @@
package com.viaversion.fabric.mc120.mixin.pipeline.client;
import com.viaversion.fabric.common.handler.FabricDecodeHandler;
import com.viaversion.fabric.common.handler.FabricEncodeHandler;
import com.viaversion.fabric.common.handler.CommonTransformer;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
@Mixin(targets = "net.minecraft.network.ClientConnection$1")
public class MixinClientConnectionChInit {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel) {
UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user).add(HostnameParserProtocol.INSTANCE);
channel.pipeline()
.addBefore("encoder", CommonTransformer.HANDLER_ENCODER_NAME, new FabricEncodeHandler(user))
.addBefore("decoder", CommonTransformer.HANDLER_DECODER_NAME, new FabricDecodeHandler(user));
}
}
}

View File

@ -0,0 +1,11 @@
package com.viaversion.fabric.mc120.platform;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import net.minecraft.SharedConstants;
public class FabricNativeVersionProvider implements NativeVersionProvider {
@Override
public int getNativeServerVersion() {
return SharedConstants.getGameVersion().getProtocolVersion();
}
}

View File

@ -0,0 +1,123 @@
package com.viaversion.fabric.mc120.platform;
import com.viaversion.fabric.common.commands.UserCommandSender;
import com.viaversion.fabric.common.platform.NativeVersionProvider;
import com.viaversion.fabric.common.provider.AbstractFabricPlatform;
import com.viaversion.fabric.common.util.FutureTaskId;
import com.viaversion.fabric.mc120.ViaFabric;
import com.viaversion.fabric.mc120.commands.NMSCommandSender;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.command.ViaCommandSender;
import io.netty.channel.EventLoop;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import java.util.logging.Level;
public class FabricPlatform extends AbstractFabricPlatform {
public static MinecraftServer getServer() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return getIntegratedServer();
}
return (MinecraftServer) FabricLoader.getInstance().getGameInstance();
}
@Environment(EnvType.CLIENT)
private static MinecraftServer getIntegratedServer() {
return MinecraftClient.getInstance().getServer();
}
@Override
public FutureTaskId runSync(Runnable runnable) {
if (getServer() != null) {
return runServerSync(runnable);
} else {
return runEventLoop(runnable);
}
}
private FutureTaskId runServerSync(Runnable runnable) {
// Kick task needs to be on main thread, it does already have error logger
return new FutureTaskId(CompletableFuture.runAsync(runnable, getServer()));
}
@Override
public ViaCommandSender[] getOnlinePlayers() {
MinecraftServer server = getServer();
if (server != null && server.isOnThread()) {
return getServerPlayers();
}
return Via.getManager().getConnectionManager().getConnectedClients().values().stream()
.map(UserCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
private ViaCommandSender[] getServerPlayers() {
return getServer().getPlayerManager().getPlayerList().stream()
.map(Entity::getCommandSource)
.map(NMSCommandSender::new)
.toArray(ViaCommandSender[]::new);
}
@Override
public void sendMessage(UUID uuid, String s) {
sendMessageServer(uuid, s);
}
private void sendMessageServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return;
runServerSync(() -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return;
player.sendMessage(NMSCommandSender.fromLegacy(s), false);
});
}
@Override
public boolean kickPlayer(UUID uuid, String s) {
return kickServer(uuid, s);
}
private boolean kickServer(UUID uuid, String s) {
MinecraftServer server = getServer();
if (server == null) return false;
Supplier<Boolean> kickTask = () -> {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid);
if (player == null) return false;
player.networkHandler.disconnect(NMSCommandSender.fromLegacy(s));
return true;
};
if (server.isOnThread()) {
return kickTask.get();
} else {
ViaFabric.JLOGGER.log(Level.WARNING, "Weird!? Player kicking was called off-thread", new Throwable());
runServerSync(kickTask::get);
}
return false; // Can't know if it worked
}
@Override
protected void installNativeVersionProvider() {
Via.getManager().getProviders().use(NativeVersionProvider.class, new FabricNativeVersionProvider());
}
@Override
protected ExecutorService asyncService() {
return ViaFabric.ASYNC_EXECUTOR;
}
@Override
protected EventLoop eventLoop() {
return ViaFabric.EVENT_LOOP;
}
}

View File

@ -0,0 +1,40 @@
package com.viaversion.fabric.mc120.platform;
import com.viaversion.fabric.mc120.providers.VFHandItemProvider;
import com.viaversion.fabric.mc120.providers.FabricVersionProvider;
import com.viaversion.fabric.mc120.providers.VFPlayerAbilitiesProvider;
import com.viaversion.fabric.mc120.providers.VFPlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.bungee.providers.BungeeMovementTransmitter;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
public class VFLoader implements ViaPlatformLoader {
@Override
public void load() {
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
Via.getManager().getProviders().use(VersionProvider.class, new FabricVersionProvider());
if (Via.getPlatform().getConf().isItemCache()) {
VFHandItemProvider handProvider = new VFHandItemProvider();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
handProvider.registerClientTick();
}
Via.getManager().getProviders().use(HandItemProvider.class, handProvider);
}
Via.getManager().getProviders().use(PlayerAbilitiesProvider.class, new VFPlayerAbilitiesProvider());
Via.getManager().getProviders().use(PlayerLookTargetProvider.class, new VFPlayerLookTargetProvider());
}
@Override
public void unload() {
// Nothing to do
}
}

View File

@ -0,0 +1,35 @@
package com.viaversion.fabric.mc120.providers;
import com.viaversion.fabric.common.config.VFConfig;
import com.viaversion.fabric.common.provider.AbstractFabricVersionProvider;
import com.viaversion.fabric.mc120.ViaFabric;
import com.viaversion.fabric.mc120.service.ProtocolAutoDetector;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.channel.ChannelPipeline;
import net.minecraft.network.ClientConnection;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
public class FabricVersionProvider extends AbstractFabricVersionProvider {
@Override
protected Logger getLogger() {
return ViaFabric.JLOGGER;
}
@Override
protected VFConfig getConfig() {
return ViaFabric.config;
}
@Override
protected CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
return ProtocolAutoDetector.detectVersion(address);
}
@Override
protected boolean isMulticonnectHandler(ChannelPipeline pipe) {
return pipe.get(ClientConnection.class).getPacketListener().getClass().getName().startsWith("net.earthcomputer.multiconnect");
}
}

View File

@ -0,0 +1,57 @@
package com.viaversion.fabric.mc120.providers;
import com.viaversion.fabric.common.util.RemappingUtil;
import com.viaversion.fabric.mc120.ViaFabric;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
public class VFHandItemProvider extends HandItemProvider {
public Item clientItem = null;
@Override
public Item getHandItem(UserConnection info) {
if (info.isClientSide()) {
return getClientItem();
}
return super.getHandItem(info);
}
private Item getClientItem() {
if (clientItem == null) {
return new DataItem(0, (byte) 0, (short) 0, null);
}
return new DataItem(clientItem);
}
@Environment(EnvType.CLIENT)
public void registerClientTick() {
try {
ClientTickEvents.END_WORLD_TICK.register(clientWorld -> tickClient());
} catch (NoClassDefFoundError ignored) {
ViaFabric.JLOGGER.info("Fabric Lifecycle V1 isn't installed");
}
}
private void tickClient() {
ClientPlayerEntity p = MinecraftClient.getInstance().player;
if (p != null) {
clientItem = fromNative(p.getInventory().getMainHandStack());
}
}
private Item fromNative(ItemStack original) {
Identifier iid = Registries.ITEM.getId(original.getItem());
int id = RemappingUtil.swordId(iid.toString());
return new DataItem(id, (byte) original.getCount(), (short) original.getDamage(), null);
}
}

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc120.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import net.minecraft.client.MinecraftClient;
public class VFPlayerAbilitiesProvider extends PlayerAbilitiesProvider {
@Override
public float getFlyingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getFlyingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getFlySpeed();
}
@Override
public float getWalkingSpeed(UserConnection connection) {
if (!connection.isClientSide()) return super.getWalkingSpeed(connection);
return MinecraftClient.getInstance().player.getAbilities().getWalkSpeed();
}
}

View File

@ -0,0 +1,22 @@
package com.viaversion.fabric.mc120.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
public class VFPlayerLookTargetProvider extends PlayerLookTargetProvider {
@Override
public Position getPlayerLookTarget(UserConnection info) {
if (!info.isClientSide()) return null;
if (MinecraftClient.getInstance().crosshairTarget instanceof BlockHitResult blockHitResult) {
final BlockPos pos = blockHitResult.getBlockPos();
return new Position(pos.getX(), pos.getY(), pos.getZ());
}
return null;
}
}

View File

@ -0,0 +1,124 @@
package com.viaversion.fabric.mc120.service;
import com.viaversion.fabric.common.AddressParser;
import com.viaversion.fabric.mc120.ViaFabric;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.*;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.network.packet.c2s.query.QueryRequestC2SPacket;
import net.minecraft.network.packet.s2c.query.QueryPongS2CPacket;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.minecraft.server.ServerMetadata;
import net.minecraft.text.Text;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@Environment(EnvType.CLIENT)
public class ProtocolAutoDetector {
private static final LoadingCache<InetSocketAddress, CompletableFuture<ProtocolVersion>> SERVER_VER = CacheBuilder.newBuilder()
.expireAfterWrite(30, TimeUnit.SECONDS)
.build(CacheLoader.from((address) -> {
CompletableFuture<ProtocolVersion> future = new CompletableFuture<>();
try {
final ClientConnection clientConnection = new ClientConnection(NetworkSide.CLIENTBOUND);
ChannelFuture ch = new Bootstrap()
.group(ClientConnection.CLIENT_IO_GROUP.get())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) {
try {
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
channel.config().setOption(ChannelOption.IP_TOS, 0x18); // Stolen from Velocity, low delay, high reliability
} catch (ChannelException ignored) {
}
channel.pipeline()
.addLast("timeout", new ReadTimeoutHandler(30))
.addLast("splitter", new SplitterHandler())
.addLast("decoder", new DecoderHandler(NetworkSide.CLIENTBOUND))
.addLast("prepender", new SizePrepender())
.addLast("encoder", new PacketEncoder(NetworkSide.SERVERBOUND))
.addLast("packet_handler", clientConnection);
}
})
.connect(address);
ch.addListener(future1 -> {
if (!future1.isSuccess()) {
future.completeExceptionally(future1.cause());
} else {
ch.channel().eventLoop().execute(() -> { // needs to execute after channel init
clientConnection.setPacketListener(new ClientQueryPacketListener() {
@Override
public void onResponse(QueryResponseS2CPacket packet) {
ServerMetadata meta = packet.metadata();
if (meta != null && meta.version().isPresent()) {
ProtocolVersion ver = ProtocolVersion.getProtocol(meta.version().get()
.protocolVersion());
future.complete(ver);
ViaFabric.JLOGGER.info("Auto-detected " + ver + " for " + address);
} else {
future.completeExceptionally(new IllegalArgumentException("Null version in query response"));
}
clientConnection.disconnect(Text.empty());
}
@Override
public void onPong(QueryPongS2CPacket packet) {
clientConnection.disconnect(Text.literal("Pong not requested!"));
}
@Override
public void onDisconnected(Text reason) {
future.completeExceptionally(new IllegalStateException(reason.getString()));
}
@Override
public boolean isConnectionOpen() {
return ch.channel().isOpen();
}
});
clientConnection.send(new HandshakeC2SPacket(address.getHostString(),
address.getPort(), NetworkState.STATUS));
clientConnection.send(new QueryRequestC2SPacket());
});
}
});
} catch (Throwable throwable) {
future.completeExceptionally(throwable);
}
return future;
}));
public static CompletableFuture<ProtocolVersion> detectVersion(InetSocketAddress address) {
try {
InetSocketAddress real = new InetSocketAddress(InetAddress.getByAddress
(new AddressParser().parse(address.getHostString()).serverAddress,
address.getAddress().getAddress()), address.getPort());
return SERVER_VER.get(real);
} catch (UnknownHostException | ExecutionException e) {
ViaFabric.JLOGGER.log(Level.WARNING, "Protocol auto detector error: ", e);
return CompletableFuture.completedFuture(null);
}
}
}

View File

@ -0,0 +1,60 @@
{
"schemaVersion": 1,
"id": "viafabric-mc120",
"name": "ViaFabric for 1.20",
"version": "${version}",
"description": "${description}",
"license": "GPL-3.0",
"contact": {
"homepage": "https://viaversion.com/fabric",
"issues": "https://github.com/ViaVersion/ViaFabric/issues",
"sources": "https://github.com/ViaVersion/ViaFabric"
},
"environment": "*",
"authors": [
{
"name": "creeper123123321",
"contact": {
"homepage": "https://creeper123123321.github.io/"
}
}
],
"contributors": [
{
"name": "GitHub contributors",
"contact": {
"homepage": "https://github.com/ViaVersion/ViaFabric/graphs/contributors"
}
}
],
"entrypoints": {
"main": [
"com.viaversion.fabric.mc120.ViaFabric"
],
"client": [
"com.viaversion.fabric.mc120.ViaFabricClient"
],
"modmenu": [
"com.viaversion.fabric.mc120.gui.ModMenuConfig"
]
},
"depends": {
"fabric-resource-loader-v0": "*",
"minecraft": "1.20.x",
"viafabric": "*"
},
"recommends": {
"fabric-command-api-v2": "*"
},
"mixins": [
"mixins.viafabric120.address.json",
"mixins.viafabric120.gui.json",
"mixins.viafabric120.debug.json",
"mixins.viafabric120.pipeline.json"
],
"custom": {
"modmenu": {
"parent": "viafabric"
}
}
}

View File

@ -0,0 +1,13 @@
{
"required": true,
"compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc120.mixin.address",
"mixins": [
],
"client": [
"client.MixinAllowedAddressResolver"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -0,0 +1,14 @@
{
"required": true,
"compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc120.mixin.debug",
"mixins": [
],
"client": [
"client.MixinClientConnectionAccessor",
"client.MixinDebugHud"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -0,0 +1,15 @@
{
"required": true,
"compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc120.mixin.gui",
"mixins": [
],
"client": [
"client.MixinMultiplayerServerListPingerListener",
"client.MixinServerEntry",
"client.MixinServerInfo"
],
"injectors": {
"defaultRequire": 0
}
}

View File

@ -0,0 +1,16 @@
{
"required": true,
"compatibilityLevel": "JAVA_16",
"package": "com.viaversion.fabric.mc120.mixin.pipeline",
"mixins": [
"MixinClientConnection",
"MixinServerNetworkIoChInit"
],
"client": [
"client.MixinClientConnection",
"client.MixinClientConnectionChInit"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@ -7,7 +7,7 @@ import com.viaversion.fabric.common.platform.FabricInjector;
import com.viaversion.fabric.common.protocol.HostnameParserProtocol;
import com.viaversion.fabric.common.util.JLoggerToLog4j;
import com.viaversion.fabric.mc18.commands.NMSCommandImpl;
import com.viaversion.fabric.mc18.commands.VRCommandHandler;
import com.viaversion.fabric.mc18.commands.VFCommandHandler;
import com.viaversion.fabric.mc18.platform.FabricPlatform;
import com.viaversion.fabric.mc18.platform.VFLoader;
import com.viaversion.viaversion.ViaManagerImpl;
@ -47,7 +47,7 @@ public class ViaFabric implements ModInitializer {
Via.init(ViaManagerImpl.builder()
.injector(new FabricInjector())
.loader(new VFLoader())
.commandHandler(new VRCommandHandler())
.commandHandler(new VFCommandHandler())
.platform(platform).build());
platform.init();

View File

@ -6,6 +6,7 @@ import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.text.Text;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public class NMSCommandSender implements ViaCommandSender {
@ -31,7 +32,7 @@ public class NMSCommandSender implements ViaCommandSender {
if (source instanceof Entity) {
return ((Entity) source).getUuid();
}
return UUID.fromString(getName());
return UUID.nameUUIDFromBytes(getName().getBytes(StandardCharsets.UTF_8));
}
@Override

View File

@ -3,7 +3,7 @@ package com.viaversion.fabric.mc18.commands;
import com.viaversion.fabric.common.commands.subs.LeakDetectSubCommand;
import com.viaversion.viaversion.commands.ViaCommandHandler;
public class VRCommandHandler extends ViaCommandHandler {
public class VFCommandHandler extends ViaCommandHandler {
{
try {
registerSubCommand(new LeakDetectSubCommand());

Some files were not shown because too many files have changed in this diff Show More