Updated build.gradle to use local distributions of Replay Studio instead of mvn repo (which didn't work on Mac)
Made Screenshots work on Windows File Systems (only worked on UNIX before) Dried Screenshot ZIP Code
This commit is contained in:
@@ -99,4 +99,8 @@ processResources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main { output.resourcesDir = output.classesDir }
|
||||||
|
}
|
||||||
|
|
||||||
defaultTasks 'build'
|
defaultTasks 'build'
|
||||||
@@ -98,8 +98,7 @@ public class KeyInputHandler {
|
|||||||
|
|
||||||
//Custom registered handlers
|
//Custom registered handlers
|
||||||
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_THUMBNAIL) && kb.isPressed() && !found) {
|
if(kb.getKeyDescription().equals(KeybindRegistry.KEY_THUMBNAIL) && kb.isPressed() && !found) {
|
||||||
ReplayScreenshot.prepareScreenshot();
|
TickAndRenderListener.requestScreenshot();
|
||||||
//GuiReplayOverlay.requestScreenshot();
|
|
||||||
//TODO: Make this properly work
|
//TODO: Make this properly work
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
|
||||||
import org.lwjgl.input.Keyboard;
|
import org.lwjgl.input.Keyboard;
|
||||||
import org.lwjgl.input.Mouse;
|
import org.lwjgl.input.Mouse;
|
||||||
import org.lwjgl.opengl.Display;
|
import org.lwjgl.opengl.Display;
|
||||||
@@ -39,11 +40,30 @@ public class TickAndRenderListener {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onRenderWorld(RenderWorldLastEvent event) throws
|
public void onRenderWorld(RenderWorldLastEvent event) throws
|
||||||
InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException {
|
InvocationTargetException, IOException, IllegalAccessException, IllegalArgumentException {
|
||||||
if(!ReplayHandler.isInReplay()) return;
|
if(!ReplayHandler.isInReplay()) return; //If not in Replay, cancel
|
||||||
|
|
||||||
|
if(requestScreenshot == 1) {
|
||||||
|
mc.addScheduledTask(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ChatMessageRequests.addChatMessage("Saving Thumbnail...", ChatMessageRequests.ChatMessageType.INFORMATION);
|
||||||
|
ReplayScreenshot.prepareScreenshot();
|
||||||
|
requestScreenshot = 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if(requestScreenshot == 2) {
|
||||||
|
mc.addScheduledTask(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ReplayScreenshot.saveScreenshot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false);
|
if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick(false);
|
||||||
if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity());
|
if(ReplayHandler.isCamera()) ReplayHandler.setCameraEntity(ReplayHandler.getCameraEntity());
|
||||||
if(ReplayHandler.isInReplay() && ReplayHandler.isPaused()) {
|
if(ReplayHandler.isInReplay() && ReplayHandler.isPaused()) {
|
||||||
@@ -60,19 +80,24 @@ public class TickAndRenderListener {
|
|||||||
lastPitch = mc.getRenderViewEntity().rotationPitch;
|
lastPitch = mc.getRenderViewEntity().rotationPitch;
|
||||||
lastYaw = mc.getRenderViewEntity().rotationYaw;
|
lastYaw = mc.getRenderViewEntity().rotationYaw;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if(requestScreenshot) {
|
|
||||||
requestScreenshot = false;
|
|
||||||
ReplayScreenshot.saveScreenshot(mc.getFramebuffer());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if(mc.isGamePaused() && ReplayHandler.isInPath()) {
|
if(mc.isGamePaused() && ReplayHandler.isInPath()) {
|
||||||
isGamePaused.set(mc, false);
|
isGamePaused.set(mc, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private boolean f1Down = false;
|
//private boolean f1Down = false;
|
||||||
|
|
||||||
|
private static int requestScreenshot = 0;
|
||||||
|
|
||||||
|
public static void requestScreenshot() {
|
||||||
|
if(requestScreenshot == 0) requestScreenshot = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void finishScreenshot() {
|
||||||
|
requestScreenshot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void tick(TickEvent event) {
|
public void tick(TickEvent event) {
|
||||||
if(!ReplayHandler.isInReplay()) return;
|
if(!ReplayHandler.isInReplay()) return;
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
package eu.crushedpixel.replaymod.recording;
|
package eu.crushedpixel.replaymod.recording;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
|
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
|
||||||
|
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
|
||||||
|
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -13,19 +23,6 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import sun.java2d.SunGraphics2D;
|
|
||||||
import net.minecraft.network.NetworkManager;
|
|
||||||
import net.minecraft.network.Packet;
|
|
||||||
import net.minecraft.network.play.server.S42PacketCombatEvent;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent;
|
|
||||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent;
|
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
|
||||||
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
|
|
||||||
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
|
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
|
||||||
|
|
||||||
public class ConnectionEventHandler {
|
public class ConnectionEventHandler {
|
||||||
|
|
||||||
private static final String decoderKey = "decoder";
|
private static final String decoderKey = "decoder";
|
||||||
|
|||||||
@@ -1,47 +1,32 @@
|
|||||||
package eu.crushedpixel.replaymod.utils;
|
package eu.crushedpixel.replaymod.utils;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
import net.minecraft.network.EnumConnectionState;
|
|
||||||
import net.minecraft.network.EnumPacketDirection;
|
|
||||||
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 akka.japi.Pair;
|
import akka.japi.Pair;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import eu.crushedpixel.replaymod.ReplayMod;
|
import eu.crushedpixel.replaymod.ReplayMod;
|
||||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||||
import eu.crushedpixel.replaymod.recording.PacketSerializer;
|
import eu.crushedpixel.replaymod.recording.PacketSerializer;
|
||||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||||
import eu.crushedpixel.replaymod.replay.PacketDeserializer;
|
import eu.crushedpixel.replaymod.replay.PacketDeserializer;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.minecraft.network.EnumConnectionState;
|
||||||
|
import net.minecraft.network.EnumPacketDirection;
|
||||||
|
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.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
@SuppressWarnings("resource") //Gets handled by finalizer
|
@SuppressWarnings("resource") //Gets handled by finalizer
|
||||||
public class ReplayFileIO {
|
public class ReplayFileIO {
|
||||||
@@ -51,7 +36,7 @@ public class ReplayFileIO {
|
|||||||
folder.mkdirs();
|
folder.mkdirs();
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getReplayFolder() {
|
public static File getReplayFolder() {
|
||||||
String path = ReplayMod.replaySettings.getRecordingPath();
|
String path = ReplayMod.replaySettings.getRecordingPath();
|
||||||
File folder = new File(path);
|
File folder = new File(path);
|
||||||
@@ -237,7 +222,7 @@ public class ReplayFileIO {
|
|||||||
private static boolean lastContainsJoinPacket = false;
|
private static boolean lastContainsJoinPacket = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param replayFile The File to reverse
|
* @param replayFile The File to reverse
|
||||||
* @param outputFile The File to save the reversed Packets in
|
* @param outputFile The File to save the reversed Packets in
|
||||||
* @param seekJoinPacket Whether a {@link S01PacketJoinGame} should be seeked in the Replay File. If containsJoinPacket is being
|
* @param seekJoinPacket Whether a {@link S01PacketJoinGame} should be seeked in the Replay File. If containsJoinPacket is being
|
||||||
@@ -319,4 +304,58 @@ public class ReplayFileIO {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final byte[] uniqueBytes = new byte[]{0,1,1,2,3,5,8};
|
||||||
|
|
||||||
|
public static void addThumbToZip(File zipFile, File thumb) throws IOException {
|
||||||
|
// get a temp file
|
||||||
|
File tempFile = File.createTempFile(zipFile.getName(), null);
|
||||||
|
// delete it, otherwise you cannot rename your existing zip to it.
|
||||||
|
tempFile.delete();
|
||||||
|
|
||||||
|
zipFile.renameTo(tempFile);
|
||||||
|
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
|
||||||
|
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
|
||||||
|
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
|
||||||
|
|
||||||
|
ZipEntry entry = zin.getNextEntry();
|
||||||
|
while (entry != null) {
|
||||||
|
String name = entry.getName();
|
||||||
|
boolean isThumb = name.contains("thumb");
|
||||||
|
if(!isThumb) {
|
||||||
|
// Add ZIP entry to output stream.
|
||||||
|
out.putNextEntry(new ZipEntry(name));
|
||||||
|
// Transfer bytes from the ZIP file to the output file
|
||||||
|
int len;
|
||||||
|
while ((len = zin.read(buf)) > 0) {
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry = zin.getNextEntry();
|
||||||
|
}
|
||||||
|
// Close the streams
|
||||||
|
zin.close();
|
||||||
|
// Compress the files
|
||||||
|
|
||||||
|
InputStream in = new FileInputStream(thumb);
|
||||||
|
// Add ZIP entry to output stream.
|
||||||
|
out.putNextEntry(new ZipEntry("thumb"));
|
||||||
|
// Transfer bytes from the file to the ZIP file
|
||||||
|
int len;
|
||||||
|
|
||||||
|
out.write(uniqueBytes);
|
||||||
|
|
||||||
|
while ((len = in.read(buf)) > 0) {
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
// Complete the entry
|
||||||
|
out.closeEntry();
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
// Complete the ZIP file
|
||||||
|
out.close();
|
||||||
|
tempFile.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.zip.ZipOutputStream;
|
|||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import eu.crushedpixel.replaymod.events.TickAndRenderListener;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
@@ -35,8 +36,6 @@ public class ReplayScreenshot {
|
|||||||
|
|
||||||
private static Minecraft mc = Minecraft.getMinecraft();
|
private static Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
private static final byte[] uniqueBytes = new byte[]{0,1,1,2,3,5,8};
|
|
||||||
|
|
||||||
private static long last_finish = -1;
|
private static long last_finish = -1;
|
||||||
|
|
||||||
private static boolean before;
|
private static boolean before;
|
||||||
@@ -51,7 +50,7 @@ public class ReplayScreenshot {
|
|||||||
|
|
||||||
private static boolean locked = false;
|
private static boolean locked = false;
|
||||||
|
|
||||||
public static void saveScreenshot(Framebuffer buffer) {
|
public static void saveScreenshot() {
|
||||||
|
|
||||||
if(locked) return;
|
if(locked) return;
|
||||||
locked = true;
|
locked = true;
|
||||||
@@ -94,32 +93,28 @@ public class ReplayScreenshot {
|
|||||||
|
|
||||||
File replayFile = ReplayHandler.getReplayFile();
|
File replayFile = ReplayHandler.getReplayFile();
|
||||||
|
|
||||||
File folder = ReplayFileIO.getReplayFolder();
|
File tempImage = File.createTempFile("thumb", null);
|
||||||
|
|
||||||
File temp = File.createTempFile("thumb", null);
|
|
||||||
|
|
||||||
int h = 720;
|
int h = 720;
|
||||||
int w = 1280;
|
int w = 1280;
|
||||||
|
|
||||||
BufferedImage img = ImageUtils.scaleImage(nbi, new Dimension(w, h));
|
BufferedImage img = ImageUtils.scaleImage(nbi, new Dimension(w, h));
|
||||||
|
|
||||||
ImageIO.write(img, "jpg", temp);
|
ImageIO.write(img, "jpg", tempImage);
|
||||||
|
|
||||||
File tempFile = File.createTempFile(replayFile.getName(), null);
|
ReplayFileIO.addThumbToZip(replayFile, tempImage);
|
||||||
tempFile.delete(); tempFile.deleteOnExit();
|
|
||||||
|
|
||||||
replayFile.renameTo(tempFile);
|
tempImage.delete();
|
||||||
|
|
||||||
replayFile.delete();
|
/*
|
||||||
replayFile.createNewFile();
|
File outputFile = File.createTempFile(replayFile.getName(), null);
|
||||||
|
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
|
|
||||||
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
|
ZipInputStream zin = new ZipInputStream(new FileInputStream(replayFile));
|
||||||
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(replayFile));
|
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(outputFile));
|
||||||
|
|
||||||
FileInputStream fis = new FileInputStream(temp);
|
|
||||||
|
|
||||||
|
//copying all of the old Zip Entries to the new file, unless it's a thumb
|
||||||
ZipEntry entry = zin.getNextEntry();
|
ZipEntry entry = zin.getNextEntry();
|
||||||
while (entry != null) {
|
while (entry != null) {
|
||||||
String name = entry.getName();
|
String name = entry.getName();
|
||||||
@@ -137,6 +132,8 @@ public class ReplayScreenshot {
|
|||||||
entry = zin.getNextEntry();
|
entry = zin.getNextEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileInputStream fis = new FileInputStream(tempImage);
|
||||||
|
|
||||||
zout.putNextEntry(new ZipEntry("thumb"));
|
zout.putNextEntry(new ZipEntry("thumb"));
|
||||||
int len;
|
int len;
|
||||||
//Add unique bytes to the end of the file
|
//Add unique bytes to the end of the file
|
||||||
@@ -146,21 +143,26 @@ public class ReplayScreenshot {
|
|||||||
zout.write(buf, 0, len);
|
zout.write(buf, 0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the streams
|
|
||||||
fis.close();
|
fis.close();
|
||||||
zin.close();
|
zin.close();
|
||||||
// Compress the files
|
|
||||||
// Complete the ZIP file
|
|
||||||
zout.close();
|
zout.close();
|
||||||
tempFile.delete();
|
|
||||||
temp.delete();
|
replayFile.delete();
|
||||||
System.out.println("thumbnail saving finished");
|
outputFile.renameTo(replayFile);
|
||||||
|
|
||||||
|
tempImage.delete();
|
||||||
|
*/
|
||||||
|
|
||||||
ChatMessageRequests.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
|
ChatMessageRequests.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
|
||||||
} catch(Exception e) {}
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
GuiReplaySaving.replaySaving = false;
|
GuiReplaySaving.replaySaving = false;
|
||||||
locked = false;
|
locked = false;
|
||||||
|
TickAndRenderListener.finishScreenshot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -168,6 +170,7 @@ public class ReplayScreenshot {
|
|||||||
ioThread.start();
|
ioThread.start();
|
||||||
}
|
}
|
||||||
catch (Exception exception) {
|
catch (Exception exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
mc.gameSettings.hideGUI = before;
|
mc.gameSettings.hideGUI = before;
|
||||||
mc.currentScreen = beforeScreen;
|
mc.currentScreen = beforeScreen;
|
||||||
ReplayHandler.setSpeed(beforeSpeed);
|
ReplayHandler.setSpeed(beforeSpeed);
|
||||||
|
|||||||
Reference in New Issue
Block a user