untested server side injecting

This commit is contained in:
creeper123123321 2019-02-08 17:46:37 -02:00
parent e8848372c2
commit 8c430d57f6
No known key found for this signature in database
GPG Key ID: 0AC57D54786721D1
19 changed files with 558 additions and 148 deletions

View File

@ -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"
}

View File

@ -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();
})
)
)
);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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 "?";
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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<Object> 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());
}
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}
}

View File

@ -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");

View File

@ -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"))

View File

@ -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

View File

@ -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

View File

@ -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) {
}
}

View File

@ -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) {
}
}

View File

@ -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"
}
}

View File

@ -0,0 +1,11 @@
{
"required": true,
"compatibilityLevel": "JAVA_8",
"package": "com.github.creeper123123321.viafabric.mixin",
"mixins": [
"MixinClientConnectionServerChInit"
],
"injectors": {
"defaultRequire": 1
}
}