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.
This commit is contained in:
@@ -3,6 +3,7 @@ package com.replaymod.core.gui;
|
|||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.replaymod.replaystudio.PacketData;
|
import com.replaymod.replaystudio.PacketData;
|
||||||
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.replay.ReplayMetaData;
|
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||||
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
||||||
@@ -45,15 +46,19 @@ public class RestoreReplayGui extends AbstractGuiScreen<RestoreReplayGui> {
|
|||||||
ReplayMetaData metaData = replayFile.getMetaData();
|
ReplayMetaData metaData = replayFile.getMetaData();
|
||||||
if (metaData != null && metaData.getDuration() == 0) {
|
if (metaData != null && metaData.getDuration() == 0) {
|
||||||
// Try to restore replay duration
|
// 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;
|
PacketData last = null;
|
||||||
while ((last = in.readPacket()) != null) {
|
while ((last = in.readPacket()) != null) {
|
||||||
metaData.setDuration((int) last.getTime());
|
metaData.setDuration((int) last.getTime());
|
||||||
|
out.write(last);
|
||||||
}
|
}
|
||||||
replayFile.writeMetaData(metaData);
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
// Write back the actual duration
|
||||||
|
replayFile.writeMetaData(metaData);
|
||||||
}
|
}
|
||||||
replayFile.save();
|
replayFile.save();
|
||||||
replayFile.close();
|
replayFile.close();
|
||||||
|
|||||||
Reference in New Issue
Block a user