Fix packet re-encoding in pre-1.13 versions

This commit is contained in:
Jonas Herzig
2019-03-11 18:16:23 +01:00
parent 32de147ae2
commit 9d315134fc

View File

@@ -6,11 +6,11 @@ import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Restrictions; import com.replaymod.core.utils.Restrictions;
import com.replaymod.replay.camera.CameraEntity; import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replaystudio.io.ReplayInputStream; import com.replaymod.replaystudio.io.ReplayInputStream;
import com.replaymod.replaystudio.io.ReplayOutputStream;
import com.replaymod.replaystudio.replay.ReplayFile; import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.studio.ReplayStudio; import com.replaymod.replaystudio.studio.ReplayStudio;
import com.replaymod.replaystudio.studio.protocol.StudioCodec;
import com.replaymod.replaystudio.studio.protocol.StudioSession;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandler.Sharable;
@@ -125,9 +125,6 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
private static int TP_DISTANCE_LIMIT = 128; private static int TP_DISTANCE_LIMIT = 128;
private static final ByteBuf byteBuf = Unpooled.buffer();
private static final ByteBufOutputStream byteBufOut = new ByteBufOutputStream(byteBuf);
/** /**
* The replay handler responsible for the current replay. * The replay handler responsible for the current replay.
*/ */
@@ -170,11 +167,6 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
*/ */
protected ReplayInputStream replayIn; protected ReplayInputStream replayIn;
/**
* @see PacketData#PacketData(ReplayInputStream, ReplayOutputStream)
*/
private ReplayOutputStream encoder;
/** /**
* The next packet that should be sent. * The next packet that should be sent.
* This is required as some actions such as jumping to a specified timestamp have to peek at the next packet. * This is required as some actions such as jumping to a specified timestamp have to peek at the next packet.
@@ -862,7 +854,6 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
synchronized (FullReplaySender.this) { synchronized (FullReplaySender.this) {
if (replayIn == null) { if (replayIn == null) {
replayIn = replayFile.getPacketData(new ReplayStudio(), true); replayIn = replayFile.getPacketData(new ReplayStudio(), true);
encoder = new ReplayOutputStream(new ReplayStudio(), byteBufOut, true);
} }
// Packet loop // Packet loop
while (true) { while (true) {
@@ -889,7 +880,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
// Read the next packet if we don't already have one // Read the next packet if we don't already have one
if (nextPacket == null) { if (nextPacket == null) {
nextPacket = new PacketData(replayIn, encoder); nextPacket = new PacketData(replayIn, loginPhase);
} }
int nextTimeStamp = nextPacket.timestamp; int nextTimeStamp = nextPacket.timestamp;
@@ -1064,7 +1055,6 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
if (replayIn == null) { if (replayIn == null) {
replayIn = replayFile.getPacketData(new ReplayStudio(), true); replayIn = replayFile.getPacketData(new ReplayStudio(), true);
encoder = new ReplayOutputStream(new ReplayStudio(), byteBufOut, true);
} }
while (true) { // Send packets while (true) { // Send packets
@@ -1076,7 +1066,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
nextPacket = null; nextPacket = null;
} else { } else {
// Otherwise read one from the input stream // Otherwise read one from the input stream
pd = new PacketData(replayIn, encoder); pd = new PacketData(replayIn, loginPhase);
} }
int nextTimeStamp = pd.timestamp; int nextTimeStamp = pd.timestamp;
@@ -1209,10 +1199,14 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
} }
private static final class PacketData { private static final class PacketData {
private static final com.github.steveice10.netty.buffer.ByteBuf byteBuf = com.github.steveice10.netty.buffer.Unpooled.buffer();
private static final StudioCodec codecLoginPhase = new StudioCodec(new StudioSession(new ReplayStudio(), false, true));
private static final StudioCodec codecPlayPhase = new StudioCodec(new StudioSession(new ReplayStudio(), false, false));
private final int timestamp; private final int timestamp;
private final byte[] bytes; private final byte[] bytes;
PacketData(ReplayInputStream in, ReplayOutputStream encoder) throws IOException { PacketData(ReplayInputStream in, boolean loginPhase) throws IOException {
com.replaymod.replaystudio.PacketData data = in.readPacket(); com.replaymod.replaystudio.PacketData data = in.readPacket();
timestamp = (int) data.getTime(); timestamp = (int) data.getTime();
// We need to re-encode MCProtocolLib packets, so we can later decode them as NMS packets // We need to re-encode MCProtocolLib packets, so we can later decode them as NMS packets
@@ -1222,10 +1216,12 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
byteBuf.markReaderIndex(); // Mark the current reader and writer index (should be at start) byteBuf.markReaderIndex(); // Mark the current reader and writer index (should be at start)
byteBuf.markWriterIndex(); byteBuf.markWriterIndex();
encoder.write(data); // Re-encode packet, data will end up in byteBuf try {
encoder.flush(); (loginPhase ? codecLoginPhase : codecPlayPhase).encode(null, data.getPacket(), byteBuf);
} catch (Exception e) {
throw new IOException(e);
}
byteBuf.skipBytes(8); // Skip packet length & timestamp
bytes = new byte[byteBuf.readableBytes()]; // Create bytes array of sufficient size bytes = new byte[byteBuf.readableBytes()]; // Create bytes array of sufficient size
byteBuf.readBytes(bytes); // Read all data into bytes byteBuf.readBytes(bytes); // Read all data into bytes