Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 16:12:42 +01:00
Add chunk handler to netty pipeline. FIxes #48
Dieser Commit ist enthalten in:
Ursprung
c9e1360951
Commit
b1f076936d
53
src/main/java/us/myles/ViaVersion/handlers/ViaChunkHandler.java
Normale Datei
53
src/main/java/us/myles/ViaVersion/handlers/ViaChunkHandler.java
Normale Datei
@ -0,0 +1,53 @@
|
|||||||
|
package us.myles.ViaVersion.handlers;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||||
|
import us.myles.ViaVersion.ConnectionInfo;
|
||||||
|
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ViaChunkHandler extends MessageToMessageEncoder {
|
||||||
|
private final ConnectionInfo info;
|
||||||
|
|
||||||
|
public ViaChunkHandler(ConnectionInfo info) {
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, Object o, List list) throws Exception {
|
||||||
|
// Split chunk bulk packet up in to single chunk packets before it reached the encoder.
|
||||||
|
// This will prevent issues with several plugins and other protocol handlers due to the chunk being sent twice.
|
||||||
|
// It also sends the chunk in the right order possible resolving some issues with added chunk/block/entity data.
|
||||||
|
if (!(o instanceof ByteBuf)) {
|
||||||
|
info.setLastPacket(o);
|
||||||
|
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
||||||
|
if(o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) {
|
||||||
|
final int[] locX = ReflectionUtil.get(o, "a", int[].class);
|
||||||
|
final int[] locZ = ReflectionUtil.get(o, "b", int[].class);
|
||||||
|
final Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
|
||||||
|
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
|
||||||
|
final Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
|
||||||
|
for(int i = 0; i < locX.length; i++) {
|
||||||
|
int x = locX[i];
|
||||||
|
int z = locZ[i];
|
||||||
|
// world invoke function
|
||||||
|
try {
|
||||||
|
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
|
||||||
|
Object packet = constructor.newInstance(chunk, true, 65535);
|
||||||
|
list.add(packet);
|
||||||
|
} catch(InstantiationException | InvocationTargetException | ClassNotFoundException | IllegalAccessException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.add(o);
|
||||||
|
}
|
||||||
|
}
|
@ -28,38 +28,6 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
|
|||||||
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
|
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
|
||||||
// handle the packet type
|
// handle the packet type
|
||||||
if (!(o instanceof ByteBuf)) {
|
if (!(o instanceof ByteBuf)) {
|
||||||
info.setLastPacket(o);
|
|
||||||
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
|
||||||
if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) {
|
|
||||||
final int[] locX = ReflectionUtil.get(o, "a", int[].class);
|
|
||||||
final int[] locZ = ReflectionUtil.get(o, "b", int[].class);
|
|
||||||
|
|
||||||
final Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
|
|
||||||
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
|
|
||||||
final Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
|
|
||||||
Runnable chunks = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
for (int i = 0; i < locX.length; i++) {
|
|
||||||
int x = locX[i];
|
|
||||||
int z = locZ[i];
|
|
||||||
// world invoke function
|
|
||||||
try {
|
|
||||||
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
|
|
||||||
Object packet = constructor.newInstance(chunk, true, 65535);
|
|
||||||
ctx.pipeline().writeAndFlush(packet);
|
|
||||||
} catch (InstantiationException | InvocationTargetException | ClassNotFoundException | IllegalAccessException | NoSuchMethodException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
chunks.run();
|
|
||||||
bytebuf.clear();
|
|
||||||
throw new CancelException();
|
|
||||||
}
|
|
||||||
// call minecraft encoder
|
// call minecraft encoder
|
||||||
PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
|
PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,10 @@ public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
|
|||||||
// Add our transformers
|
// Add our transformers
|
||||||
ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
|
ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
|
||||||
ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
|
ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
|
||||||
|
ViaChunkHandler chunkHandler = new ViaChunkHandler(info);
|
||||||
|
|
||||||
socketChannel.pipeline().replace("encoder", "encoder", encoder);
|
socketChannel.pipeline().replace("encoder", "encoder", encoder);
|
||||||
socketChannel.pipeline().replace("decoder", "decoder", decoder);
|
socketChannel.pipeline().replace("decoder", "decoder", decoder);
|
||||||
|
socketChannel.pipeline().addAfter("packet_handler", "viaversion_chunk_handler", chunkHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren