diff --git a/libs/replaystudio-0.0.1-SNAPSHOT-all.jar b/libs/replaystudio-0.0.1-SNAPSHOT-all.jar index 78d9e328..447ee212 100644 Binary files a/libs/replaystudio-0.0.1-SNAPSHOT-all.jar and b/libs/replaystudio-0.0.1-SNAPSHOT-all.jar differ diff --git a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java index c63d0d81..b8e54cfc 100755 --- a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java +++ b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java @@ -1,5 +1,9 @@ package eu.crushedpixel.replaymod; +import java.io.IOException; + +import javax.swing.JOptionPane; + import net.minecraft.client.Minecraft; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; @@ -12,10 +16,12 @@ import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import eu.crushedpixel.replaymod.api.client.ApiClient; +import eu.crushedpixel.replaymod.api.client.ApiException; import eu.crushedpixel.replaymod.events.GuiEventHandler; import eu.crushedpixel.replaymod.events.GuiReplayOverlay; import eu.crushedpixel.replaymod.events.KeyInputHandler; import eu.crushedpixel.replaymod.events.RecordingHandler; +import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler; import eu.crushedpixel.replaymod.recording.ConnectionEventHandler; import eu.crushedpixel.replaymod.registry.KeybindRegistry; import eu.crushedpixel.replaymod.renderer.SafeEntityRenderer; @@ -108,9 +114,21 @@ public class ReplayMod } catch(Exception e) { e.printStackTrace(); } - //ReplayTrimmer.trim(new File("/Users/mariusmetzger/toTrim.mcpr"), new File("/Users/mariusmetzger/trimmed.mcpr"), 1000*60, 2000*60); - //if(AuthenticationHandler.isBlacklisted(Minecraft.getMinecraft().getSession().getPlayerID())) { - //System.exit(0); - //} + + + /* + boolean auth = false; + try { + auth = AuthenticationHandler.hasDonated(Minecraft.getMinecraft().getSession().getPlayerID()); + } catch(Exception e) { + JOptionPane.showMessageDialog(null, "Couldn't connect to the Replay Mod Server to verify whether you donated!"); + FMLCommonHandler.instance().exitJava(0, false); + } + + if(!auth) { + JOptionPane.showMessageDialog(null, "It seems like you didn't donate, so you can't use the Replay Mod yet."); + FMLCommonHandler.instance().exitJava(0, false); + } + */ } } diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java index b5b38bea..efcb2ea1 100755 --- a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiClient.java @@ -17,6 +17,7 @@ import com.google.gson.JsonParser; import eu.crushedpixel.replaymod.api.client.holders.ApiError; import eu.crushedpixel.replaymod.api.client.holders.AuthKey; +import eu.crushedpixel.replaymod.api.client.holders.Donated; import eu.crushedpixel.replaymod.api.client.holders.FileInfo; import eu.crushedpixel.replaymod.api.client.holders.SearchResult; import eu.crushedpixel.replaymod.api.client.holders.Success; @@ -35,7 +36,7 @@ public class ApiClient { AuthKey auth = invokeAndReturn(builder, AuthKey.class); return auth; } - + public boolean logout(String auth) throws IOException, ApiException { QueryBuilder builder = new QueryBuilder(ApiMethods.logout); builder.put("auth", auth); @@ -43,6 +44,13 @@ public class ApiClient { return succ.isSuccess(); } + public boolean hasDonated(String uuid) throws IOException, ApiException { + QueryBuilder builder = new QueryBuilder(ApiMethods.check_auth); + builder.put("uuid", uuid); + Donated succ = invokeAndReturn(builder, Donated.class); + return succ.hasDonated(); + } + public UserFiles getUserFiles(String auth, String user) throws IOException, ApiException { QueryBuilder builder = new QueryBuilder(ApiMethods.replay_files); builder.put("auth", auth); diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiMethods.java b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiMethods.java index dfced8d0..eb2d04da 100755 --- a/src/main/java/eu/crushedpixel/replaymod/api/client/ApiMethods.java +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/ApiMethods.java @@ -11,5 +11,6 @@ public class ApiMethods { public static final String get_thumbnail = "get_thumbnail"; public static final String remove_file = "remove_file"; public static final String rate_file = "rate_file"; + public static final String check_auth = "check_auth"; } diff --git a/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Donated.java b/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Donated.java new file mode 100644 index 00000000..7fe7fe20 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/api/client/holders/Donated.java @@ -0,0 +1,10 @@ +package eu.crushedpixel.replaymod.api.client.holders; + +public class Donated { + + private boolean donated = false; + + public boolean hasDonated() { + return donated; + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/coremod/ClassTransformer.java b/src/main/java/eu/crushedpixel/replaymod/coremod/ClassTransformer.java index edad28d0..68f8c491 100755 --- a/src/main/java/eu/crushedpixel/replaymod/coremod/ClassTransformer.java +++ b/src/main/java/eu/crushedpixel/replaymod/coremod/ClassTransformer.java @@ -21,7 +21,6 @@ public class ClassTransformer implements IClassTransformer { @Override public byte[] transform(String name, String transformedName, byte[] basicClass) { - if(name.equals("cqh")) { return patchRenderEffectMethod(name, basicClass, true); } diff --git a/src/main/java/eu/crushedpixel/replaymod/entities/CameraEntity.java b/src/main/java/eu/crushedpixel/replaymod/entities/CameraEntity.java index 562f0b76..e2136156 100755 --- a/src/main/java/eu/crushedpixel/replaymod/entities/CameraEntity.java +++ b/src/main/java/eu/crushedpixel/replaymod/entities/CameraEntity.java @@ -25,12 +25,14 @@ public class CameraEntity extends EntityPlayer { private Field drawBlockOutline; - private static final double SPEED = 10; //2 blocks per second + private static final double MAX_SPEED = 20; - private double decay = 6; //decays by 75% per second; + private double decay = 4; private long lastCall = 0; + private boolean speedup = false; + //frac = time since last tick public void updateMovement() { Minecraft mc = Minecraft.getMinecraft(); @@ -40,15 +42,6 @@ public class CameraEntity extends EntityPlayer { mc.thePlayer.rotationPitch = mc.getRenderViewEntity().rotationPitch; mc.thePlayer.rotationYaw = mc.getRenderViewEntity().rotationYaw; - /* - mc.thePlayer.posX = mc.getRenderViewEntity().posX; - mc.thePlayer.posY = mc.getRenderViewEntity().posY; - mc.thePlayer.posZ = mc.getRenderViewEntity().posZ; - - TimeHandler.setDesiredDaytime(18000); - TimeHandler.setTimeOverridden(true); - */ - //removes water/suffocation/shadow overlays in screen mc.thePlayer.posX = 0; mc.thePlayer.posY = 500; @@ -70,7 +63,12 @@ public class CameraEntity extends EntityPlayer { moveRelative(movement.xCoord*factor, movement.yCoord*factor, movement.zCoord*factor); double decFac = Math.max(0, 1-(decay*(frac/1000D))); - motion *= decFac; + + if(!speedup) { + motion *= decFac; + } else { + speedup = false; + } lastCall = Sys.getTime(); } @@ -79,6 +77,11 @@ public class CameraEntity extends EntityPlayer { this.setRotation(yaw, pitch); } + public void speedUp() { + this.motion = Math.min(MAX_SPEED, motion+0.1); + speedup = true; + } + public void setMovement(MoveDirection dir) { Vec3 oldDir = direction; @@ -104,8 +107,6 @@ public class CameraEntity extends EntityPlayer { } if(oldDir != null) direction = direction.normalize().add(new Vec3(oldDir.xCoord*(motion/4f), oldDir.yCoord*(motion/4f), oldDir.zCoord*(motion/4f)).normalize()); - - this.motion = SPEED; } public void moveAbsolute(double x, double y, double z) { diff --git a/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java b/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java index 1438df0f..bad2bdda 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java @@ -36,6 +36,7 @@ import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.studio.VersionValidator; import eu.crushedpixel.replaymod.timer.MCTimerHandler; import eu.crushedpixel.replaymod.utils.MouseUtils; +import eu.crushedpixel.replaymod.utils.ReplayFileIO; import eu.crushedpixel.replaymod.utils.ResourceHelper; import eu.crushedpixel.replaymod.video.VideoWriter; @@ -43,6 +44,8 @@ public class GuiEventHandler { private static Minecraft mc = Minecraft.getMinecraft(); + private static int replayCount = 0; + private static List allowedGUIs = new ArrayList() { { add(GuiReplaySettings.class); @@ -107,7 +110,12 @@ public class GuiEventHandler { e.gui.drawString(mc.fontRendererObj, "LOGGED OUT", 5, 15, DARK_RED.getRGB()); } - if(!VersionValidator.isValid) { + if(replayCount == 0) { + if(editorButton.isMouseOver()) { + Point mouse = MouseUtils.getMousePos(); + e.gui.drawCenteredString(mc.fontRendererObj, "At least one Replay required", (int)mouse.getX(), (int)mouse.getY()+4, Color.RED.getRGB()); + } + } else if(!VersionValidator.isValid) { if(editorButton.isMouseOver()) { Point mouse = MouseUtils.getMousePos(); e.gui.drawCenteredString(mc.fontRendererObj, "Java 1.7 or newer required", (int)mouse.getX(), (int)mouse.getY()+4, Color.RED.getRGB()); @@ -146,9 +154,11 @@ public class GuiEventHandler { //rm.enabled = AuthenticationHandler.isAuthenticated(); event.buttonList.add(rm); + replayCount = ReplayFileIO.getAllReplayFiles().size(); + GuiButton re = new GuiButton(GuiConstants.REPLAY_EDITOR_BUTTON_ID, event.gui.width / 2 + 2, i1 + 2*24, "Replay Editor"); re.width = re.width/2 - 2; - re.enabled = VersionValidator.isValid; + re.enabled = VersionValidator.isValid && replayCount > 0; event.buttonList.add(re); editorButton = re; diff --git a/src/main/java/eu/crushedpixel/replaymod/events/GuiReplayOverlay.java b/src/main/java/eu/crushedpixel/replaymod/events/GuiReplayOverlay.java index 39832fbf..3ae7eeee 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/GuiReplayOverlay.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/GuiReplayOverlay.java @@ -10,6 +10,7 @@ import java.util.concurrent.TimeUnit; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; @@ -83,9 +84,9 @@ public class GuiReplayOverlay extends Gui { private boolean mouseDown = false; private static boolean requestScreenshot = false; - + private static Field isGamePaused; - + static { try { isGamePaused = Minecraft.class.getDeclaredField(MCPNames.field("field_71445_n")); @@ -103,9 +104,9 @@ public class GuiReplayOverlay extends Gui { public GuiReplayOverlay() { try { -// drawBlockOutline = EntityRenderer.class.getDeclaredField(MCPNames.field("field_175073_D")); - // drawBlockOutline.setAccessible(true); - // drawBlockOutline.set(Minecraft.getMinecraft().entityRenderer, false); + // drawBlockOutline = EntityRenderer.class.getDeclaredField(MCPNames.field("field_175073_D")); + // drawBlockOutline.setAccessible(true); + // drawBlockOutline.set(Minecraft.getMinecraft().entityRenderer, false); } catch(Exception e) {} } @@ -125,20 +126,20 @@ public class GuiReplayOverlay extends Gui { ReplayHandler.getCameraEntity().updateMovement(); if(!ReplayHandler.isInPath()) onMouseMove(new MouseEvent()); FMLCommonHandler.instance().bus().post(new InputEvent.KeyInputEvent()); - + } private double lastX, lastY, lastZ; private float lastPitch, lastYaw; - + @SubscribeEvent public void onChangeView(MouseEvent event) { if(ReplayHandler.isInPath()) { event.setCanceled(true); } } - + @SubscribeEvent public void onRenderWorld(RenderWorldLastEvent event) throws IllegalAccessException, IllegalArgumentException, @@ -187,7 +188,7 @@ public class GuiReplayOverlay extends Gui { @SubscribeEvent public void onRenderGui(RenderGameOverlayEvent.Post event) throws IllegalArgumentException, IllegalAccessException { - + if(!ReplayHandler.isInReplay() || FMLClientHandler.instance().isGUIOpen(GuiSpectateSelection.class) || VideoWriter.isRecording()) { return; } @@ -195,7 +196,11 @@ public class GuiReplayOverlay extends Gui { //System.out.println(System.currentTimeMillis()+" | "+MCTimerHandler.getTicks()+" | "+MCTimerHandler.getPartialTicks()); if(!ReplayGuiRegistry.hidden) ReplayGuiRegistry.hide(); - + + if(FMLClientHandler.instance().isGUIOpen(GuiChat.class)) { + mc.displayGuiScreen(new GuiMouseInput()); + } + if(event.type == ElementType.PLAYER_LIST) { if(event.isCancelable()) { event.setCanceled(true); @@ -204,7 +209,7 @@ public class GuiReplayOverlay extends Gui { } GL11.glEnable(GL11.GL_BLEND); - // drawBlockOutline.set(Minecraft.getMinecraft().entityRenderer, false); + // drawBlockOutline.set(Minecraft.getMinecraft().entityRenderer, false); if(!ReplayHandler.isInReplay()) { return; @@ -217,7 +222,7 @@ public class GuiReplayOverlay extends Gui { Point scaled = MouseUtils.getScaledDimensions(); final int width = (int)scaled.getX(); final int height = (int)scaled.getY(); - + //Draw Timeline drawTimeline(timelineX, width - 14, 9); drawRealTimeline(realTimelineX, width - 14 - 11, realTimelineY, mouseX, mouseY); @@ -872,8 +877,9 @@ public class GuiReplayOverlay extends Gui { b0 = -1; } - ReplayHandler.getCameraEntity().setAngles(f3, f4 * (float)b0); - + if(ReplayHandler.getCameraEntity() != null) { + ReplayHandler.getCameraEntity().setAngles(f3, f4 * (float)b0); + } } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/events/KeyInputHandler.java b/src/main/java/eu/crushedpixel/replaymod/events/KeyInputHandler.java index 4e96a1ca..6baecfa1 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/KeyInputHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/KeyInputHandler.java @@ -34,38 +34,50 @@ public class KeyInputHandler { continue; } try { - + boolean speedup = false; + if(ReplayHandler.isCamera()) { if(kb.getKeyDescription().equals("key.forward")) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.FORWARD); + speedup = true; } if(kb.getKeyDescription().equals("key.back")) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.BACKWARD); + speedup = true; } if(kb.getKeyDescription().equals("key.jump")) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.UP); + speedup = true; } if(kb.getKeyDescription().equals("key.left")) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.LEFT); + speedup = true; } if(kb.getKeyDescription().equals("key.right")) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.RIGHT); + speedup = true; } } if(kb.getKeyDescription().equals("key.sneak")) { if(ReplayHandler.isCamera()) { ReplayHandler.getCameraEntity().setMovement(MoveDirection.DOWN); + speedup = true; } else { ReplayHandler.spectateCamera(); } } + + if(speedup) { + ReplayHandler.getCameraEntity().speedUp(); + } if(kb.getKeyDescription().equals("key.chat")) { mc.displayGuiScreen(new GuiMouseInput()); + break; } //Custom registered handlers diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiConnectPart.java b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiConnectPart.java index 232e6765..0978b947 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiConnectPart.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiConnectPart.java @@ -41,11 +41,6 @@ public class GuiConnectPart extends GuiStudioPart { fontRendererObj = mc.fontRendererObj; } - @Override - public void applyFilters() { - // TODO Auto-generated method stub - } - @Override public String getDescription() { return DESCRIPTION; @@ -195,4 +190,10 @@ public class GuiConnectPart extends GuiStudioPart { } } } + + @Override + public void applyFilters(File replayFile, File outputFile) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiReplayStudio.java b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiReplayStudio.java index 06fc6264..0272dac4 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiReplayStudio.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiReplayStudio.java @@ -141,6 +141,21 @@ public class GuiReplayStudio extends GuiScreen { currentTab = StudioTab.CONNECT; } else if(button.id == GuiConstants.REPLAY_EDITOR_MODIFY_TAB) { currentTab = StudioTab.MODIFY; + } else if(button.id == GuiConstants.REPLAY_EDITOR_SAVE_BUTTON) { + File outputFile = getSelectedFile(); + File folder = ReplayFileIO.getReplayFolder(); + if(!overrideSave) { + String name = FilenameUtils.getBaseName(outputFile.getAbsolutePath())+"_edited"; + File f = new File(folder, name+".mcpr"); + int num = 0; + while(f.exists()) { + num++; + String fileName = name+"_"+num; + f = new File(folder, fileName+".mcpr"); + } + outputFile = f; + } + currentTab.getStudioPart().applyFilters(getSelectedFile(), outputFile); } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiStudioPart.java b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiStudioPart.java index 405d7668..22f1cfa3 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiStudioPart.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiStudioPart.java @@ -1,5 +1,6 @@ package eu.crushedpixel.replaymod.gui.replaystudio; +import java.io.File; import java.io.IOException; import net.minecraft.client.gui.GuiScreen; @@ -12,7 +13,7 @@ public abstract class GuiStudioPart extends GuiScreen { protected int yPos = 0; - public abstract void applyFilters(); + public abstract void applyFilters(File replayFile, File outputFile); public abstract String getDescription(); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiTrimPart.java b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiTrimPart.java index 60b1335f..f1f8fcf5 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiTrimPart.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replaystudio/GuiTrimPart.java @@ -1,6 +1,10 @@ package eu.crushedpixel.replaymod.gui.replaystudio; import java.awt.Color; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -9,6 +13,7 @@ import net.minecraft.client.Minecraft; import org.lwjgl.input.Keyboard; import eu.crushedpixel.replaymod.gui.elements.GuiNumberInput; +import eu.crushedpixel.replaymod.studio.StudioImplementation; public class GuiTrimPart extends GuiStudioPart { @@ -30,8 +35,12 @@ public class GuiTrimPart extends GuiStudioPart { } @Override - public void applyFilters() { - // TODO Auto-generated method stub + public void applyFilters(File replayFile, File outputFile) { + try { + StudioImplementation.trimReplay(replayFile, false, getStartTimestamp(), getEndTimestamp(), outputFile); + } catch(Exception e) { + e.printStackTrace(); + } } private int valueOf(String text) { diff --git a/src/main/java/eu/crushedpixel/replaymod/online/authentication/AuthenticationHandler.java b/src/main/java/eu/crushedpixel/replaymod/online/authentication/AuthenticationHandler.java index b76b0f05..053450e7 100755 --- a/src/main/java/eu/crushedpixel/replaymod/online/authentication/AuthenticationHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/online/authentication/AuthenticationHandler.java @@ -1,11 +1,13 @@ package eu.crushedpixel.replaymod.online.authentication; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; import net.minecraft.client.Minecraft; import eu.crushedpixel.replaymod.ReplayMod; +import eu.crushedpixel.replaymod.api.client.ApiClient; import eu.crushedpixel.replaymod.api.client.ApiException; import eu.crushedpixel.replaymod.reflection.MCPNames; @@ -15,6 +17,8 @@ public class AuthenticationHandler { public static final int INVALID = 2; public static final int NO_CONNECTION = 3; + private static final ApiClient apiClient = new ApiClient(); + private static Minecraft mc = Minecraft.getMinecraft(); private static String authkey = null; @@ -26,15 +30,9 @@ public class AuthenticationHandler { public static String getKey() { return authkey; } - - private static List blackUUIDs = new ArrayList() { - { - add("23978392a78c49cf9f5235a151fd4083"); //Hudelsohn - } - }; - public static boolean isBlacklisted(String uuid) { - return blackUUIDs.contains(uuid.replace("-", "")); + public static boolean hasDonated(String uuid) throws IOException, ApiException { + return apiClient.hasDonated(uuid); } public static int authenticate(String username, String password) { diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java index ae46b1cf..795cb77f 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java @@ -49,7 +49,7 @@ public class ReplayProcess { public static void startReplayProcess(boolean record) { ReplayHandler.selectKeyframe(null); - + isVideoRecording = record; lastPosition = null; motionSpline = null; @@ -59,10 +59,11 @@ public class ReplayProcess { requestFinish = false; ChatMessageRequests.initialize(); - if(ReplayHandler.getPosKeyframeCount() < 2) { - ChatMessageRequests.addChatMessage("At least 2 position keyframes required!", ChatMessageType.WARNING); + if(ReplayHandler.getPosKeyframeCount() < 2 && ReplayHandler.getTimeKeyframeCount() < 2) { + ChatMessageRequests.addChatMessage("At least 2 position or time keyframes required!", ChatMessageType.WARNING); return; } + startRealTime = System.currentTimeMillis(); lastRealTime = startRealTime; lastRealReplayTime = 0; @@ -73,7 +74,7 @@ public class ReplayProcess { previousReplaySpeed = ReplayHandler.getSpeed(); EnchantmentTimer.resetRecordingTime(); - + TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1); if(tf != null) { int ts = tf.getTimestamp(); @@ -138,20 +139,26 @@ public class ReplayProcess { } public static void tickReplay() { - if(isVideoRecording()) { - recordingTick(); - } else { - normalTick(); - } + pathTick(isVideoRecording()); } - private static void normalTick() { - + private static void pathTick(boolean recording) { if(ReplayHandler.isHurrying()) { - lastRealTime = System.currentTimeMillis(); + if(!recording) + lastRealTime = System.currentTimeMillis(); return; } + if(recording) { + if(blocked) return; + + deepBlock = true; + blocked = true; + } + + int posCount = ReplayHandler.getPosKeyframeCount(); + int timeCount = ReplayHandler.getTimeKeyframeCount(); + if(!linear && motionSpline == null) { //set up spline path motionSpline = new SplinePoint(); @@ -182,16 +189,21 @@ public class ReplayProcess { timeLinear.addPoint(((TimeKeyframe)kf).getTimestamp()); } } - } if(!calculated) { calculated = true; - if(motionSpline != null) motionSpline.calcSpline(); + if(posCount > 1) + motionSpline.calcSpline(); } long curTime = System.currentTimeMillis(); - long timeStep = curTime - lastRealTime; + long timeStep; + if(recording) { + timeStep = 1000/ReplayMod.replaySettings.getVideoFramerate(); + } else { + timeStep = curTime - lastRealTime; + } int curRealReplayTime = (int)(lastRealReplayTime + timeStep); @@ -225,7 +237,7 @@ public class ReplayProcess { double curSpeed = 0f; - if(nextTime != null || lastTime != null) { + if(timeCount > 1 && (nextTime != null || lastTime != null)) { if(nextTime != null) { nextTimeStamp = nextTime.getRealTimestamp(); } else { @@ -239,7 +251,8 @@ public class ReplayProcess { } if(!(nextTime == null || lastTime == null)) { - curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp))); + if(lastTimeStamp == nextTimeStamp) curSpeed = 0f; + else curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp))); } if(lastTimeStamp == nextTimeStamp) { @@ -252,25 +265,31 @@ public class ReplayProcess { float currentPosStepPerc = (float)currentPos/(float)currentPosDiff; //The percentage of the travelled path between the current positions if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0; - + int currentTimeDiff = nextTimeStamp - lastTimeStamp; int currentTime = curRealReplayTime - lastTimeStamp; - + float currentTimeStepPerc = (float)currentTime/(float)currentTimeDiff; //The percentage of the travelled path between the current timestamps if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0; - float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(ReplayHandler.getPosKeyframeCount()-1); - float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(ReplayHandler.getTimeKeyframeCount()-1); - + float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(posCount-1); + float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(timeCount-1); + Position pos = null; - if(!linear) { - pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos))); + if(posCount > 1) { + if(!linear) { + pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos))); + } else { + pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos))); + } } else { - pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos))); + if(posCount == 1) { + pos = ReplayHandler.getNextPositionKeyframe(-1).getPosition(); + } } Integer curPos = null; - if(timeLinear != null) { + if(timeLinear != null && timeCount > 1) { curPos = timeLinear.getPoint(Math.max(0, Math.min(1, timePos))); } @@ -278,164 +297,11 @@ public class ReplayProcess { ReplayHandler.setSpeed(curSpeed); - if(curPos != null) ReplayHandler.setReplayPos(curPos); - - //splinePos = (index of last entry + add) / total entries - - lastRealReplayTime = curRealReplayTime; - lastRealTime = curTime; - - if(requestFinish) { - stopReplayProcess(true); - requestFinish = false; - } - - if(splinePos >= 1) { - requestFinish = true; - } - } - - private static void recordingTick() { - if(ReplayHandler.isHurrying()) { - return; - } - - if(blocked && isVideoRecording()) { - return; - } - - deepBlock = true; - blocked = true; - - if(!linear && motionSpline == null) { - //set up spline path - motionSpline = new SplinePoint(); - for(Keyframe kf : ReplayHandler.getKeyframes()) { - if(kf instanceof PositionKeyframe) { - PositionKeyframe pkf = (PositionKeyframe)kf; - Position pos = pkf.getPosition(); - motionSpline.addPoint(pos); - } - } - } - - if(linear && motionLinear == null) { - //set up linear path - motionLinear = new LinearPoint(); - for(Keyframe kf : ReplayHandler.getKeyframes()) { - if(kf instanceof PositionKeyframe) { - PositionKeyframe pkf = (PositionKeyframe)kf; - Position pos = pkf.getPosition(); - motionLinear.addPoint(pos); - } - } - } - if(timeLinear == null) { - timeLinear = new LinearTimestamp(); - for(Keyframe kf : ReplayHandler.getKeyframes()) { - if(kf instanceof TimeKeyframe) { - timeLinear.addPoint(((TimeKeyframe)kf).getTimestamp()); - } - } - - } - - if(!calculated) { - calculated = true; - motionSpline.calcSpline(); - } - - long curTime = System.currentTimeMillis(); - long timeStep = 1000/ReplayMod.replaySettings.getVideoFramerate(); - - int curRealReplayTime = (int)(lastRealReplayTime + timeStep); - - PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime); - PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime); - - ReplayHandler.setRealTimelineCursor(curRealReplayTime); - - int lastPosStamp = 0; - int nextPosStamp = 0; - - if(nextPos != null || lastPos != null) { - if(nextPos != null) { - nextPosStamp = nextPos.getRealTimestamp(); - } else { - nextPosStamp = lastPos.getRealTimestamp(); - } - - if(lastPos != null) { - lastPosStamp = lastPos.getRealTimestamp(); - } else { - lastPosStamp = nextPos.getRealTimestamp(); - } - } - - TimeKeyframe lastTime = ReplayHandler.getPreviousTimeKeyframe(curRealReplayTime); - TimeKeyframe nextTime = ReplayHandler.getNextTimeKeyframe(curRealReplayTime); - - int lastTimeStamp = 0; - int nextTimeStamp = 0; - - double curSpeed = 0f; - - if(nextTime != null || lastTime != null) { - if(nextTime != null) { - nextTimeStamp = nextTime.getRealTimestamp(); - } else { - nextTimeStamp = lastTime.getRealTimestamp(); - } - - if(lastTime != null) { - lastTimeStamp = lastTime.getRealTimestamp(); - } else { - lastTimeStamp = nextTime.getRealTimestamp(); - } - - if(!(nextTime == null || lastTime == null)) { - curSpeed = ((double)((nextTime.getTimestamp()-lastTime.getTimestamp())))/((double)((nextTimeStamp-lastTimeStamp))); - } - - if(lastTimeStamp == nextTimeStamp) { - curSpeed = 0f; - } - } - - int currentPosDiff = nextPosStamp - lastPosStamp; - int currentPos = curRealReplayTime - lastPosStamp; - - float currentPosStepPerc = (float)currentPos/(float)currentPosDiff; //The percentage of the travelled path between the current positions - if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0; - - int currentTimeDiff = nextTimeStamp - lastTimeStamp; - int currentTime = curRealReplayTime - lastTimeStamp; - - float currentTimeStepPerc = (float)currentTime/(float)currentTimeDiff; //The percentage of the travelled path between the current timestamps - if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0; - - float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentPosStepPerc)/(float)(ReplayHandler.getPosKeyframeCount()-1); - float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentTimeStepPerc)/(float)(ReplayHandler.getTimeKeyframeCount()-1); - - Position pos = null; - if(!linear) { - pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos))); - } else { - pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos))); - } - - Integer curPos = null; - if(timeLinear != null) { - curPos = timeLinear.getPoint(Math.max(0, Math.min(1, timePos))); - } - - if(pos != null) ReplayHandler.getCameraEntity().movePath(pos); - - ReplayHandler.setSpeed((float)curSpeed); - if(isVideoRecording()) { + if(recording) { MCTimerHandler.updateTimer((1f/ReplayMod.replaySettings.getVideoFramerate())); EnchantmentTimer.increaseRecordingTime((1000/ReplayMod.replaySettings.getVideoFramerate())); } + if(curPos != null) ReplayHandler.setReplayPos(curPos); //splinePos = (index of last entry + add) / total entries @@ -458,13 +324,19 @@ public class ReplayProcess { if(requestFinish) { stopReplayProcess(true); - VideoWriter.endRecording(); + requestFinish = false; + if(recording) { + VideoWriter.endRecording(); + } } - if(splinePos >= 1) { + if((splinePos >= 1 || posCount <= 1) && (timePos >= 1 || timeCount <= 1)) { + System.out.println(timePos+" | "+timeCount); requestFinish = true; } - deepBlock = false; + if(recording) { + deepBlock = false; + } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplaySender.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplaySender.java index e65868e3..d32e6c7d 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplaySender.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplaySender.java @@ -280,7 +280,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter { currentTimeStamp = pd.getTimestamp(); //System.out.println(currentTimeStamp); - if(!ReplayHandler.isInPath() && !hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) { + if(!ReplayHandler.isInPath() && !hurryToTimestamp && (mc.theWorld != null && mc.theWorld.getChunkProvider().getLoadedChunkCount() > 0)) { //if(!hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) { int timeWait = (int)Math.round((currentTimeStamp - lastTimeStamp)/replaySpeed); long timeDiff = System.currentTimeMillis() - lastPacketSent; diff --git a/src/main/java/eu/crushedpixel/replaymod/studio/StudioImplementation.java b/src/main/java/eu/crushedpixel/replaymod/studio/StudioImplementation.java index badfad91..491528df 100755 --- a/src/main/java/eu/crushedpixel/replaymod/studio/StudioImplementation.java +++ b/src/main/java/eu/crushedpixel/replaymod/studio/StudioImplementation.java @@ -1,28 +1,43 @@ package eu.crushedpixel.replaymod.studio; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; +import com.google.gson.JsonObject; + +import net.minecraft.network.play.server.S3EPacketTeams; import de.johni0702.replaystudio.PacketData; +import de.johni0702.replaystudio.filter.ChangeTimestampFilter; import de.johni0702.replaystudio.filter.RemoveFilter; import de.johni0702.replaystudio.filter.SquashFilter; import de.johni0702.replaystudio.io.ReplayOutputStream; import de.johni0702.replaystudio.stream.PacketStream; import de.johni0702.replaystudio.studio.ReplayStudio; +import eu.crushedpixel.replaymod.recording.ReplayMetaData; +import eu.crushedpixel.replaymod.utils.ReplayFileIO; public class StudioImplementation { - public static void trimReplay(InputStream replayFileStream, boolean isTmcpr, int beginning, int ending, File outputFile) throws IOException { + public static void trimReplay(File replayFile, boolean isTmcpr, int beginning, int ending, File outputFile) throws IOException { ReplayStudio studio = new ReplayStudio(); - PacketStream stream = studio.createReplayStream(replayFileStream, isTmcpr); + studio.setWrappingEnabled(false); + PacketStream stream = studio.createReplayStream(new FileInputStream(replayFile), isTmcpr); stream.addFilter(new SquashFilter(), -1, beginning); stream.addFilter(new RemoveFilter(), ending, -1); - outputFile.createNewFile(); + ChangeTimestampFilter ctf = new ChangeTimestampFilter(); + JsonObject cfg = new JsonObject(); + cfg.addProperty("offset", -beginning); + ctf.init(studio, cfg); - FileOutputStream fos = new FileOutputStream(outputFile); + stream.addFilter(ctf, beginning, ending); + + File temp = File.createTempFile("trimmed", "tmcpr"); + temp.deleteOnExit(); + + FileOutputStream fos = new FileOutputStream(temp); ReplayOutputStream out = new ReplayOutputStream(studio, fos); PacketData packetData; @@ -32,6 +47,15 @@ public class StudioImplementation { for(PacketData data : stream.end()) { out.write(data); } + out.close(); + + ReplayMetaData metaData = ReplayFileIO.getMetaData(replayFile); + ending = Math.min(metaData.getDuration(), ending); + metaData.setDuration(ending-beginning); + + outputFile.createNewFile(); + + ReplayFileIO.writeReplayFile(outputFile, temp, metaData); } } diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java index ba975cdf..b6981179 100755 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java @@ -45,10 +45,15 @@ import eu.crushedpixel.replaymod.replay.PacketDeserializer; @SuppressWarnings("resource") //Gets handled by finalizer public class ReplayFileIO { - public static List getAllReplayFiles() { + public static File getReplayFolder() { File folder = new File("./replay_recordings/"); folder.mkdirs(); + return folder; + } + + public static List getAllReplayFiles() { List files = new ArrayList(); + File folder = getReplayFolder(); for(File file : folder.listFiles()) { if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals( ConnectionEventHandler.ZIP_FILE_EXTENSION)) { @@ -58,7 +63,7 @@ public class ReplayFileIO { return files; } - private static DataInputStream getMetaDataInputStream(File replayFile) throws Exception { + private static DataInputStream getMetaDataInputStream(File replayFile) throws IOException { ZipFile archive = null; try { @@ -67,7 +72,7 @@ public class ReplayFileIO { ConnectionEventHandler.JSON_FILE_EXTENSION); return new DataInputStream(archive.getInputStream(tmcpr)); - } catch(Exception e) { + } catch(IOException e) { throw e; } } @@ -118,7 +123,7 @@ public class ReplayFileIO { } } - public static ReplayMetaData getMetaData(File replayFile) throws Exception { + public static ReplayMetaData getMetaData(File replayFile) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(getMetaDataInputStream(replayFile))); String json = br.readLine();