diff --git a/.travis.yml b/.travis.yml index 28fe2f3..8191b3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ - language: java #before_cache: #- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock @@ -9,11 +8,11 @@ language: java # - "$HOME/.gradle/wrapper/" deploy: provider: releases - api_key: + token: secure: B+xrpk79kvRF5AhNqHKlsUd1vloo4xe1oZjzsmsm67rrd2RS9iBgpRBC5YfCeYmxj5HviBjQx3Qzdu/zzaYP9ry5IT17t5g3OcPpP9GynyinIlfAN6TUlk9u0D7ojSYV6JJjD7Go8K9+U5E+jEn4cSIVQ4kFWH62lDyjjNQqZitd4p+/J9M4p5sQ9BiC2oUIFVMrOXZs5v0tqVSCWGp/s2OkX+ie/RYm1ULW4vvpwTlK2+fklOfq2qyityPtV1v6DQoOMJ4GdouBVGtva7hdnuHtCCqVvwTnpgmItLE68uCczgR4gQ5SIeCo7Vppda6jSseA5DDku1YwUUTRm1VOENhmv3iln9sDRiZbX17d86689FslMAltSggmg4urEPmjzlP55NCebvEsQoKp8x3XuViUOUqkQS+e/IGkK1F4oeh4YB7Mz6LyGM3TOv2gfE+nbQ4xU7s1nELoqdwUp2HshN4SFxurLtKDfC2/ZHRwtwXhGbEQgK0TSRSohxoE8a1XZvXLJ+ddc8ZZX8LqBiKgXkkEyvpAehAqK+lWsqIBJp+828CMeUet9sYNJ9QkAy3Lz8ecwuzCXEuacTW+f6XW1rBr2wPSXOJQt45xt4IfW1so7G1V5QSmcExU3uKKxkgekOnhZjT8LTmUpaSBW1Nu2a5kKuHnHvs0uDexhoJ/cEs= file_glob: true file: build/libs/* - skip_cleanup: true + cleanup: true on: repo: ViaVersion/ViaFabric all_branches: true diff --git a/README.md b/README.md index 7a88064..12a7542 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ Adding [ViaBackwards](https://viaversion.com/backwards) (and optionally [ViaRewi - your client can connect to newer versions -A chart with compatible versions is available at https://viaversion.com +**What versions can ViaVersion, ViaBackwards and ViaRewind translate?:** +- See https://viaversion.com **Commands**: @@ -49,10 +50,22 @@ A chart with compatible versions is available at https://viaversion.com **Alternatives to this mod:** - [ClientViaVersion](https://github.com/Gerrygames/ClientViaVersion): This discontinued client-side plugin for The 5zig Mod implemented ViaVersion, ViaBackwards and ViaRewind for 1.7.10, 1.8.9, 1.12 and 1.12.2 clients, allowing them to connect to 1.7-1.12.2 servers. It also had a protocol translation for 1.7 servers, which there's an updated version at https://github.com/KennyTV/ViaVersion/tree/hack (unsupported). -- [multiconnect](https://www.curseforge.com/minecraft/mc-mods/multiconnect): This client-side Fabric mod does also translate older protocols and fixes some differences between versions, which ViaFabric doesn't. Currently, it goes down to 1.10. (2020-06-23) +- [multiconnect](https://www.curseforge.com/minecraft/mc-mods/multiconnect): This client-side Fabric mod does also accept older protocols and fixes some differences between versions, which ViaFabric doesn't. Currently, it goes down to 1.10. (2020-06-23) - [Protocol4](https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/2299203-protocol4-1-0-2-allows-1-7-10-clients-to-connect): This LiteLoader client-side mod allows your 1.7.10 client to connect to 1.7.x servers. - [ProtocolSupport](https://protocol.support/): This Bukkit plugin allows clients to connect from older versions (down to 1.4.7). - [ViaVersion](https://viaversion.com): ViaVersion can run as a plugin for BungeeCord, CraftBukkit, SpongeCommon and Velocity servers. + +**How can I disable client-side ViaFabric?:** +-You can disable it by resetting the anti-cheat warning in config file or by setting protocol version to -1 + + +**Does it work with multiconnect at same time on client?:** +- Yes, ViaFabric can be used with multiconnect. ViaFabric will set multiconnect version auto detector to the supported version which is closest to client-side version. +- Example of setups: +- (1.8 server) <-> (disabled ViaFabric) <-> (auto detected 1.8 server - multiconnect on Minecraft) = doesn't work because multiconnect doesn't support it +- (1.8 server) <-> (forced 1.8 - ViaFabric in client - suggests 1.10) <-> (detected 1.10 server - multiconnect on Minecraft) = works, with ViaVersion translating 1.8 -> 1.10 and multiconnect accepting 1.10 +- (1.8 server) <-> (forced 1.8 - ViaFabric in client - detected 1.12.2 client) <-> (forced 1.12.2 server - multiconnect on Minecraft) = works with ViaVersion translating 1.8 -> 1.12.2 and multiconnect accepting 1.12.2 + ## WARNING **I cannot guarantee that this mod is allowed on every (or even any) server. This mod may cause problems with anti cheat plugins. USE AT OWN RISK** diff --git a/src/main/java/com/github/creeper123123321/viafabric/config/VRConfig.java b/src/main/java/com/github/creeper123123321/viafabric/config/VRConfig.java index 9b58270..b02d4d1 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/config/VRConfig.java +++ b/src/main/java/com/github/creeper123123321/viafabric/config/VRConfig.java @@ -24,11 +24,11 @@ package com.github.creeper123123321.viafabric.config; -import net.minecraft.SharedConstants; import us.myles.ViaVersion.util.Config; import java.io.File; import java.net.URL; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -36,6 +36,7 @@ import java.util.Map; public class VRConfig extends Config { public static final String ENABLE_CLIENT_SIDE = "enable-client-side"; public static final String CLIENT_SIDE_VERSION = "client-side-version"; + public static final String CLIENT_SIDE_FORCE_DISABLE = "client-side-force-disable"; public VRConfig(File configFile) { super(configFile); @@ -60,16 +61,24 @@ public class VRConfig extends Config { return getBoolean(ENABLE_CLIENT_SIDE, false); } - public int getClientSideVersion() { - int nat = SharedConstants.getGameVersion().getProtocolVersion(); - return !isClientSideEnabled() ? nat : getInt(CLIENT_SIDE_VERSION, -1); - } - public void setClientSideEnabled(boolean val) { set(ENABLE_CLIENT_SIDE, val); } + public int getClientSideVersion() { + if (!isClientSideEnabled()) return -1; + return getInt(CLIENT_SIDE_VERSION, -1); + } + public void setClientSideVersion(int val) { set(CLIENT_SIDE_VERSION, val); } + + public Collection getClientSideForceDisable() { + return (List) get(CLIENT_SIDE_FORCE_DISABLE, List.class, Collections.emptyList()); + } + + public boolean isForcedDisable(String line) { + return getClientSideForceDisable().contains(line); + } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/listeners/UpdateListener.java b/src/main/java/com/github/creeper123123321/viafabric/listeners/UpdateListener.java deleted file mode 100644 index f165544..0000000 --- a/src/main/java/com/github/creeper123123321/viafabric/listeners/UpdateListener.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 creeper123123321 and contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.github.creeper123123321.viafabric.listeners; - -import com.github.creeper123123321.viafabric.commands.NMSCommandSender; -import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.command.ViaCommandSender; -import us.myles.ViaVersion.api.data.UserConnection; -import us.myles.ViaVersion.update.UpdateUtil; - -import java.util.Arrays; -import java.util.UUID; - -public class UpdateListener { - public static void onJoin(UserConnection conn) { - UUID id = conn.getProtocolInfo().getUuid(); - if (conn instanceof VRClientSideUserConnection) { - onClientJoin(id); - } else { - onServerJoin(id); - } - } - - private static void onClientJoin(UUID id) { - MinecraftClient.getInstance().execute(() -> { - Entity entity = MinecraftClient.getInstance().targetedEntity; - if (entity != null) { - onSenderJoin(new NMSCommandSender(entity.getCommandSource()), id); - } - }); - } - - private static void onServerJoin(UUID id) { - Via.getPlatform().runSync(() -> { - Arrays.stream(Via.getPlatform().getOnlinePlayers()) - .filter(it -> it.getUUID().equals(id)).findAny().ifPresent(sender -> { - onSenderJoin(sender, id); - }); - }); - } - - private static void onSenderJoin(ViaCommandSender sender, UUID connId) { - if (sender.hasPermission("viaversion.admin") - && Via.getConfig().isCheckForUpdates()) { - UpdateUtil.sendUpdateMessage(connId); - } - } -} diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinDebugHud.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinDebugHud.java index 3ea996a..34793fc 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinDebugHud.java +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinDebugHud.java @@ -51,12 +51,14 @@ public class MixinDebugHud { ProtocolInfo protocol = ((VRDecodeHandler) viaDecoder).getInfo().getProtocolInfo(); if (protocol != null) { ProtocolVersion serverVer = ProtocolVersion.getProtocol(protocol.getServerProtocolVersion()); + ProtocolVersion clientVer = ProtocolVersion.getProtocol(protocol.getProtocolVersion()); String inactive = ""; if (!protocol.getUser().isActive()) { inactive = " (inactive)"; } - info.getReturnValue().add("[ViaFabric] Client injected: " - + serverVer.getName() + " (" + serverVer.getId() + ") server" + inactive); + info.getReturnValue().add("[ViaFabric] Client injected: C: " + + clientVer.getName() + " (" + clientVer.getId() + ") S: " + + serverVer.getName() + "(" + serverVer.getId() + ")" + inactive); } } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/platform/VRConnectionManager.java b/src/main/java/com/github/creeper123123321/viafabric/platform/VRConnectionManager.java index 0b78c35..3b19617 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/platform/VRConnectionManager.java +++ b/src/main/java/com/github/creeper123123321/viafabric/platform/VRConnectionManager.java @@ -24,7 +24,6 @@ package com.github.creeper123123321.viafabric.platform; -import com.github.creeper123123321.viafabric.listeners.UpdateListener; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.platform.ViaConnectionManager; @@ -33,22 +32,4 @@ public class VRConnectionManager extends ViaConnectionManager { public boolean isFrontEnd(UserConnection connection) { return !(connection instanceof VRClientSideUserConnection); } - - @Override - public void onLoginSuccess(UserConnection connection) { - super.onLoginSuccess(connection); - if (!isFrontEnd(connection)) { - // We'll use it later - this.clients.put(connection.getProtocolInfo().getUuid(), connection); - UpdateListener.onJoin(connection); - } - } - - @Override - public void onDisconnect(UserConnection connection) { - super.onDisconnect(connection); - if (!isFrontEnd(connection)) { - this.clients.remove(connection.getProtocolInfo().getUuid()); - } - } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java b/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java index 1faeed4..77f2ee3 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java +++ b/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java @@ -36,12 +36,8 @@ import net.fabricmc.api.Environment; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.entity.Entity; import net.minecraft.network.MessageType; -import net.minecraft.network.OffThreadException; -import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket; -import net.minecraft.network.packet.s2c.play.DisconnectS2CPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; @@ -51,7 +47,6 @@ import us.myles.ViaVersion.api.ViaAPI; import us.myles.ViaVersion.api.ViaVersionConfig; import us.myles.ViaVersion.api.command.ViaCommandSender; import us.myles.ViaVersion.api.configuration.ConfigurationProvider; -import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.platform.TaskId; import us.myles.ViaVersion.api.platform.ViaConnectionManager; import us.myles.ViaVersion.api.platform.ViaPlatform; @@ -217,12 +212,7 @@ public class VRPlatform implements ViaPlatform { @Override public void sendMessage(UUID uuid, String s) { - UserConnection user = Via.getManager().getConnection(uuid); - if (user instanceof VRClientSideUserConnection) { - sendMessageClient(s); - } else { - sendMessageServer(uuid, s); - } + sendMessageServer(uuid, s); } private void sendMessageServer(UUID uuid, String s) { @@ -235,42 +225,9 @@ public class VRPlatform implements ViaPlatform { }); } - @Environment(EnvType.CLIENT) - private void sendMessageClient(String s) { - ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler(); - if (handler != null) { - try { - handler.onChatMessage(new ChatMessageS2CPacket( - Text.Serializer.fromJson(legacyToJson(s)) - )); - } catch (OffThreadException ignored) { - } - } - } - @Override public boolean kickPlayer(UUID uuid, String s) { - UserConnection user = Via.getManager().getConnection(uuid); - if (user instanceof VRClientSideUserConnection) { - return kickClient(s); - } else { - return kickServer(uuid, s); - } - } - - @Environment(EnvType.CLIENT) - private boolean kickClient(String msg) { - ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler(); - if (handler != null) { - try { - handler.onDisconnect(new DisconnectS2CPacket( - Text.Serializer.fromJson(legacyToJson(msg)) - )); - } catch (OffThreadException ignored) { - } - return true; - } - return false; + return kickServer(uuid, s); } private boolean kickServer(UUID uuid, String s) { diff --git a/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java b/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java index cd6bc04..67a8a52 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java +++ b/src/main/java/com/github/creeper123123321/viafabric/providers/VRVersionProvider.java @@ -26,14 +26,124 @@ package com.github.creeper123123321.viafabric.providers; import com.github.creeper123123321.viafabric.ViaFabric; import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; +import com.google.common.primitives.Ints; +import net.minecraft.network.ClientConnection; +import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.exception.CancelException; +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion.protocols.base.BaseProtocol1_16; +import us.myles.ViaVersion.protocols.base.BaseProtocol1_7; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.base.VersionProvider; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.*; +import java.util.stream.IntStream; + public class VRVersionProvider extends VersionProvider { + private Set multiconnectSupportedVersions = null; + + { + try { + Class mcApiClass = Class.forName("net.earthcomputer.multiconnect.api.MultiConnectAPI"); + Class iProtocolClass = Class.forName("net.earthcomputer.multiconnect.api.IProtocol"); + Object mcApiInstance = mcApiClass.getMethod("instance").invoke(null); + List protocols = (List) mcApiClass.getMethod("getSupportedProtocols").invoke(mcApiInstance); + Method getValue = iProtocolClass.getMethod("getValue"); + multiconnectSupportedVersions = new TreeSet<>(); + for (Object protocol : protocols) { + multiconnectSupportedVersions.add((Integer) getValue.invoke(protocol)); + } + ViaFabric.JLOGGER.info("ViaFabric will integrate with multiconnect"); + } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException + | ClassCastException ignored) { + } + } + @Override public int getServerProtocol(UserConnection connection) throws Exception { - if (connection instanceof VRClientSideUserConnection) - return ViaFabric.config.getClientSideVersion(); + if (connection instanceof VRClientSideUserConnection) { + int clientSideVersion = ViaFabric.config.getClientSideVersion(); + if (connection.getChannel() != null) { + ProtocolInfo info = connection.getProtocolInfo(); + + SocketAddress addr = connection.getChannel().remoteAddress(); + if (addr instanceof InetSocketAddress && (isDisabled(((InetSocketAddress) addr).getHostString()) + || ((((InetSocketAddress) addr).getAddress() != null) && + (isDisabled(((InetSocketAddress) addr).getAddress().getHostAddress()) + || isDisabled(((InetSocketAddress) addr).getAddress().getHostName()))))) { + return -1; + } + + if (info != null + && info.getState() == State.STATUS + && info.getProtocolVersion() == -1 + && clientSideVersion != -1 + && connection.getChannel().pipeline().get(ClientConnection.class).getPacketListener() + .getClass().getName().startsWith("net.earthcomputer.multiconnect")) { // multiconnect version detector + int multiconnectSuggestion = getVersionForMulticonnect(clientSideVersion); + ViaFabric.JLOGGER.info("Sending " + ProtocolVersion.getProtocol(multiconnectSuggestion) + " for multiconnect version detector"); + PacketWrapper newAnswer = new PacketWrapper(0x00, null, connection); + newAnswer.write(Type.STRING, "{\"version\":{\"name\":\"viafabric integration\",\"protocol\":" + multiconnectSuggestion + "}}"); + newAnswer.send(info.getPipeline().contains(BaseProtocol1_16.class) ? BaseProtocol1_16.class : BaseProtocol1_7.class); + throw CancelException.generate(); + } + } + return clientSideVersion; + } return super.getServerProtocol(connection); } + + private int getVersionForMulticonnect(int clientSideVersion) { + // https://github.com/ViaVersion/ViaVersion/blob/master/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java + // multiconnect supports it + int[] compatibleProtocols = multiconnectSupportedVersions.stream().mapToInt(it -> it).toArray(); + if (Arrays.binarySearch(compatibleProtocols, clientSideVersion) >= 0) + return clientSideVersion; + + // Older than multiconnect supports, get the lowest version + if (clientSideVersion < compatibleProtocols[0]) { + return compatibleProtocols[0]; + } + + // Loop through all protocols to get the closest protocol id that multiconnect supports (and that viaversion does too) + + // TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work. + // This is more of a workaround for snapshot support by multiconnect. + for (int i = compatibleProtocols.length - 1; i >= 0; i--) { + int protocol = compatibleProtocols[i]; + if (clientSideVersion > protocol && ProtocolVersion.isRegistered(protocol)) + return protocol; + } + + ViaFabric.JLOGGER.severe("multiconnect integration: Panic, no protocol id found for " + clientSideVersion); + return clientSideVersion; + } + + private boolean isDisabled(String addr) { + String[] parts = addr.split("\\."); + boolean isNumericIp = parts.length == 4 && Arrays.stream(parts).map(Ints::tryParse).allMatch(Objects::nonNull); + return IntStream.range(0, parts.length).anyMatch(i -> { + String query; + if (isNumericIp) { + query = String.join(".", Arrays.stream(parts, 0, i + 1) + .toArray(String[]::new)) + ((i != 3) ? ".*" : ""); + } else { + query = ((i != 0) ? "*." : "") + String.join(".", Arrays.stream(parts, i, parts.length) + .toArray(String[]::new)); + } + if (ViaFabric.config.isForcedDisable(query)) { + ViaFabric.JLOGGER.info(addr + " is force-disabled. (Matches " + query + ")"); + return true; + } else { + return false; + } + }); + } } diff --git a/src/main/resources/assets/viafabric/config.yml b/src/main/resources/assets/viafabric/config.yml index 32f38e9..186e22f 100644 --- a/src/main/resources/assets/viafabric/config.yml +++ b/src/main/resources/assets/viafabric/config.yml @@ -3,4 +3,8 @@ # This option enables client-side transforming (can also be enabled in-game) enable-client-side: false # This option sets the protocol version to be used when connection to the server (can also be changed in-game) -client-side-version: -1 \ No newline at end of file +client-side-version: -1 +# List of servers which ViaFabric will force disabling transforming on client-side. +# This isn't always the address in multiplayer GUI. It will use the SRV record pointer when present. Check the game log for the address. +# Uses https://wiki.vg/Mojang_API#Blocked_Servers format (mc.example.com, *.example.com, 192.168.0.1, 192.168.*) +client-side-force-disable: ["hypixel.net", "*.hypixel.net", "hivemc.com", "*.hivemc.com", "hivemc.eu", "*.hivemc.eu"] \ No newline at end of file