From 8c430d57f682e5b2d99378c81358ce63b87bab4a Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Fri, 8 Feb 2019 17:46:37 -0200 Subject: [PATCH] untested server side injecting --- build.gradle | 13 +- .../viafabric/VRViaVersionInitializer.java | 42 ++++++ .../creeper123123321/viafabric/ViaFabric.java | 58 ++++----- .../viafabric/commands/NMSCommandSender.java | 80 ++++++++++++ .../UserCommandSender.java} | 20 +-- .../{ => clientside}/VRDecodeHandler.java | 2 +- .../{ => clientside}/VREncodeHandler.java | 2 +- .../serverside/FabricDecodeHandler.java | 122 ++++++++++++++++++ .../serverside/FabricEncodeHandler.java | 96 ++++++++++++++ .../MixinClientConnectionServerChInit.java | 57 ++++++++ .../client/MixinClientConnectionChInit.java | 12 +- .../mixin/client/MixinMultiplayerGui.java | 8 +- ...n.java => VRClientSideUserConnection.java} | 4 +- .../viafabric/platform/VRPlatform.java | 64 +++++---- .../protocol/ClientSideInterceptor.java | 39 ++++++ .../viafabric/protocol/Interceptor.java | 68 ---------- src/main/resources/fabric.mod.json | 8 +- ...main.json => mixins.viafabric.client.json} | 0 .../resources/mixins.viafabric.common.json | 11 ++ 19 files changed, 558 insertions(+), 148 deletions(-) create mode 100644 src/main/java/com/github/creeper123123321/viafabric/commands/NMSCommandSender.java rename src/main/java/com/github/creeper123123321/viafabric/{platform/VRCommandSender.java => commands/UserCommandSender.java} (75%) rename src/main/java/com/github/creeper123123321/viafabric/handler/{ => clientside}/VRDecodeHandler.java (98%) rename src/main/java/com/github/creeper123123321/viafabric/handler/{ => clientside}/VREncodeHandler.java (98%) create mode 100644 src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricDecodeHandler.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricEncodeHandler.java create mode 100644 src/main/java/com/github/creeper123123321/viafabric/mixin/MixinClientConnectionServerChInit.java rename src/main/java/com/github/creeper123123321/viafabric/platform/{VRUserConnection.java => VRClientSideUserConnection.java} (96%) create mode 100644 src/main/java/com/github/creeper123123321/viafabric/protocol/ClientSideInterceptor.java delete mode 100644 src/main/java/com/github/creeper123123321/viafabric/protocol/Interceptor.java rename src/main/resources/{mixins.viafabric.main.json => mixins.viafabric.client.json} (100%) create mode 100644 src/main/resources/mixins.viafabric.common.json diff --git a/build.gradle b/build.gradle index d82498c..bffef4f 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,7 @@ repositories { maven { url 'https://repo.viaversion.com/' } maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } maven { url 'https://maven.fabricmc.net/' } + maven { url "http://server.bbkr.space:8081/artifactory/libs-snapshot" } } processResources { @@ -34,9 +35,15 @@ dependencies { compile "us.myles:viaversion:2.0.0-19w04a" compile "de.gerrygames:viarewind-all:1.4.0" - minecraft "com.mojang:minecraft:19w04a" - mappings "net.fabricmc:yarn:19w04a.1" - modCompile "net.fabricmc:fabric-loader:0.3.3.101" + minecraft "com.mojang:minecraft:19w05a" + mappings "net.fabricmc:yarn:19w05a.6" + + modCompile "net.fabricmc:fabric-loader:0.3.5.106" + + // Fabric API. This is technically optional, but you probably want it anyway. + modCompile "net.fabricmc:fabric:0.1.5.88" + + modCompile "io.github.cottonmc:client-commands:0.1.0+19w05a-SNAPSHOT" } diff --git a/src/main/java/com/github/creeper123123321/viafabric/VRViaVersionInitializer.java b/src/main/java/com/github/creeper123123321/viafabric/VRViaVersionInitializer.java index e880832..b4a2c40 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/VRViaVersionInitializer.java +++ b/src/main/java/com/github/creeper123123321/viafabric/VRViaVersionInitializer.java @@ -24,12 +24,18 @@ package com.github.creeper123123321.viafabric; +import com.github.creeper123123321.viafabric.commands.NMSCommandSender; import com.github.creeper123123321.viafabric.commands.VRCommandHandler; import com.github.creeper123123321.viafabric.platform.VRInjector; import com.github.creeper123123321.viafabric.platform.VRLoader; import com.github.creeper123123321.viafabric.platform.VRPlatform; import com.github.creeper123123321.viafabric.protocol.protocol1_7_6_10to1_7_1_5.Protocol1_7_6_10to1_7_1_5; import com.github.creeper123123321.viafabric.protocol.protocol1_8to1_7_6_10.Protocol1_8TO1_7_6_10; +import com.mojang.brigadier.arguments.StringArgumentType; +import io.github.cottonmc.clientcommands.ArgumentBuilders; +import io.github.cottonmc.clientcommands.ClientCommands; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.FabricLoader; import us.myles.ViaVersion.ViaManager; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; @@ -49,5 +55,41 @@ public class VRViaVersionInitializer { ProtocolRegistry.registerProtocol(new Protocol1_7_6_10to1_7_1_5(), Collections.singletonList(ProtocolVersion.v1_7_6.getId()), ProtocolVersion.v1_7_1.getId()); ProtocolRegistry.registerProtocol(new Protocol1_8TO1_7_6_10(), Collections.singletonList(ProtocolVersion.v1_8.getId()), ProtocolVersion.v1_7_6.getId()); }); + + + if (FabricLoader.INSTANCE.getEnvironmentType() == EnvType.CLIENT) { + ClientCommands.registerCommand(command -> command + .register( + ArgumentBuilders.literal("viafabric") + .then( + ArgumentBuilders + .argument("args", StringArgumentType.greedyString()) + .executes(ctx -> { + String args = StringArgumentType.getString(ctx, "args"); + Via.getManager() + .getCommandHandler() + .onCommand( + new NMSCommandSender(ctx.getSource()), + args.split(" ", -1) + ); + return 1; + }) + .suggests((ctx, builder) -> { + String args = StringArgumentType.getString(ctx, "args"); + Via.getManager() + .getCommandHandler() + .onTabComplete( + new NMSCommandSender( + ctx.getSource() + ), + args.split(" ", -1) + ) + .forEach(builder::suggest); + return builder.buildFuture(); + }) + ) + ) + ); + } } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java b/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java index 2a2aaf5..eb84e30 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java +++ b/src/main/java/com/github/creeper123123321/viafabric/ViaFabric.java @@ -30,7 +30,7 @@ import com.google.common.io.CharStreams; import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.channel.DefaultEventLoop; import io.netty.channel.EventLoop; -import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.FabricLoader; import net.minecraft.client.MinecraftClient; import org.apache.commons.codec.digest.DigestUtils; @@ -55,7 +55,7 @@ import java.util.concurrent.ThreadFactory; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ViaFabric implements ClientModInitializer { +public class ViaFabric implements ModInitializer { public static final java.util.logging.Logger JLOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaFabric")); public static final ExecutorService ASYNC_EXECUTOR; public static final EventLoop EVENT_LOOP; @@ -74,33 +74,6 @@ public class ViaFabric implements ClientModInitializer { .get().getInfo().getVersionString(); } - @Override - public void onInitializeClient() { - File viaVersionJar = FabricLoader.INSTANCE.getConfigDirectory().toPath().resolve("ViaFabric").resolve("viaversion.jar").toFile(); - try { - checkForUpdates(viaVersionJar, "viaversion", "us/myles", ""); - } catch (Exception e) { - e.printStackTrace(); - } - File viaRewindJar = FabricLoader.INSTANCE.getConfigDirectory().toPath().resolve("ViaFabric").resolve("viarewind.jar").toFile(); - try { - checkForUpdates(viaRewindJar, "viarewind-all", "de/gerrygames", "ViaRewind"); - } catch (Exception e) { - e.printStackTrace(); - } - try { - Method addUrl = ViaFabric.class.getClassLoader().getClass().getMethod("addURL", URL.class); - addUrl.setAccessible(true); - addUrl.invoke(ViaFabric.class.getClassLoader(), viaVersionJar.toURI().toURL()); - addUrl.invoke(ViaFabric.class.getClassLoader(), viaRewindJar.toURI().toURL()); - Class.forName("com.github.creeper123123321.viafabric.VRViaVersionInitializer") - .getMethod("init") - .invoke(null); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | MalformedURLException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - private void checkForUpdates(File jar, String artifactName, String groupIdPath, String depName) throws Exception { int timeDivisor = 1000 * 60 * 60 * 24; long cachedTime = System.currentTimeMillis() / timeDivisor; @@ -154,4 +127,31 @@ public class ViaFabric implements ClientModInitializer { } } } + + @Override + public void onInitialize() { + File viaVersionJar = FabricLoader.INSTANCE.getConfigDirectory().toPath().resolve("ViaFabric").resolve("viaversion.jar").toFile(); + try { + checkForUpdates(viaVersionJar, "viaversion", "us/myles", ""); + } catch (Exception e) { + e.printStackTrace(); + } + File viaRewindJar = FabricLoader.INSTANCE.getConfigDirectory().toPath().resolve("ViaFabric").resolve("viarewind.jar").toFile(); + try { + checkForUpdates(viaRewindJar, "viarewind-all", "de/gerrygames", "ViaRewind"); + } catch (Exception e) { + e.printStackTrace(); + } + try { + Method addUrl = ViaFabric.class.getClassLoader().getClass().getMethod("addURL", URL.class); + addUrl.setAccessible(true); + addUrl.invoke(ViaFabric.class.getClassLoader(), viaVersionJar.toURI().toURL()); + addUrl.invoke(ViaFabric.class.getClassLoader(), viaRewindJar.toURI().toURL()); + Class.forName("com.github.creeper123123321.viafabric.VRViaVersionInitializer") + .getMethod("init") + .invoke(null); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | MalformedURLException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/commands/NMSCommandSender.java b/src/main/java/com/github/creeper123123321/viafabric/commands/NMSCommandSender.java new file mode 100644 index 0000000..d9c3d4f --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/commands/NMSCommandSender.java @@ -0,0 +1,80 @@ +/* + * 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.commands; + +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.FabricLoader; +import net.minecraft.client.network.ClientCommandSource; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.command.CommandSource; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.TextComponent; +import us.myles.ViaVersion.api.command.ViaCommandSender; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter; + +import java.util.UUID; + +public class NMSCommandSender implements ViaCommandSender { + private 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); + } + + @Override + public void sendMessage(String s) { + if (source instanceof ServerCommandSource) { + ((ServerCommandSource) source).sendFeedback(TextComponent.Serializer.fromJsonString(ChatRewriter.legacyTextToJson(s)), false); + } + } + + @Override + public UUID getUUID() { + if (source instanceof ServerCommandSource) { + Entity entity = ((ServerCommandSource) source).getEntity(); + if (entity != null) return entity.getUuid(); + } else if (FabricLoader.INSTANCE.getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) { + return FabricLoader.INSTANCE.getEnvironmentHandler().getClientPlayer().getUuid(); + } + return UUID.fromString(getName()); + } + + @Override + public String getName() { + if (source instanceof ServerCommandSource) { + return ((ServerCommandSource) source).getName(); + } else if (FabricLoader.INSTANCE.getEnvironmentType() == EnvType.CLIENT && source instanceof ClientCommandSource) { + return FabricLoader.INSTANCE.getEnvironmentHandler().getClientPlayer().getEntityName(); + } + return "?"; + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/platform/VRCommandSender.java b/src/main/java/com/github/creeper123123321/viafabric/commands/UserCommandSender.java similarity index 75% rename from src/main/java/com/github/creeper123123321/viafabric/platform/VRCommandSender.java rename to src/main/java/com/github/creeper123123321/viafabric/commands/UserCommandSender.java index 3180c88..6d36dde 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/platform/VRCommandSender.java +++ b/src/main/java/com/github/creeper123123321/viafabric/commands/UserCommandSender.java @@ -22,20 +22,20 @@ * SOFTWARE. */ -package com.github.creeper123123321.viafabric.platform; +package com.github.creeper123123321.viafabric.commands; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.command.ViaCommandSender; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; import java.util.UUID; -public class VRCommandSender implements ViaCommandSender { - private UUID uuid; - private String name; +public class UserCommandSender implements ViaCommandSender { + private UserConnection con; - public VRCommandSender(UUID uuid, String name) { - this.uuid = uuid; - this.name = name; + public UserCommandSender(UserConnection con) { + this.con = con; } @Override @@ -45,16 +45,16 @@ public class VRCommandSender implements ViaCommandSender { @Override public void sendMessage(String s) { - Via.getPlatform().sendMessage(uuid, s); + Via.getPlatform().sendMessage(getUUID(), s); } @Override public UUID getUUID() { - return uuid; + return con.get(ProtocolInfo.class).getUuid(); } @Override public String getName() { - return name; + return con.get(ProtocolInfo.class).getUsername(); } } diff --git a/src/main/java/com/github/creeper123123321/viafabric/handler/VRDecodeHandler.java b/src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VRDecodeHandler.java similarity index 98% rename from src/main/java/com/github/creeper123123321/viafabric/handler/VRDecodeHandler.java rename to src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VRDecodeHandler.java index 1cb16a3..e5e0cb9 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/handler/VRDecodeHandler.java +++ b/src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VRDecodeHandler.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package com.github.creeper123123321.viafabric.handler; +package com.github.creeper123123321.viafabric.handler.clientside; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; diff --git a/src/main/java/com/github/creeper123123321/viafabric/handler/VREncodeHandler.java b/src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VREncodeHandler.java similarity index 98% rename from src/main/java/com/github/creeper123123321/viafabric/handler/VREncodeHandler.java rename to src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VREncodeHandler.java index 585f159..b3e0f2d 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/handler/VREncodeHandler.java +++ b/src/main/java/com/github/creeper123123321/viafabric/handler/clientside/VREncodeHandler.java @@ -22,7 +22,7 @@ * SOFTWARE. */ -package com.github.creeper123123321.viafabric.handler; +package com.github.creeper123123321.viafabric.handler.clientside; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; diff --git a/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricDecodeHandler.java b/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricDecodeHandler.java new file mode 100644 index 0000000..fce61db --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricDecodeHandler.java @@ -0,0 +1,122 @@ +/* + * 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.handler.serverside; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.exception.CancelException; +import us.myles.ViaVersion.packets.Direction; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.util.PipelineUtil; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +public class FabricDecodeHandler extends ByteToMessageDecoder { + // https://github.com/MylesIsCool/ViaVersion/blob/1abc3ebea66878192b08b577353dff7d619ed51e/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeDecodeHandler.java + private final ByteToMessageDecoder minecraftDecoder; + private final UserConnection info; + + public FabricDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) { + this.info = info; + this.minecraftDecoder = minecraftDecoder; + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List list) throws Exception { + // use transformers + if (bytebuf.readableBytes() > 0) { + // Ignore if pending disconnect + if (info.isPendingDisconnect()) { + return; + } + // Increment received + boolean second = info.incrementReceived(); + // Check PPS + if (second) { + if (info.handlePPS()) + return; + } + + if (info.isActive()) { + // Handle ID + int id = Type.VAR_INT.read(bytebuf); + // Transform + ByteBuf newPacket = ctx.alloc().buffer(); + try { + if (id == PacketWrapper.PASSTHROUGH_ID) { + newPacket.writeBytes(bytebuf); + } else { + PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info); + ProtocolInfo protInfo = info.get(ProtocolInfo.class); + protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper); + wrapper.writeToBuffer(newPacket); + } + + bytebuf.clear(); + bytebuf = newPacket; + } catch (Exception e) { + // Clear Buffer + bytebuf.clear(); + // Release Packet, be free! + newPacket.release(); + throw e; + } + } + + // call minecraft decoder + try { + list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf)); + } catch (InvocationTargetException e) { + if (e.getCause() instanceof Exception) { + throw (Exception) e.getCause(); + } + } finally { + if (info.isActive()) { + bytebuf.release(); + } + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelException.class)) return; + super.exceptionCaught(ctx, cause); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + ProtocolInfo pi = info.get(ProtocolInfo.class); + if (pi.getUuid() != null) { + Via.getManager().removePortedClient(pi.getUuid()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricEncodeHandler.java b/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricEncodeHandler.java new file mode 100644 index 0000000..3839fb2 --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/handler/serverside/FabricEncodeHandler.java @@ -0,0 +1,96 @@ +/* + * 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.handler.serverside; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.exception.CancelException; +import us.myles.ViaVersion.packets.Direction; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.util.PipelineUtil; + +import java.lang.reflect.InvocationTargetException; + +public class FabricEncodeHandler extends MessageToByteEncoder { + // https://github.com/MylesIsCool/ViaVersion/blob/master/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeEncodeHandler.java + private final UserConnection info; + private final MessageToByteEncoder minecraftEncoder; + + public FabricEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) { + this.info = info; + this.minecraftEncoder = minecraftEncoder; + } + + + @Override + protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception { + // handle the packet type + if (!(o instanceof ByteBuf)) { + // call minecraft encoder + try { + PipelineUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf); + } catch (InvocationTargetException e) { + if (e.getCause() instanceof Exception) { + throw (Exception) e.getCause(); + } + } + } + if (bytebuf.readableBytes() == 0) { + throw new CancelException(); + } + // Increment sent + info.incrementSent(); + if (info.isActive()) { + // Handle ID + int id = Type.VAR_INT.read(bytebuf); + // Transform + ByteBuf oldPacket = bytebuf.copy(); + bytebuf.clear(); + + try { + PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info); + ProtocolInfo protInfo = info.get(ProtocolInfo.class); + protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper); + wrapper.writeToBuffer(bytebuf); + } catch (Exception e) { + bytebuf.clear(); + throw e; + } finally { + oldPacket.release(); + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelException.class)) return; + super.exceptionCaught(ctx, cause); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/MixinClientConnectionServerChInit.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/MixinClientConnectionServerChInit.java new file mode 100644 index 0000000..837c07c --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/MixinClientConnectionServerChInit.java @@ -0,0 +1,57 @@ +/* + * 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.mixin; + +import com.github.creeper123123321.viafabric.handler.serverside.FabricDecodeHandler; +import com.github.creeper123123321.viafabric.handler.serverside.FabricEncodeHandler; +import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; +import com.github.creeper123123321.viafabric.protocol.ClientSideInterceptor; +import io.netty.channel.Channel; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.handler.codec.MessageToByteEncoder; +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 us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolPipeline; + +@Mixin(targets = "net.minecraft.server.ServerNetworkIO$1") +public class MixinClientConnectionServerChInit { + @Inject(method = "initChannel(Lio/netty/channel/Channel;)V", at = @At(value = "TAIL"), remap = false) + private void onInitChannel(Channel channel, CallbackInfo ci) { + if (channel instanceof SocketChannel) { + UserConnection user = new VRClientSideUserConnection(channel); + new ProtocolPipeline(user).add(new ClientSideInterceptor()); + + MessageToByteEncoder oldEncoder = (MessageToByteEncoder) channel.pipeline().get("encoder"); + ByteToMessageDecoder oldDecoder = (ByteToMessageDecoder) channel.pipeline().get("decoder"); + + channel.pipeline().replace("encoder", "encoder", new FabricEncodeHandler(user, oldEncoder)); + channel.pipeline().replace("decoder", "decoder", new FabricDecodeHandler(user, oldDecoder)); + } + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java index a7e5941..664eff4 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinClientConnectionChInit.java @@ -24,10 +24,10 @@ package com.github.creeper123123321.viafabric.mixin.client; -import com.github.creeper123123321.viafabric.handler.VRDecodeHandler; -import com.github.creeper123123321.viafabric.handler.VREncodeHandler; -import com.github.creeper123123321.viafabric.platform.VRUserConnection; -import com.github.creeper123123321.viafabric.protocol.Interceptor; +import com.github.creeper123123321.viafabric.handler.clientside.VRDecodeHandler; +import com.github.creeper123123321.viafabric.handler.clientside.VREncodeHandler; +import com.github.creeper123123321.viafabric.platform.VRClientSideUserConnection; +import com.github.creeper123123321.viafabric.protocol.ClientSideInterceptor; import io.netty.channel.Channel; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.ByteToMessageDecoder; @@ -44,8 +44,8 @@ public class MixinClientConnectionChInit { @Inject(method = "initChannel(Lio/netty/channel/Channel;)V", at = @At(value = "TAIL"), remap = false) private void onInitChannel(Channel channel, CallbackInfo ci) { if (channel instanceof SocketChannel) { - UserConnection user = new VRUserConnection(channel); - new ProtocolPipeline(user).add(new Interceptor()); + UserConnection user = new VRClientSideUserConnection(channel); + new ProtocolPipeline(user).add(new ClientSideInterceptor()); MessageToByteEncoder oldEncoder = (MessageToByteEncoder) channel.pipeline().get("encoder"); ByteToMessageDecoder oldDecoder = (ByteToMessageDecoder) channel.pipeline().get("decoder"); diff --git a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinMultiplayerGui.java b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinMultiplayerGui.java index ccf43af..3799626 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinMultiplayerGui.java +++ b/src/main/java/com/github/creeper123123321/viafabric/mixin/client/MixinMultiplayerGui.java @@ -26,9 +26,9 @@ package com.github.creeper123123321.viafabric.mixin.client; import com.github.creeper123123321.viafabric.gui.multiplayer.SaveProtocolButton; import com.github.creeper123123321.viafabric.util.VersionFormatFilter; -import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiEventListener; -import net.minecraft.client.gui.menu.MultiplayerGui; +import net.minecraft.client.gui.Screen; +import net.minecraft.client.gui.menu.MultiplayerScreen; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.resource.language.I18n; import org.spongepowered.asm.mixin.Mixin; @@ -39,8 +39,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; -@Mixin(MultiplayerGui.class) -public abstract class MixinMultiplayerGui extends Gui { +@Mixin(MultiplayerScreen.class) +public abstract class MixinMultiplayerGui extends Screen { private TextFieldWidget protocolVersion; @Inject(method = "onInitialized", at = @At("TAIL")) diff --git a/src/main/java/com/github/creeper123123321/viafabric/platform/VRUserConnection.java b/src/main/java/com/github/creeper123123321/viafabric/platform/VRClientSideUserConnection.java similarity index 96% rename from src/main/java/com/github/creeper123123321/viafabric/platform/VRUserConnection.java rename to src/main/java/com/github/creeper123123321/viafabric/platform/VRClientSideUserConnection.java index ee27754..9fe18ba 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/platform/VRUserConnection.java +++ b/src/main/java/com/github/creeper123123321/viafabric/platform/VRClientSideUserConnection.java @@ -33,8 +33,8 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.util.PipelineUtil; -public class VRUserConnection extends UserConnection { - public VRUserConnection(Channel socketChannel) { +public class VRClientSideUserConnection extends UserConnection { + public VRClientSideUserConnection(Channel socketChannel) { super(socketChannel); } // Based on https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/reflection/Injector.java 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 ed197d4..6392996 100644 --- a/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java +++ b/src/main/java/com/github/creeper123123321/viafabric/platform/VRPlatform.java @@ -25,10 +25,15 @@ package com.github.creeper123123321.viafabric.platform; import com.github.creeper123123321.viafabric.ViaFabric; -import com.github.creeper123123321.viafabric.protocol.Interceptor; +import com.github.creeper123123321.viafabric.commands.UserCommandSender; +import com.github.creeper123123321.viafabric.protocol.ClientSideInterceptor; import com.github.creeper123123321.viafabric.util.FutureTaskId; import net.fabricmc.loader.FabricLoader; import net.fabricmc.loader.ModContainer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sortme.ChatMessageType; +import net.minecraft.text.TextComponent; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.ViaAPI; @@ -144,39 +149,54 @@ public class VRPlatform implements ViaPlatform { @Override public ViaCommandSender[] getOnlinePlayers() { - return Via.getManager().getPortedPlayers().values().stream().map(it -> { - ProtocolInfo info = it.get(ProtocolInfo.class); - return new VRCommandSender(info.getUuid(), info.getUsername()); - }).toArray(ViaCommandSender[]::new); + return Via.getManager().getPortedPlayers().values().stream() + .map(UserCommandSender::new) + .toArray(ViaCommandSender[]::new); } @Override public void sendMessage(UUID uuid, String s) { UserConnection user = Via.getManager().getPortedPlayers().get(uuid); - PacketWrapper chat = new PacketWrapper(0x0E, null, user); - chat.write(Type.STRING, ChatRewriter.legacyTextToJson(s)); - chat.write(Type.BYTE, (byte) 0); // Position chat box - try { - chat.send(Interceptor.class); - } catch (CancelException e) { - // Ignore - } catch (Exception e) { - e.printStackTrace(); + if (user instanceof VRClientSideUserConnection) { + PacketWrapper chat = new PacketWrapper(0x0E, null, user); + chat.write(Type.STRING, ChatRewriter.legacyTextToJson(s)); + chat.write(Type.BYTE, (byte) 0); // Position chat box + try { + chat.send(ClientSideInterceptor.class); + } catch (CancelException e) { + // Ignore + } catch (Exception e) { + e.printStackTrace(); + } + } else { + MinecraftServer server = FabricLoader.INSTANCE.getEnvironmentHandler().getServerInstance(); + if (server == null) return ; + ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid); + if (player == null) return; + player.sendChatMessage(TextComponent.Serializer.fromJsonString(ChatRewriter.legacyTextToJson(s)), ChatMessageType.SYSTEM); } } @Override public boolean kickPlayer(UUID uuid, String s) { UserConnection user = Via.getManager().getPortedPlayers().get(uuid); - PacketWrapper chat = new PacketWrapper(0x1B, null, user); - chat.write(Type.STRING, ChatRewriter.legacyTextToJson(s)); - try { - chat.sendFuture(Interceptor.class).addListener(future -> user.getChannel().close()); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; + if (user instanceof VRClientSideUserConnection) { + PacketWrapper chat = new PacketWrapper(0x1B, null, user); + chat.write(Type.STRING, ChatRewriter.legacyTextToJson(s)); + try { + chat.sendFuture(ClientSideInterceptor.class).addListener(future -> user.getChannel().close()); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + MinecraftServer server = FabricLoader.INSTANCE.getEnvironmentHandler().getServerInstance(); + if (server == null) return false; + ServerPlayerEntity player = server.getPlayerManager().getPlayer(uuid); + if (player == null) return false; + player.networkHandler.disconnect(TextComponent.Serializer.fromJsonString(ChatRewriter.legacyTextToJson(s))); } + return true; } @Override diff --git a/src/main/java/com/github/creeper123123321/viafabric/protocol/ClientSideInterceptor.java b/src/main/java/com/github/creeper123123321/viafabric/protocol/ClientSideInterceptor.java new file mode 100644 index 0000000..40a1270 --- /dev/null +++ b/src/main/java/com/github/creeper123123321/viafabric/protocol/ClientSideInterceptor.java @@ -0,0 +1,39 @@ +/* + * 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.protocol; + +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.Protocol; + +public class ClientSideInterceptor extends Protocol { + @Override + protected void registerPackets() { + } + + @Override + public void init(UserConnection userConnection) { + + } +} diff --git a/src/main/java/com/github/creeper123123321/viafabric/protocol/Interceptor.java b/src/main/java/com/github/creeper123123321/viafabric/protocol/Interceptor.java deleted file mode 100644 index f0a81df..0000000 --- a/src/main/java/com/github/creeper123123321/viafabric/protocol/Interceptor.java +++ /dev/null @@ -1,68 +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.protocol; - -import com.github.creeper123123321.viafabric.platform.VRCommandSender; -import us.myles.ViaVersion.api.PacketWrapper; -import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.data.UserConnection; -import us.myles.ViaVersion.api.protocol.Protocol; -import us.myles.ViaVersion.api.remapper.PacketHandler; -import us.myles.ViaVersion.api.remapper.PacketRemapper; -import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.base.ProtocolInfo; - -public class Interceptor extends Protocol { - @Override - protected void registerPackets() { - // Chat message - registerIncoming(State.PLAY, 0x02, 0x02, new PacketRemapper() { - @Override - public void registerMap() { - map(Type.STRING); - handler(new PacketHandler() { - @Override - public void handle(PacketWrapper packetWrapper) throws Exception { - String msg = packetWrapper.get(Type.STRING, 0); - ProtocolInfo info = packetWrapper.user().get(ProtocolInfo.class); - if (msg.startsWith("/viafabric")) { - Via.getManager().getCommandHandler().onCommand( - new VRCommandSender(info.getUuid(), info.getUsername()), - msg.length() == 10 ? new String[0] : msg.substring(11).split(" ", -1) - ); - packetWrapper.cancel(); - } - } - }); - } - }); - } - - @Override - public void init(UserConnection userConnection) { - - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 009b402..71e291f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,12 +1,16 @@ { "id": "viafabric", "name": "ViaFabric", - "side": "client", + "side": "universal", "version": "@version@", "initializers": [ "com.github.creeper123123321.viafabric.ViaFabric" ], + "requires": { + "fabric": "*" + }, "mixins": { - "client": "mixins.viafabric.main.json" + "common": "mixins.viafabric.common.json", + "client": "mixins.viafabric.client.json" } } diff --git a/src/main/resources/mixins.viafabric.main.json b/src/main/resources/mixins.viafabric.client.json similarity index 100% rename from src/main/resources/mixins.viafabric.main.json rename to src/main/resources/mixins.viafabric.client.json diff --git a/src/main/resources/mixins.viafabric.common.json b/src/main/resources/mixins.viafabric.common.json new file mode 100644 index 0000000..b19ddbe --- /dev/null +++ b/src/main/resources/mixins.viafabric.common.json @@ -0,0 +1,11 @@ +{ + "required": true, + "compatibilityLevel": "JAVA_8", + "package": "com.github.creeper123123321.viafabric.mixin", + "mixins": [ + "MixinClientConnectionServerChInit" + ], + "injectors": { + "defaultRequire": 1 + } +}