Clean up and restructure the replay sender

Add a ReplayFile class for easy reading of replay files
This commit is contained in:
johni0702
2015-05-10 12:31:01 +02:00
parent 2fe3e2091b
commit 136761b424
11 changed files with 764 additions and 511 deletions

View File

@@ -0,0 +1,117 @@
package eu.crushedpixel.replaymod.utils;
import com.google.common.base.Supplier;
import com.google.gson.Gson;
import eu.crushedpixel.replaymod.holders.KeyframeSet;
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
public class ReplayFile extends ZipFile {
public static final String TEMP_FILE_EXTENSION = ".tmcpr";
public static final String JSON_FILE_EXTENSION = ".json";
public static final String ZIP_FILE_EXTENSION = ".mcpr";
public static final String ENTRY_RECORDING = "recording" + TEMP_FILE_EXTENSION;
public static final String ENTRY_METADATA = "metaData" + JSON_FILE_EXTENSION;
public static final String ENTRY_PATHS = "paths";
public static final String ENTRY_THUMB = "thumb";
private final File file;
public ReplayFile(File f) throws IOException {
super(f);
this.file = f;
}
public File getFile() {
return file;
}
public ZipArchiveEntry recordingEntry() {
return getEntry(ENTRY_RECORDING);
}
public Supplier<InputStream> recording() {
return new Supplier<InputStream>() {
@Override
public InputStream get() {
try {
return getInputStream(recordingEntry());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
public ZipArchiveEntry metadataEntry() {
return getEntry(ENTRY_METADATA);
}
public Supplier<ReplayMetaData> metadata() {
return new Supplier<ReplayMetaData>() {
@Override
public ReplayMetaData get() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(metadataEntry())));
return new Gson().fromJson(reader, ReplayMetaData.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
public ZipArchiveEntry pathsEntry() {
return getEntry(ENTRY_PATHS);
}
public Supplier<KeyframeSet[]> paths() {
return new Supplier<KeyframeSet[]>() {
@Override
public KeyframeSet[] get() {
try {
ZipArchiveEntry entry = pathsEntry();
if (entry == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(entry)));
return new Gson().fromJson(reader, KeyframeSet[].class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
public ZipArchiveEntry thumbEntry() {
return getEntry(ENTRY_THUMB);
}
public Supplier<BufferedImage> thumb() {
return new Supplier<BufferedImage>() {
@Override
public BufferedImage get() {
try {
ZipArchiveEntry entry = thumbEntry();
if (entry == null) {
return null;
}
InputStream is = getInputStream(entry);
int i = 7;
while (i > 0) {
i -= is.skip(i); // Security through obscurity \o/
}
return ImageIO.read(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
}

View File

@@ -1,11 +1,9 @@
package eu.crushedpixel.replaymod.utils;
import akka.japi.Pair;
import com.google.gson.Gson;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.holders.KeyframeSet;
import eu.crushedpixel.replaymod.holders.PacketData;
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
import eu.crushedpixel.replaymod.recording.PacketSerializer;
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
import io.netty.buffer.ByteBuf;
@@ -16,8 +14,6 @@ import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.S01PacketJoinGame;
import net.minecraft.network.play.server.S08PacketPlayerPosLook;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FilenameUtils;
import java.io.*;
@@ -54,28 +50,13 @@ public class ReplayFileIO {
List<File> files = new ArrayList<File>();
File folder = getReplayFolder();
for(File file : folder.listFiles()) {
if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(
ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(ReplayFile.ZIP_FILE_EXTENSION)) {
files.add(file);
}
}
return files;
}
private static DataInputStream getMetaDataInputStream(File replayFile) throws IOException {
ZipFile archive = null;
try {
archive = new ZipFile(replayFile);
ZipArchiveEntry tmcpr = archive.getEntry("metaData" +
ConnectionEventHandler.JSON_FILE_EXTENSION);
return new DataInputStream(archive.getInputStream(tmcpr));
} catch(IOException e) {
throw e;
}
}
public static void writeReplayFile(File replayFile, File tempFile, ReplayMetaData metaData) throws IOException {
byte[] buffer = new byte[1024];
@@ -88,13 +69,13 @@ public class ReplayFileIO {
String json = new Gson().toJson(metaData);
zos.putNextEntry(new ZipEntry("metaData.json"));
zos.putNextEntry(new ZipEntry(ReplayFile.ENTRY_METADATA));
PrintWriter pw = new PrintWriter(zos);
pw.write(json);
pw.flush();
zos.closeEntry();
zos.putNextEntry(new ZipEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION));
zos.putNextEntry(new ZipEntry(ReplayFile.ENTRY_RECORDING));
FileInputStream fis = new FileInputStream(tempFile);
int len;
while((len = fis.read(buffer)) > 0) {
@@ -107,26 +88,13 @@ public class ReplayFileIO {
zos.close();
}
private static Pair<Long, DataInputStream> getTempFileInputStream(File replayFile) throws Exception {
ZipFile archive = null;
try {
archive = new ZipFile(replayFile);
ZipArchiveEntry tmcpr = archive.getEntry("recording" +
ConnectionEventHandler.TEMP_FILE_EXTENSION);
long size = tmcpr.getSize();
return new Pair<Long, DataInputStream>(size, new DataInputStream(archive.getInputStream(tmcpr)));
} catch(Exception e) {
throw e;
}
}
public static ReplayMetaData getMetaData(File replayFile) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(getMetaDataInputStream(replayFile)));
String json = br.readLine();
return new Gson().fromJson(json, ReplayMetaData.class);
ReplayFile file = new ReplayFile(replayFile);
try {
return file.metadata().get();
} finally {
file.close();
}
}
/**
@@ -138,12 +106,13 @@ public class ReplayFileIO {
if(replayFile == lastReplayFile) {
return lastContainsJoinPacket;
}
ReplayFile file = null;
lastReplayFile = replayFile;
lastContainsJoinPacket = false;
try {
Pair<Long, DataInputStream> pair = getTempFileInputStream(replayFile);
dis = pair.second();
file = new ReplayFile(replayFile);
dis = new DataInputStream(file.recording().get());
PacketData pd = readPacketData(dis);
while(dis.available() > 0) {
Packet p = deserializePacket(pd.getByteArray());
@@ -163,8 +132,10 @@ public class ReplayFileIO {
if(dis != null) {
dis.close();
}
} catch(Exception e) {
}
if (file != null) {
file.close();
}
} catch(Exception ignored) {}
}
return false;
@@ -238,6 +209,7 @@ public class ReplayFileIO {
RandomAccessFile raf = null;
DataInputStream dis = null;
ReplayFile file = null;
boolean bounds = false;
int lower = 0, upper = 0;
@@ -255,10 +227,10 @@ public class ReplayFileIO {
outputFile.createNewFile();
}
raf = new RandomAccessFile(outputFile, "rw");
file = new ReplayFile(replayFile);
Pair<Long, DataInputStream> pair = getTempFileInputStream(replayFile);
dis = pair.second();
long fileLength = pair.first();
dis = new DataInputStream(file.recording().get());
long fileLength = file.recordingEntry().getSize();
raf.setLength(fileLength);
@@ -300,8 +272,10 @@ public class ReplayFileIO {
if(dis != null) {
dis.close();
}
} catch(Exception e) {
}
if(file != null) {
file.close();
}
} catch(Exception ignored) {}
}
return false;