Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix server side for fabric #1026

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@
import com.github.retrooper.packetevents.util.LogManager;
import com.github.retrooper.packetevents.util.mappings.GlobalRegistryHolder;
import com.github.retrooper.packetevents.util.reflection.ReflectionObject;
import io.github.retrooper.packetevents.handler.PacketDecoder;
import io.github.retrooper.packetevents.handler.PacketEncoder;
import io.github.retrooper.packetevents.handler.PacketEventsClientDecoder;
import io.github.retrooper.packetevents.handler.PacketEventsClientEncoder;
import io.github.retrooper.packetevents.handler.PacketEventsServerDecoder;
import io.github.retrooper.packetevents.handler.PacketEventsServerEncoder;
import io.github.retrooper.packetevents.impl.netty.NettyManagerImpl;
import io.github.retrooper.packetevents.impl.netty.manager.player.PlayerManagerAbstract;
import io.github.retrooper.packetevents.impl.netty.manager.protocol.ProtocolManagerAbstract;
import io.github.retrooper.packetevents.impl.netty.manager.server.ServerManagerAbstract;
import io.github.retrooper.packetevents.injector.CustomPipelineUtil;
import io.netty.channel.Channel;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.Connection;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -100,9 +105,13 @@ public Object getRegistryCacheKey(User user, ClientVersion version) {
private final PlayerManagerAbstract playerManager = new PlayerManagerAbstract() {
@Override
public int getPing(@NotNull Object player) {
String name = ((LocalPlayer) player).getGameProfile().getName();
String name = ((Player) player).getGameProfile().getName();
try {
return ((LocalPlayer) player).connection.getPlayerInfo(name).getLatency();
if (player instanceof LocalPlayer localPlayer) {
return localPlayer.connection.getPlayerInfo(name).getLatency();
} else {
return ((ServerPlayer) player).connection.latency();
}
} catch (Exception ex) {
PacketEvents.getAPI().getLogManager().debug("Failed to get ping for player " + name);
return -1;
Expand Down Expand Up @@ -136,20 +145,29 @@ public void uninject() {
@Override
public void updateUser(Object ch, User user) {
Channel channel = (Channel) ch;
PacketDecoder decoder = (PacketDecoder) channel.pipeline().get(PacketEvents.DECODER_NAME);
PacketEventsServerDecoder decoder = (PacketEventsServerDecoder) channel.pipeline().get(PacketEvents.DECODER_NAME);
decoder.user = user;
PacketEncoder encoder = (PacketEncoder) channel.pipeline().get(PacketEvents.ENCODER_NAME);
PacketEventsServerEncoder encoder = (PacketEventsServerEncoder) channel.pipeline().get(PacketEvents.ENCODER_NAME);
encoder.user = user;
}

@Override
public void setPlayer(Object ch, Object player) {
Channel channel = (Channel) ch;
PacketDecoder decoder = (PacketDecoder) channel.pipeline().get(PacketEvents.DECODER_NAME);
decoder.player = (LocalPlayer) player;

PacketEncoder encoder = (PacketEncoder) channel.pipeline().get(PacketEvents.ENCODER_NAME);
encoder.player = (LocalPlayer) player;
if (player instanceof LocalPlayer localPlayer) {
PacketEventsClientDecoder decoder = (PacketEventsClientDecoder) channel.pipeline().get(PacketEvents.DECODER_NAME);
decoder.player = localPlayer;

PacketEventsClientEncoder encoder = (PacketEventsClientEncoder) channel.pipeline().get(PacketEvents.ENCODER_NAME);
encoder.player = localPlayer;
} else if (player instanceof ServerPlayer serverPlayer) {
PacketEventsServerDecoder decoder = (PacketEventsServerDecoder) channel.pipeline().get(PacketEvents.DECODER_NAME);
decoder.player = serverPlayer;

PacketEventsServerEncoder encoder = (PacketEventsServerEncoder) channel.pipeline().get(PacketEvents.ENCODER_NAME);
encoder.player = serverPlayer;
}
}

@Override
Expand Down Expand Up @@ -194,7 +212,7 @@ public void load() {
public void onPacketPlaySend(PacketPlaySendEvent event) {
if (event.getPacketType() == PacketType.Play.Server.JOIN_GAME) {
PacketEvents.getAPI().getInjector().setPlayer(event.getChannel(),
Minecraft.getInstance().player);
event.getPlayer());
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,23 @@
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.util.PacketEventsImplHelper;
import io.github.retrooper.packetevents.injector.CustomPipelineUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import net.minecraft.client.player.LocalPlayer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@ChannelHandler.Sharable
public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
private static Method DECOMPRESSOR_METHOD, COMPRESSOR_METHOD;
public class PacketEventsClientDecoder extends MessageToMessageDecoder<ByteBuf> {
public User user;
public LocalPlayer player;
public boolean checkedCompression;

public PacketDecoder(User user) {
public PacketEventsClientDecoder(User user) {
this.user = user;
}

Expand Down Expand Up @@ -53,45 +50,30 @@ private boolean handleCompression(ChannelHandlerContext ctx, ByteBuf buffer) {
// Need to decompress this packet due to bad order
ChannelHandler decompressor = ctx.pipeline().get("decompress");
//CompressionDecoder
try {
if (DECOMPRESSOR_METHOD == null) {
DECOMPRESSOR_METHOD = decompressor.getClass().getDeclaredMethod("decode", ChannelHandlerContext.class, ByteBuf.class, List.class);
List<?> list = CustomPipelineUtil.callDecode(decompressor, ctx, buffer);
ByteBuf decompressed = (ByteBuf) list.get(0);
if (buffer != decompressed) {
try {
buffer.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
List<?> list = new ArrayList<>(1);
DECOMPRESSOR_METHOD.invoke(decompressor, ctx, buffer, list);
ByteBuf decompressed = (ByteBuf) list.get(0);
if (buffer != decompressed) {
try {
buffer.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
}
//Relocate handlers
PacketDecoder decoder = (PacketDecoder) ctx.pipeline().remove(PacketEvents.DECODER_NAME);
ctx.pipeline().addAfter("decompress", PacketEvents.DECODER_NAME, decoder);
PacketEncoder encoder = (PacketEncoder) ctx.pipeline().remove(PacketEvents.ENCODER_NAME);
ctx.pipeline().addAfter("compress", PacketEvents.ENCODER_NAME, encoder);
checkedCompression = true;
return true;
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
//Relocate handlers
PacketEventsClientDecoder decoder = (PacketEventsClientDecoder) ctx.pipeline().remove(PacketEvents.DECODER_NAME);
ctx.pipeline().addAfter("decompress", PacketEvents.DECODER_NAME, decoder);
PacketEventsClientEncoder encoder = (PacketEventsClientEncoder) ctx.pipeline().remove(PacketEvents.ENCODER_NAME);
ctx.pipeline().addAfter("compress", PacketEvents.ENCODER_NAME, encoder);
checkedCompression = true;
return true;
}
return false;
}

private void recompress(ChannelHandlerContext ctx, ByteBuf buffer) {
ByteBuf compressed = ctx.alloc().buffer();
try {
ChannelHandler compressor = ctx.pipeline().get("compress");
if (COMPRESSOR_METHOD == null) {
COMPRESSOR_METHOD = compressor.getClass().getDeclaredMethod("encode", ChannelHandlerContext.class, ByteBuf.class, ByteBuf.class);
}
COMPRESSOR_METHOD.invoke(compressor, ctx, buffer, compressed);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
ChannelHandler compressor = ctx.pipeline().get("compress");
CustomPipelineUtil.callEncode(compressor, ctx, buffer, compressed);
try {
buffer.clear().writeBytes(compressed);
PacketEvents.getAPI().getLogManager().debug("Recompressed packet!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
import net.minecraft.client.player.LocalPlayer;

@ChannelHandler.Sharable
public class PacketEncoder extends MessageToByteEncoder<ByteBuf> {
public class PacketEventsClientEncoder extends MessageToByteEncoder<ByteBuf> {
public User user;
public LocalPlayer player;

public PacketEncoder(User user) {
public PacketEventsClientEncoder(User user) {
this.user = user;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.github.retrooper.packetevents.handler;

import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.exception.PacketProcessException;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.util.ExceptionUtil;
import com.github.retrooper.packetevents.util.PacketEventsImplHelper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect;
import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import net.kyori.adventure.text.Component;
import net.minecraft.server.level.ServerPlayer;

import java.util.List;

@ChannelHandler.Sharable
public class PacketEventsServerDecoder extends MessageToMessageDecoder<ByteBuf> {
public User user;
public ServerPlayer player;
public boolean hasBeenRelocated;

public PacketEventsServerDecoder(User user) {
this.user = user;
}

public PacketEventsServerDecoder(PacketEventsServerDecoder decoder) {
user = decoder.user;
player = decoder.player;
hasBeenRelocated = decoder.hasBeenRelocated;
}

public void read(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {
Object buffer = PacketEventsImplHelper.handleServerBoundPacket(ctx.channel(), user, player, input, true);
out.add(ByteBufHelper.retain(buffer));
}

@Override
public void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (buffer.isReadable()) {
read(ctx, buffer, out);
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
//Check if the minecraft server will already print our exception for us.
//Don't print errors during handshake
boolean didWeCauseThis = ExceptionUtil.isException(cause, PacketProcessException.class);
if (didWeCauseThis
&& (user == null || user.getDecoderState() != ConnectionState.HANDSHAKING)) {
if (PacketEvents.getAPI().getSettings().isFullStackTraceEnabled()) {
cause.printStackTrace();
} else {
PacketEvents.getAPI().getLogManager().warn(cause.getMessage());
}

if (PacketEvents.getAPI().getSettings().isKickOnPacketExceptionEnabled()) {
try {
if (user != null) {
user.sendPacket(new WrapperPlayServerDisconnect(Component.text("Invalid packet")));
}
} catch (Exception ignored) { // There may (?) be an exception if the player is in the wrong state...
// Do nothing.
}
ctx.channel().close();
if (player != null) {
player.connection.disconnect(net.minecraft.network.chat.Component.literal("Invalid packet"));
}

if (user != null) {
PacketEvents.getAPI().getLogManager().warn("Disconnected " + user.getProfile().getName() + " due to invalid packet!");
}
}
}
}

@Override
public void userEventTriggered(final ChannelHandlerContext ctx, final Object event) throws Exception {
if (PacketEventsServerEncoder.COMPRESSION_ENABLED_EVENT == null || event != PacketEventsServerEncoder.COMPRESSION_ENABLED_EVENT) {
super.userEventTriggered(ctx, event);
return;
}

// Via changes the order of handlers in this event, so we must respond to Via changing their stuff
ServerConnectionInitializer.relocateHandlers(ctx.channel(), this, user);
super.userEventTriggered(ctx, event);
}

}
Loading