diff --git a/build.gradle b/build.gradle index a9783cc0..e957737e 100755 --- a/build.gradle +++ b/build.gradle @@ -69,7 +69,7 @@ dependencies { shade 'org.aspectj:aspectjrt:1.8.2' - shade 'com.github.replaymod:ReplayStudio:2df8d8b' + shade 'com.github.replaymod:ReplayStudio:a2168ca' testCompile 'junit:junit:4.11' } diff --git a/gradle/reprod/checksums.txt b/gradle/reprod/checksums.txt index dfe945dc..a45e657e 100644 --- a/gradle/reprod/checksums.txt +++ b/gradle/reprod/checksums.txt @@ -14,8 +14,8 @@ f98b3e07c6b6a32dd6f9f70f5cef4ac9be42a9a6c850ceb8f33767da94706635 /com/github/joh 03e3dff7f9b3ac6cd3b87684fd36a2f6996a4b164a2f8fab9c22c01cb7bfb84b /com/github/johni0702/gradle-reproducible-builds-plugin/a524ada/gradle-reproducible-builds-plugin-a524ada.pom 75ccc0e24d37ed5b8916e1bcffad1e067c2b1cfa21b635287f968db5c3c1963a /com/github/jponge/lzma-java/1.3/lzma-java-1.3.jar fbcba81b21a8bc3c0761e4798fa05285444b43d681c03c9af49f9b2e1ecb0184 /com/github/jponge/lzma-java/1.3/lzma-java-1.3.pom -f38a7028bbac3f6c6b15cb40d533c96c6e8fdb54fc93d922cfa1931b25fa8c5c /com/github/replaymod/ReplayStudio/2df8d8b/ReplayStudio-2df8d8b.jar -1075c4246911339023a15bc962d6408925b959656443cad3193bbe7ca3dae5fb /com/github/replaymod/ReplayStudio/2df8d8b/ReplayStudio-2df8d8b.pom +04d7ceaf1e83006d2d93518884353a7856399669332d1174f2572e3d6ec03cd3 /com/github/replaymod/ReplayStudio/a2168ca/ReplayStudio-a2168ca.jar +0703ef825f3e3cd0943f6955fd12da923eb255ed94fe421cbb207b2dcfd61ba4 /com/github/replaymod/ReplayStudio/a2168ca/ReplayStudio-a2168ca.pom c6ebd74cd6108b8c372c95b842725ee5bd6d3303ba26cb00f18bc92f80b47956 /com/github/tony19/named-regexp/0.2.3/named-regexp-0.2.3.jar 7cdd89a892927998beab59398ef073232588f6e83e411cf4f0905833bf300487 /com/github/tony19/named-regexp/0.2.3/named-regexp-0.2.3.pom 47c625c83a8cf97b8bbdff2acde923ff8fd3174e62aabcfc5d1b86692594ffba /com/google/api-client/google-api-client/1.22.0/google-api-client-1.22.0.jar diff --git a/src/main/java/com/replaymod/replay/ReplaySender.java b/src/main/java/com/replaymod/replay/ReplaySender.java index 92d97bd4..ebafb8e1 100755 --- a/src/main/java/com/replaymod/replay/ReplaySender.java +++ b/src/main/java/com/replaymod/replay/ReplaySender.java @@ -5,8 +5,12 @@ import com.google.common.io.Files; import com.replaymod.core.ReplayMod; import com.replaymod.core.utils.Restrictions; import com.replaymod.replay.camera.CameraEntity; +import com.replaymod.replaystudio.io.ReplayInputStream; +import com.replaymod.replaystudio.io.ReplayOutputStream; import com.replaymod.replaystudio.replay.ReplayFile; +import com.replaymod.replaystudio.studio.ReplayStudio; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandler.Sharable; @@ -109,10 +113,10 @@ public class ReplaySender extends ChannelDuplexHandler { protected ChannelHandlerContext ctx; /** - * The data input stream from which new packets are read. + * The replay input stream from which new packets are read. * When accessing this stream make sure to synchronize on {@code this} as it's used from multiple threads. */ - protected DataInputStream dis; + protected ReplayInputStream replayIn; /** * The next packet that should be sent. @@ -575,8 +579,8 @@ public class ReplaySender extends ChannelDuplexHandler { REPLAY_LOOP: while (!terminate) { synchronized (ReplaySender.this) { - if (dis == null) { - dis = new DataInputStream(replayFile.getPacketData()); + if (replayIn == null) { + replayIn = replayFile.getPacketData(); } // Packet loop while (true) { @@ -603,7 +607,7 @@ public class ReplaySender extends ChannelDuplexHandler { // Read the next packet if we don't already have one if (nextPacket == null) { - nextPacket = new PacketData(dis); + nextPacket = new PacketData(replayIn); } int nextTimeStamp = nextPacket.timestamp; @@ -660,9 +664,9 @@ public class ReplaySender extends ChannelDuplexHandler { nextPacket = null; lastPacketSent = System.currentTimeMillis(); replayHandler.restartedReplay(); - if (dis != null) { - dis.close(); - dis = null; + if (replayIn != null) { + replayIn.close(); + replayIn = null; } } } @@ -751,17 +755,17 @@ public class ReplaySender extends ChannelDuplexHandler { if (timestamp < lastTimeStamp) { // Restart the replay if we need to go backwards in time hasWorldLoaded = false; lastTimeStamp = 0; - if (dis != null) { - dis.close(); - dis = null; + if (replayIn != null) { + replayIn.close(); + replayIn = null; } startFromBeginning = false; nextPacket = null; replayHandler.restartedReplay(); } - if (dis == null) { - dis = new DataInputStream(replayFile.getPacketData()); + if (replayIn == null) { + replayIn = replayFile.getPacketData(); } while (true) { // Send packets @@ -773,7 +777,7 @@ public class ReplaySender extends ChannelDuplexHandler { nextPacket = null; } else { // Otherwise read one from the input stream - pd = new PacketData(dis); + pd = new PacketData(replayIn); } int nextTimeStamp = pd.timestamp; @@ -788,7 +792,7 @@ public class ReplaySender extends ChannelDuplexHandler { } catch (EOFException eof) { // Shit! We hit the end before finishing our job! What shall we do now? // well, let's just pretend we're done... - dis = null; + replayIn = null; break; } catch (IOException e) { e.printStackTrace(); @@ -918,13 +922,32 @@ public class ReplaySender extends ChannelDuplexHandler { } private static final class PacketData { + private static final ByteBuf byteBuf = Unpooled.buffer(); + private static final ByteBufOutputStream byteBufOut = new ByteBufOutputStream(byteBuf); + private static final ReplayOutputStream encoder = new ReplayOutputStream(new ReplayStudio(), byteBufOut); private final int timestamp; private final byte[] bytes; - public PacketData(DataInputStream in) throws IOException { - timestamp = in.readInt(); - bytes = new byte[in.readInt()]; - in.readFully(bytes); + public PacketData(ReplayInputStream in) throws IOException { + com.replaymod.replaystudio.PacketData data = in.readPacket(); + timestamp = (int) data.getTime(); + // We need to re-encode MCProtocolLib packets, so we can later decode them as NMS packets + // The main reason we aren't reading them as NMS packets is that we want ReplayStudio to be able + // to apply ViaVersion (and potentially other magic) to it. + synchronized (encoder) { + byteBuf.markReaderIndex(); // Mark the current reader and writer index (should be at start) + byteBuf.markWriterIndex(); + + encoder.write(data); // Re-encode packet, data will end up in byteBuf + encoder.flush(); + + byteBuf.skipBytes(8); // Skip packet length & timestamp + bytes = new byte[byteBuf.readableBytes()]; // Create bytes array of sufficient size + byteBuf.readBytes(bytes); // Read all data into bytes + + byteBuf.resetReaderIndex(); // Reset reader & writer index for next use + byteBuf.resetWriterIndex(); + } } } }