Clean up and restructure the replay sender
Add a ReplayFile class for easy reading of replay files
This commit is contained in:
@@ -13,6 +13,7 @@ import eu.crushedpixel.replaymod.registry.UploadedFileHandler;
|
||||
import eu.crushedpixel.replaymod.renderer.SafeEntityRenderer;
|
||||
import eu.crushedpixel.replaymod.replay.ReplaySender;
|
||||
import eu.crushedpixel.replaymod.settings.ReplaySettings;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -158,7 +159,7 @@ public class ReplayMod {
|
||||
File folder = ReplayFileIO.getReplayFolder();
|
||||
|
||||
for(File f : folder.listFiles()) {
|
||||
if(("." + FilenameUtils.getExtension(f.getAbsolutePath())).equals(ConnectionEventHandler.TEMP_FILE_EXTENSION)) {
|
||||
if(("." + FilenameUtils.getExtension(f.getAbsolutePath())).equals(ReplayFile.TEMP_FILE_EXTENSION)) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import eu.crushedpixel.replaymod.api.client.holders.Category;
|
||||
import eu.crushedpixel.replaymod.gui.GuiConstants;
|
||||
import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer;
|
||||
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||
import eu.crushedpixel.replaymod.reflection.MCPNames;
|
||||
import eu.crushedpixel.replaymod.utils.ImageUtils;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ResourceHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
@@ -20,8 +20,6 @@ import net.minecraft.client.gui.GuiTextField;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -30,7 +28,8 @@ import org.lwjgl.input.Keyboard;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -64,30 +63,17 @@ public class GuiUploadFile extends GuiScreen {
|
||||
boolean correctFile = false;
|
||||
this.replayFile = file;
|
||||
|
||||
if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
|
||||
ZipFile archive = null;
|
||||
if(("." + FilenameUtils.getExtension(file.getAbsolutePath())).equals(ReplayFile.ZIP_FILE_EXTENSION)) {
|
||||
ReplayFile archive = null;
|
||||
try {
|
||||
archive = new ZipFile(file);
|
||||
ZipArchiveEntry recfile = archive.getEntry("recording" + ConnectionEventHandler.TEMP_FILE_EXTENSION);
|
||||
ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
|
||||
archive = new ReplayFile(file);
|
||||
|
||||
ZipArchiveEntry image = archive.getEntry("thumb");
|
||||
BufferedImage img = null;
|
||||
if(image != null) {
|
||||
InputStream is = archive.getInputStream(image);
|
||||
is.skip(7);
|
||||
BufferedImage bimg = ImageIO.read(is);
|
||||
if(bimg != null) {
|
||||
thumb = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
|
||||
}
|
||||
metaData = archive.metadata().get();
|
||||
BufferedImage img = archive.thumb().get();
|
||||
if(img != null) {
|
||||
thumb = ImageUtils.scaleImage(img, new Dimension(1280, 720));
|
||||
}
|
||||
|
||||
InputStream is = archive.getInputStream(metadata);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
String json = br.readLine();
|
||||
|
||||
metaData = gson.fromJson(json, ReplayMetaData.class);
|
||||
|
||||
archive.close();
|
||||
correctFile = true;
|
||||
} catch(Exception e) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package eu.crushedpixel.replaymod.gui.replayviewer;
|
||||
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@@ -48,7 +48,7 @@ public class GuiRenameReplay extends GuiScreen {
|
||||
} else if(button.id == 0) {
|
||||
File folder = ReplayFileIO.getReplayFolder();
|
||||
|
||||
File initRenamed = new File(folder, this.field_146583_f.getText().trim() + ConnectionEventHandler.ZIP_FILE_EXTENSION.replaceAll("[^a-zA-Z0-9\\.\\-]", "_"));
|
||||
File initRenamed = new File(folder, (this.field_146583_f.getText().trim() + ReplayFile.ZIP_FILE_EXTENSION).replaceAll("[^a-zA-Z0-9\\.\\-]", "_"));
|
||||
File renamed = initRenamed;
|
||||
int i = 1;
|
||||
while(renamed.isFile()) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package eu.crushedpixel.replaymod.gui.replayviewer;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.mojang.realmsclient.util.Pair;
|
||||
import eu.crushedpixel.replaymod.ReplayMod;
|
||||
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
|
||||
@@ -8,11 +7,11 @@ import eu.crushedpixel.replaymod.gui.GuiReplaySettings;
|
||||
import eu.crushedpixel.replaymod.gui.elements.GuiReplayListExtended;
|
||||
import eu.crushedpixel.replaymod.gui.online.GuiUploadFile;
|
||||
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.utils.ImageUtils;
|
||||
import eu.crushedpixel.replaymod.utils.MouseUtils;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@@ -20,8 +19,6 @@ import net.minecraft.client.gui.GuiYesNo;
|
||||
import net.minecraft.client.gui.GuiYesNoCallback;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.Util;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.lwjgl.Sys;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
@@ -29,7 +26,8 @@ import org.lwjgl.input.Keyboard;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
@@ -43,7 +41,6 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
|
||||
private static final int DELETE_BUTTON_ID = 9005;
|
||||
private static final int SETTINGS_BUTTON_ID = 9006;
|
||||
private static final int CANCEL_BUTTON_ID = 9007;
|
||||
private static Gson gson = new Gson();
|
||||
private boolean initialized;
|
||||
private GuiReplayListExtended replayGuiList;
|
||||
private List<Pair<Pair<File, ReplayMetaData>, File>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, File>>();
|
||||
@@ -65,39 +62,21 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback {
|
||||
|
||||
for(File file : ReplayFileIO.getAllReplayFiles()) {
|
||||
try {
|
||||
ZipFile archive = new ZipFile(file);
|
||||
ZipArchiveEntry metadata = archive.getEntry("metaData" + ConnectionEventHandler.JSON_FILE_EXTENSION);
|
||||
|
||||
ZipArchiveEntry image = archive.getEntry("thumb");
|
||||
BufferedImage img = null;
|
||||
if(image != null) {
|
||||
InputStream is = archive.getInputStream(image);
|
||||
is.skip(7);
|
||||
BufferedImage bimg = ImageIO.read(is);
|
||||
if(bimg != null) {
|
||||
img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
|
||||
}
|
||||
}
|
||||
|
||||
ReplayFile replayFile = new ReplayFile(file);
|
||||
ReplayMetaData metaData = replayFile.metadata().get();
|
||||
BufferedImage img = replayFile.thumb().get();
|
||||
File tmp = null;
|
||||
if(img != null) {
|
||||
img = ImageUtils.scaleImage(img, new Dimension(1280, 720));
|
||||
tmp = File.createTempFile(FilenameUtils.getBaseName(file.getAbsolutePath()), "jpg");
|
||||
tmp.deleteOnExit();
|
||||
|
||||
ImageIO.write(img, "jpg", tmp);
|
||||
}
|
||||
|
||||
InputStream is = archive.getInputStream(metadata);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
String json = br.readLine();
|
||||
|
||||
ReplayMetaData metaData = gson.fromJson(json, ReplayMetaData.class);
|
||||
|
||||
replayFileList.add(Pair.of(Pair.of(file, metaData), tmp));
|
||||
|
||||
archive.close();
|
||||
replayFile.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package eu.crushedpixel.replaymod.recording;
|
||||
|
||||
import eu.crushedpixel.replaymod.ReplayMod;
|
||||
import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -26,9 +27,6 @@ import java.util.Map.Entry;
|
||||
|
||||
public class ConnectionEventHandler {
|
||||
|
||||
public static final String TEMP_FILE_EXTENSION = ".tmcpr";
|
||||
public static final String JSON_FILE_EXTENSION = ".json";
|
||||
public static final String ZIP_FILE_EXTENSION = ".mcpr";
|
||||
private static final String decoderKey = "decoder";
|
||||
private static final String packetHandlerKey = "packet_handler";
|
||||
private static final String DATE_FORMAT = "yyyy_MM_dd_HH_mm_ss";
|
||||
@@ -92,7 +90,7 @@ public class ConnectionEventHandler {
|
||||
File folder = ReplayFileIO.getReplayFolder();
|
||||
|
||||
fileName = sdf.format(Calendar.getInstance().getTime());
|
||||
currentFile = new File(folder, fileName + TEMP_FILE_EXTENSION);
|
||||
currentFile = new File(folder, fileName + ReplayFile.TEMP_FILE_EXTENSION);
|
||||
|
||||
currentFile.createNewFile();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package eu.crushedpixel.replaymod.recording;
|
||||
import com.google.gson.Gson;
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
|
||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
@@ -134,7 +135,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
||||
|
||||
File folder = ReplayFileIO.getReplayFolder();
|
||||
|
||||
File archive = new File(folder, name + ConnectionEventHandler.ZIP_FILE_EXTENSION);
|
||||
File archive = new File(folder, name + ReplayFile.ZIP_FILE_EXTENSION);
|
||||
archive.createNewFile();
|
||||
|
||||
ReplayFileIO.writeReplayFile(archive, file, metaData);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.mojang.authlib.GameProfile;
|
||||
import eu.crushedpixel.replaymod.ReplayMod;
|
||||
import eu.crushedpixel.replaymod.entities.CameraEntity;
|
||||
import eu.crushedpixel.replaymod.holders.*;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -14,6 +15,7 @@ import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ReplayHandler {
|
||||
@@ -36,6 +38,11 @@ public class ReplayHandler {
|
||||
|
||||
private static KeyframeSet[] keyframeRepository = new KeyframeSet[]{};
|
||||
|
||||
/**
|
||||
* The file currently being played.
|
||||
*/
|
||||
private static ReplayFile currentReplayFile;
|
||||
|
||||
public static KeyframeSet[] getKeyframeRepository() {
|
||||
return keyframeRepository;
|
||||
}
|
||||
@@ -49,7 +56,7 @@ public class ReplayHandler {
|
||||
|
||||
ReplayFileIO.writeKeyframeRegistryToFile(repo, tempFile);
|
||||
|
||||
ReplayMod.replayFileAppender.registerModifiedFile(tempFile, "paths", ReplayMod.replaySender.getReplayFile());
|
||||
ReplayMod.replayFileAppender.registerModifiedFile(tempFile, "paths", getReplayFile());
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -325,13 +332,23 @@ public class ReplayHandler {
|
||||
|
||||
channel = new OpenEmbeddedChannel(networkManager);
|
||||
|
||||
ReplayMod.replaySender = new ReplaySender(file, networkManager);
|
||||
// Open replay
|
||||
try {
|
||||
currentReplayFile = new ReplayFile(file);
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
KeyframeSet[] paths = currentReplayFile.paths().get();
|
||||
ReplayHandler.setKeyframeRepository(paths == null ? new KeyframeSet[0] : paths, false);
|
||||
|
||||
ReplayMod.replaySender = new ReplaySender(currentReplayFile, true);
|
||||
channel.pipeline().addFirst(ReplayMod.replaySender);
|
||||
channel.pipeline().fireChannelActive();
|
||||
|
||||
try {
|
||||
ReplayMod.overlay.resetUI(true);
|
||||
} catch(Exception e) {}
|
||||
} catch(Exception e) {} // TODO proper handling
|
||||
|
||||
//Load lighting and trigger update
|
||||
ReplayMod.replaySettings.setLightingEnabled(ReplayMod.replaySettings.isLightingEnabled());
|
||||
@@ -374,6 +391,15 @@ public class ReplayHandler {
|
||||
ReplayMod.replaySender.terminateReplay();
|
||||
}
|
||||
|
||||
if (currentReplayFile != null) {
|
||||
try {
|
||||
currentReplayFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentReplayFile = null;
|
||||
}
|
||||
|
||||
resetKeyframes();
|
||||
|
||||
inReplay = false;
|
||||
@@ -400,10 +426,7 @@ public class ReplayHandler {
|
||||
}
|
||||
|
||||
public static File getReplayFile() {
|
||||
if(ReplayMod.replaySender != null) {
|
||||
return ReplayMod.replaySender.getReplayFile();
|
||||
}
|
||||
return null;
|
||||
return currentReplayFile == null ? null : currentReplayFile.getFile();
|
||||
}
|
||||
|
||||
public static TimeKeyframe getFirstTimeKeyframe() {
|
||||
|
||||
@@ -65,8 +65,6 @@ public class ReplayProcess {
|
||||
calculated = false;
|
||||
requestFinish = false;
|
||||
|
||||
ReplayMod.replaySender.resetToleratedTimeStamp();
|
||||
|
||||
blocked = deepBlock = false;
|
||||
|
||||
startRealTime = System.currentTimeMillis();
|
||||
@@ -97,6 +95,7 @@ public class ReplayProcess {
|
||||
|
||||
ReplayHandler.sortKeyframes();
|
||||
ReplayHandler.setInPath(true);
|
||||
ReplayMod.replaySender.setAsyncMode(false);
|
||||
|
||||
//gets first Timestamp and sets Replay Time to it
|
||||
TimeKeyframe tf = ReplayHandler.getFirstTimeKeyframe();
|
||||
@@ -105,7 +104,7 @@ public class ReplayProcess {
|
||||
if(ts < ReplayMod.replaySender.currentTimeStamp()) {
|
||||
mc.displayGuiScreen(null);
|
||||
}
|
||||
ReplayMod.replaySender.jumpToTime(ts);
|
||||
ReplayMod.replaySender.sendPacketsTill(ts);
|
||||
}
|
||||
|
||||
ReplayMod.chatMessageHandler.addLocalizedChatMessage("replaymod.chat.pathstarted", ChatMessageType.INFORMATION);
|
||||
@@ -132,6 +131,7 @@ public class ReplayProcess {
|
||||
}
|
||||
|
||||
ReplayHandler.setInPath(false);
|
||||
ReplayMod.replaySender.setAsyncMode(true);
|
||||
|
||||
ReplayMod.replaySender.stopHurrying();
|
||||
|
||||
@@ -357,8 +357,8 @@ public class ReplayProcess {
|
||||
lastRenderPartialTicks = MCTimerHandler.getRenderTicks();
|
||||
lastTicks = MCTimerHandler.getTicks();
|
||||
|
||||
if(curTimestamp != null && curTimestamp != ReplayMod.replaySender.getDesiredTimestamp())
|
||||
ReplayMod.replaySender.jumpToTime(curTimestamp);
|
||||
if(curTimestamp != null)
|
||||
ReplayMod.replaySender.sendPacketsTill(curTimestamp);
|
||||
|
||||
//splinePos = (index of last entry + add) / total entries
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
117
src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java
Normal file
117
src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java
Normal 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user