diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java index c38d09a5..5c6fb827 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/timelines/GuiMarkerTimeline.java @@ -1,7 +1,8 @@ package eu.crushedpixel.replaymod.gui.elements.timelines; import eu.crushedpixel.replaymod.ReplayMod; -import eu.crushedpixel.replaymod.holders.MarkerKeyframe; +import eu.crushedpixel.replaymod.holders.Keyframe; +import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.utils.MouseUtils; import net.minecraft.client.Minecraft; @@ -14,7 +15,7 @@ public class GuiMarkerTimeline extends GuiTimeline { private static final int KEYFRAME_MARKER_X = 109; private static final int KEYFRAME_MARKER_Y = 20; - private MarkerKeyframe clickedKeyFrame; + private Keyframe clickedKeyFrame; private long clickTime; private boolean dragging; @@ -36,7 +37,7 @@ public class GuiMarkerTimeline extends GuiTimeline { int tolerance = (int) (2 * Math.round(zoom * timelineLength / width)); - MarkerKeyframe closest = null; + Keyframe closest = null; if(mouseY >= positionY + BORDER_TOP + 10) { closest = ReplayHandler.getClosestMarkerForRealTime((int) time, tolerance); } @@ -71,14 +72,14 @@ public class GuiMarkerTimeline extends GuiTimeline { int tolerance = (int) (2 * Math.round(zoom * timelineLength / width)); - MarkerKeyframe closest = null; + Keyframe closest = null; if(mouseY >= positionY + BORDER_TOP + 10) { closest = ReplayHandler.getClosestMarkerForRealTime((int) time, tolerance); } if(closest != null) { //Jump to clicked Marker Keyframe - ReplayHandler.setLastPosition(closest.getPosition()); + ReplayHandler.setLastPosition(closest.getValue().getPosition()); ReplayMod.replaySender.jumpToTime(closest.getRealTimestamp()); } } @@ -123,7 +124,7 @@ public class GuiMarkerTimeline extends GuiTimeline { drawTimelineCursor(leftTime, rightTime, bodyWidth); //Draw Keyframe logos - for (MarkerKeyframe kf : ReplayHandler.getMarkers()) { + for(Keyframe kf : ReplayHandler.getMarkers()) { if (kf != null && !kf.equals(ReplayHandler.getSelectedMarkerKeyframe())) drawKeyframe(kf, bodyWidth, leftTime, rightTime, segmentLength); } @@ -148,12 +149,12 @@ public class GuiMarkerTimeline extends GuiTimeline { long leftTime = Math.round(timeStart * timelineLength); double segmentLength = timelineLength * zoom; - for(MarkerKeyframe marker : ReplayHandler.getMarkers()) { + for(Keyframe marker : ReplayHandler.getMarkers()) { int keyframeX = getKeyframeX(marker.getRealTimestamp(), leftTime, bodyWidth, segmentLength); if(MouseUtils.isMouseWithinBounds(keyframeX - 2, this.positionY + BORDER_TOP + 10 + 1, 5, 5)) { Point mouse = MouseUtils.getMousePos(); - String markerName = marker.getName(); + String markerName = marker.getValue().getName(); if(markerName == null) markerName = I18n.format("replaymod.gui.ingame.unnamedmarker"); ReplayMod.tooltipRenderer.drawTooltip(mouse.getX(), mouse.getY(), markerName, null, Color.WHITE); @@ -166,7 +167,7 @@ public class GuiMarkerTimeline extends GuiTimeline { } } - private void drawKeyframe(MarkerKeyframe kf, int bodyWidth, long leftTime, long rightTime, double segmentLength) { + private void drawKeyframe(Keyframe kf, int bodyWidth, long leftTime, long rightTime, double segmentLength) { if (kf.getRealTimestamp() <= rightTime && kf.getRealTimestamp() >= leftTime) { int textureX = KEYFRAME_MARKER_X; int textureY = KEYFRAME_MARKER_Y; diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/Marker.java b/src/main/java/eu/crushedpixel/replaymod/holders/Marker.java new file mode 100644 index 00000000..bb13c13a --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/holders/Marker.java @@ -0,0 +1,20 @@ +package eu.crushedpixel.replaymod.holders; + +import eu.crushedpixel.replaymod.interpolation.KeyframeValue; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Marker implements KeyframeValue { + + private String name; + private AdvancedPosition position; + + @Override + public KeyframeValue newInstance() { + return new Marker(); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/MarkerKeyframe.java b/src/main/java/eu/crushedpixel/replaymod/holders/MarkerKeyframe.java deleted file mode 100644 index 7b9ef41b..00000000 --- a/src/main/java/eu/crushedpixel/replaymod/holders/MarkerKeyframe.java +++ /dev/null @@ -1,14 +0,0 @@ -package eu.crushedpixel.replaymod.holders; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class MarkerKeyframe { - - private int realTimestamp; - private AdvancedPosition position; - private String name; - -} diff --git a/src/main/java/eu/crushedpixel/replaymod/recording/DataListener.java b/src/main/java/eu/crushedpixel/replaymod/recording/DataListener.java index dde65a8d..419543de 100755 --- a/src/main/java/eu/crushedpixel/replaymod/recording/DataListener.java +++ b/src/main/java/eu/crushedpixel/replaymod/recording/DataListener.java @@ -3,7 +3,8 @@ package eu.crushedpixel.replaymod.recording; import com.google.common.hash.Hashing; import com.google.common.io.Files; import eu.crushedpixel.replaymod.ReplayMod; -import eu.crushedpixel.replaymod.holders.MarkerKeyframe; +import eu.crushedpixel.replaymod.holders.Keyframe; +import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.holders.PacketData; import eu.crushedpixel.replaymod.utils.ReplayFile; import eu.crushedpixel.replaymod.utils.ReplayFileIO; @@ -35,7 +36,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter { protected boolean alive = true; protected DataWriter dataWriter; protected Set players = new HashSet(); - protected Set markers = new HashSet(); + protected Set> markers = new HashSet>(); private boolean singleplayer; private int saveState = 0; //0: Idle, 1: Saving, 2: Saved @@ -161,7 +162,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter { queue.add(new PacketData(bytes, timestamp)); } - public void requestFinish(Set players, Set markers) { + public void requestFinish(Set players, Set> markers) { active = false; try { diff --git a/src/main/java/eu/crushedpixel/replaymod/recording/PacketListener.java b/src/main/java/eu/crushedpixel/replaymod/recording/PacketListener.java index 5462367c..0684f48d 100755 --- a/src/main/java/eu/crushedpixel/replaymod/recording/PacketListener.java +++ b/src/main/java/eu/crushedpixel/replaymod/recording/PacketListener.java @@ -7,8 +7,9 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.chat.ChatMessageHandler; -import eu.crushedpixel.replaymod.holders.MarkerKeyframe; import eu.crushedpixel.replaymod.holders.AdvancedPosition; +import eu.crushedpixel.replaymod.holders.Keyframe; +import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.utils.ReplayFileIO; import io.netty.channel.ChannelHandlerContext; import net.minecraft.client.Minecraft; @@ -207,7 +208,7 @@ public class PacketListener extends DataListener { AdvancedPosition pos = new AdvancedPosition(Minecraft.getMinecraft().getRenderViewEntity(), false); int timestamp = (int) (System.currentTimeMillis() - startTime); - MarkerKeyframe marker = new MarkerKeyframe(timestamp, pos, null); + Keyframe marker = new Keyframe(timestamp, new Marker(null, pos)); markers.add(marker); diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java index 2cfd2e7d..917744af 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java @@ -47,7 +47,7 @@ public class ReplayHandler { private static int realTimelinePosition = 0; private static Keyframe selectedKeyframe; - private static MarkerKeyframe selectedMarkerKeyframe; + private static Keyframe selectedMarkerKeyframe; private static boolean inPath = false; private static CameraEntity cameraEntity; @@ -59,8 +59,8 @@ public class ReplayHandler { private static Entity currentEntity = null; private static AdvancedPosition lastPosition = null; - private static MarkerKeyframe[] initialMarkers = new MarkerKeyframe[0]; - private static List markerKeyframes = new ArrayList(); + private static Keyframe[] initialMarkers = new Keyframe[0]; + private static List> markerKeyframes = new ArrayList>(); private static float cameraTilt = 0; @@ -95,11 +95,11 @@ public class ReplayHandler { } } - public static MarkerKeyframe[] getMarkers() { - return markerKeyframes.toArray(new MarkerKeyframe[markerKeyframes.size()]); + public static Keyframe[] getMarkers() { + return markerKeyframes.toArray(new Keyframe[markerKeyframes.size()]); } - public static void setMarkers(MarkerKeyframe[] m, boolean write) { + public static void setMarkers(Keyframe[] m, boolean write) { markerKeyframes.clear(); Collections.addAll(markerKeyframes, m); @@ -232,7 +232,7 @@ public class ReplayHandler { else { AdvancedPosition pos = new AdvancedPosition(mc.getRenderViewEntity(), false); int timestamp = ReplayMod.replaySender.currentTimeStamp(); - markerKeyframes.add(new MarkerKeyframe(timestamp, pos, null)); + markerKeyframes.add(new Keyframe(timestamp, new Marker(null, pos))); } } @@ -291,17 +291,17 @@ public class ReplayHandler { fireKeyframesModifyEvent(); } - public static MarkerKeyframe getClosestMarkerForRealTime(int realTime, int tolerance) { - List found = new ArrayList(); - for(MarkerKeyframe kf : markerKeyframes) { + public static Keyframe getClosestMarkerForRealTime(int realTime, int tolerance) { + List> found = new ArrayList>(); + for(Keyframe kf : markerKeyframes) { if(Math.abs(kf.getRealTimestamp() - realTime) <= tolerance) { found.add(kf); } } - MarkerKeyframe closest = null; + Keyframe closest = null; - for(MarkerKeyframe kf : found) { + for(Keyframe kf : found) { if(closest == null || Math.abs(closest.getRealTimestamp() - realTime) > Math.abs(kf.getRealTimestamp() - realTime)) { closest = kf; } @@ -309,15 +309,15 @@ public class ReplayHandler { return closest; } - public static MarkerKeyframe getPreviousMarkerKeyframe(int realTime) { + public static Keyframe getPreviousMarkerKeyframe(int realTime) { if(markerKeyframes.isEmpty()) return null; - MarkerKeyframe backup = null; - List found = new ArrayList(); - for(MarkerKeyframe kf : markerKeyframes) { + Keyframe backup = null; + List> found = new ArrayList>(); + for(Keyframe kf : markerKeyframes) { if(kf.getRealTimestamp() < realTime) { - found.add((MarkerKeyframe)kf); + found.add((Keyframe)kf); } else if(kf.getRealTimestamp() == realTime) { - backup = (MarkerKeyframe)kf; + backup = (Keyframe)kf; } } @@ -326,10 +326,10 @@ public class ReplayHandler { else return backup; } - public static MarkerKeyframe getNextMarkerKeyframe(int realTime) { + public static Keyframe getNextMarkerKeyframe(int realTime) { if(markerKeyframes.isEmpty()) return null; - MarkerKeyframe backup = null; - for(MarkerKeyframe kf : markerKeyframes) { + Keyframe backup = null; + for(Keyframe kf : markerKeyframes) { if(kf.getRealTimestamp() > realTime) { return kf; //first found element is next } else if(kf.getRealTimestamp() == realTime) { @@ -384,19 +384,15 @@ public class ReplayHandler { fireKeyframesModifyEvent(); } - public static boolean isSelected(Keyframe kf) { - return kf == selectedKeyframe; - } - public static void selectKeyframe(Keyframe kf) { selectedKeyframe = kf; } - public static boolean isSelected(MarkerKeyframe kf) { - return kf == selectedMarkerKeyframe; + public static boolean isSelected(Keyframe kf) { + return kf == selectedMarkerKeyframe || kf == selectedMarkerKeyframe; } - public static void selectMarkerKeyframe(MarkerKeyframe kf) { selectedMarkerKeyframe = kf; } + public static void selectMarkerKeyframe(Keyframe kf) { selectedMarkerKeyframe = kf; } public static boolean isInReplay() { return inReplay; @@ -444,8 +440,10 @@ public class ReplayHandler { KeyframeSet[] paths = currentReplayFile.paths().get(); ReplayHandler.setKeyframeRepository(paths == null ? new KeyframeSet[0] : paths, false); - MarkerKeyframe[] markers = currentReplayFile.markers().get(); - if(markers == null) markers = new MarkerKeyframe[0]; + List> markerList = currentReplayFile.markers().get(); + Keyframe[] markers; + if(markerList == null) markers = new Keyframe[0]; + else markers = markerList.toArray(new Keyframe[markerList.size()]); ReplayHandler.setMarkers(markers, false); ReplayHandler.initialMarkers = markers; @@ -557,7 +555,7 @@ public class ReplayHandler { return selectedKeyframe; } - public static MarkerKeyframe getSelectedMarkerKeyframe() { return selectedMarkerKeyframe; } + public static Keyframe getSelectedMarkerKeyframe() { return selectedMarkerKeyframe; } public static int getRealTimelineCursor() { return realTimelinePosition; diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java index 73b9ecf5..ba01ca88 100644 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFile.java @@ -1,13 +1,15 @@ package eu.crushedpixel.replaymod.utils; import com.google.common.base.Supplier; +import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import eu.crushedpixel.replaymod.assets.AssetRepository; import eu.crushedpixel.replaymod.assets.CustomObjectRepository; +import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.KeyframeSet; -import eu.crushedpixel.replaymod.holders.MarkerKeyframe; +import eu.crushedpixel.replaymod.holders.Marker; import eu.crushedpixel.replaymod.holders.PlayerVisibility; import eu.crushedpixel.replaymod.recording.ReplayMetaData; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; @@ -16,10 +18,8 @@ import org.apache.commons.compress.archivers.zip.ZipFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.lang.reflect.Type; +import java.util.*; public class ReplayFile extends ZipFile { @@ -135,17 +135,20 @@ public class ReplayFile extends ZipFile { return getEntry(ENTRY_MARKERS); } - public Supplier markers() { - return new Supplier() { + public Supplier>> markers() { + return new Supplier>>() { @Override - public MarkerKeyframe[] get() { + public List> get() { try { ZipArchiveEntry entry = markersEntry(); if (entry == null) { return null; } BufferedReader reader = new BufferedReader(new InputStreamReader(getInputStream(entry))); - return new Gson().fromJson(reader, MarkerKeyframe[].class); + + Type keyframeType = new TypeToken>>(){}.getType(); + + return new Gson().fromJson(reader, keyframeType); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java index d0f2c646..545002ae 100755 --- a/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java +++ b/src/main/java/eu/crushedpixel/replaymod/utils/ReplayFileIO.java @@ -3,10 +3,7 @@ package eu.crushedpixel.replaymod.utils; import com.google.gson.Gson; import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.assets.CustomObjectRepository; -import eu.crushedpixel.replaymod.holders.KeyframeSet; -import eu.crushedpixel.replaymod.holders.MarkerKeyframe; -import eu.crushedpixel.replaymod.holders.PacketData; -import eu.crushedpixel.replaymod.holders.PlayerVisibility; +import eu.crushedpixel.replaymod.holders.*; import eu.crushedpixel.replaymod.recording.PacketSerializer; import eu.crushedpixel.replaymod.recording.ReplayMetaData; import io.netty.buffer.ByteBuf; @@ -53,7 +50,7 @@ public class ReplayFileIO { return files; } - public static void writeReplayFile(File replayFile, File tempFile, ReplayMetaData metaData, Set markers, + public static void writeReplayFile(File replayFile, File tempFile, ReplayMetaData metaData, Set> markers, Map resourcePacks, Map resourcePackRequests) throws IOException { byte[] buffer = new byte[1024]; @@ -82,7 +79,7 @@ public class ReplayFileIO { zos.putNextEntry(new ZipEntry(ReplayFile.ENTRY_MARKERS)); pw = new PrintWriter(zos); - pw.write(new Gson().toJson(markers.toArray(new MarkerKeyframe[markers.size()]))); + pw.write(new Gson().toJson(markers.toArray(new Keyframe[markers.size()]))); pw.flush(); zos.closeEntry(); } @@ -166,7 +163,7 @@ public class ReplayFileIO { write((Object) metaData, file); } - public static void write(MarkerKeyframe[] markers, File file) throws IOException { + public static void write(Keyframe[] markers, File file) throws IOException { write((Object) markers, file); }