From d2def94fc17b0046ad028324f3560bb5794b28fc Mon Sep 17 00:00:00 2001 From: johni0702 Date: Mon, 23 Jan 2017 17:52:11 +0100 Subject: [PATCH] Fix duration of replays corrupted because of JVM/OS crash A JVM or OS crash can lead to incomplete packets at the end of a recording. The duration of a corrupted replay file is not restored properly if that file contains an incomplete packet. Furthermore, the entity tracker does not load properly with such an incomplete packet. Both bugs are fixed with this commit. To fix these bugs for replays that have already been recovered, simply open them in the Replay Viewer, modify them somehow (save a new path) and force the game to quit forcefully. The replays will be recovered the next time the game starts and both bugs will be fixed. --- .../java/com/replaymod/core/gui/RestoreReplayGui.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/replaymod/core/gui/RestoreReplayGui.java b/src/main/java/com/replaymod/core/gui/RestoreReplayGui.java index c6a4a3d1..d922c1e4 100644 --- a/src/main/java/com/replaymod/core/gui/RestoreReplayGui.java +++ b/src/main/java/com/replaymod/core/gui/RestoreReplayGui.java @@ -3,6 +3,7 @@ package com.replaymod.core.gui; import com.google.common.io.Files; import com.replaymod.replaystudio.PacketData; import com.replaymod.replaystudio.io.ReplayInputStream; +import com.replaymod.replaystudio.io.ReplayOutputStream; import com.replaymod.replaystudio.replay.ReplayFile; import com.replaymod.replaystudio.replay.ReplayMetaData; import com.replaymod.replaystudio.replay.ZipReplayFile; @@ -45,15 +46,19 @@ public class RestoreReplayGui extends AbstractGuiScreen { ReplayMetaData metaData = replayFile.getMetaData(); if (metaData != null && metaData.getDuration() == 0) { // Try to restore replay duration - try (ReplayInputStream in = replayFile.getPacketData()) { + // We need to re-write the packet data in case there are any incomplete packets dangling at the end + try (ReplayInputStream in = replayFile.getPacketData(); + ReplayOutputStream out = replayFile.writePacketData()) { PacketData last = null; while ((last = in.readPacket()) != null) { metaData.setDuration((int) last.getTime()); + out.write(last); } - replayFile.writeMetaData(metaData); } catch (Throwable t) { t.printStackTrace(); } + // Write back the actual duration + replayFile.writeMetaData(metaData); } replayFile.save(); replayFile.close();