diff --git a/ReplayStudio b/ReplayStudio index ebdef6fc..99955dd5 160000 --- a/ReplayStudio +++ b/ReplayStudio @@ -1 +1 @@ -Subproject commit ebdef6fc1b6f62cab6b06b0f37f11565a6bc9d04 +Subproject commit 99955dd5646cb26bf754bee94b5efc5d80919935 diff --git a/jGui b/jGui index f7270bb5..87f7f270 160000 --- a/jGui +++ b/jGui @@ -1 +1 @@ -Subproject commit f7270bb5f960a75eeaa1164592684e99b3a5ac12 +Subproject commit 87f7f270098bde3dac1cb65628f5f1315bce3a09 diff --git a/src/main/java/com/replaymod/core/ReplayMod.java b/src/main/java/com/replaymod/core/ReplayMod.java index d348abc9..41e13c8c 100755 --- a/src/main/java/com/replaymod/core/ReplayMod.java +++ b/src/main/java/com/replaymod/core/ReplayMod.java @@ -122,6 +122,22 @@ public class ReplayMod { testIfMoeshAndExitMinecraft(); runLater(() -> { + // Cleanup deleted corrupted replays + try { + File[] files = getReplayFolder().listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory() && file.getName().endsWith(".mcpr.del")) { + if (file.lastModified() + 2 * 24 * 60 * 60 * 1000 < System.currentTimeMillis()) { + FileUtils.deleteDirectory(file); + } + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + // Restore corrupted replays try { File[] files = getReplayFolder().listFiles(); diff --git a/src/main/java/com/replaymod/online/gui/GuiReplayCenter.java b/src/main/java/com/replaymod/online/gui/GuiReplayCenter.java index e1054c96..c7e375fe 100644 --- a/src/main/java/com/replaymod/online/gui/GuiReplayCenter.java +++ b/src/main/java/com/replaymod/online/gui/GuiReplayCenter.java @@ -20,6 +20,7 @@ import com.replaymod.online.api.replay.pagination.FavoritedFilePagination; import com.replaymod.online.api.replay.pagination.Pagination; import com.replaymod.online.api.replay.pagination.SearchPagination; import com.replaymod.replaystudio.replay.ReplayMetaData; +import com.replaymod.replaystudio.studio.ReplayStudio; import de.johni0702.minecraft.gui.container.AbstractGuiContainer; import de.johni0702.minecraft.gui.container.GuiContainer; import de.johni0702.minecraft.gui.container.GuiPanel; @@ -115,6 +116,9 @@ public class GuiReplayCenter extends GuiScreen { boolean disliked = dislikedReplays.contains(replayId); loadButton.setI18nLabel(selected.downloaded ? "replaymod.gui.load" : "replaymod.gui.download"); + if (selected.incompatible) { + loadButton.setDisabled(); + } favoriteButton.setI18nLabel("replaymod.gui.center." + (favorited ? "unfavorite" : "favorite")); // Only allow button usage for either unfavorite or favorite after they've actually downloaded it @@ -339,6 +343,7 @@ public class GuiReplayCenter extends GuiScreen { public final GuiLabel author = new GuiLabel(); public final GuiLabel date = new GuiLabel().setColor(Colors.LIGHT_GRAY); public final GuiLabel server = new GuiLabel().setColor(Colors.LIGHT_GRAY); + public final GuiLabel version = new GuiLabel().setColor(Colors.RED); public final GuiLabel category = new GuiLabel().setColor(Colors.GREY); public final GuiPanel stats = new GuiPanel().setLayout(new HorizontalLayout().setSpacing(3)); public final GuiLabel favorites = new GuiLabel(stats).setColor(Colors.ORANGE); @@ -353,9 +358,10 @@ public class GuiReplayCenter extends GuiScreen { pos(category, 0, y(server) + height(server) + 3); pos(date, width - width(date), y(author)); + pos(version, width - width(version), y(server)); pos(stats, width - width(stats), y(category)); } - }).addElements(null, name, author, date, server, category, stats); + }).addElements(null, name, author, date, server, version, category, stats); public final GuiImage thumbnail; public final GuiLabel duration = new GuiLabel(); public final GuiPanel durationPanel = new GuiPanel().setBackgroundColor(Colors.HALF_TRANSPARENT) @@ -389,6 +395,7 @@ public class GuiReplayCenter extends GuiScreen { private final long dateMillis; private final int sortId; private final boolean downloaded; + private final boolean incompatible; public GuiReplayEntry(FileInfo fileInfo, BufferedImage thumbImage, int sortId, boolean downloaded) { this.fileInfo = fileInfo; @@ -404,6 +411,10 @@ public class GuiReplayCenter extends GuiScreen { } else { server.setText(metaData.getServerName()); } + incompatible = !new ReplayStudio().isCompatible(fileInfo.getMetadata().getFileFormatVersion()); + if (incompatible) { + version.setText("Minecraft " + fileInfo.getMetadata().getMcVersion()); + } dateMillis = metaData.getDate(); date.setText(new SimpleDateFormat().format(new Date(dateMillis))); if (thumbImage == null) { diff --git a/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java b/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java index c03a3690..3d78603a 100644 --- a/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java +++ b/src/main/java/com/replaymod/pathing/player/AbstractTimelinePlayer.java @@ -79,6 +79,7 @@ public abstract class AbstractTimelinePlayer { public void onTick(ReplayTimer.UpdatedEvent event) { if (future.isDone()) { mc.timer = ((ReplayTimer) mc.timer).getWrapped(); + replayHandler.getReplaySender().setReplaySpeed(0); replayHandler.getReplaySender().setAsyncMode(true); MinecraftForge.EVENT_BUS.unregister(this); return; diff --git a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java index 964dac1e..3e3ddbdb 100644 --- a/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java +++ b/src/main/java/com/replaymod/render/gui/GuiRenderSettings.java @@ -186,7 +186,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { // Closing this GUI ensures that settings are saved getMinecraft().displayGuiScreen(null); try { - VideoRenderer videoRenderer = new VideoRenderer(save(true), replayHandler, timeline); + VideoRenderer videoRenderer = new VideoRenderer(save(false), replayHandler, timeline); videoRenderer.renderVideo(); } catch (IOException e) { e.printStackTrace(); @@ -378,7 +378,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { updateInputs(); } - public RenderSettings save(boolean saveOutputFile) { + public RenderSettings save(boolean serialize) { return new RenderSettings( renderMethodDropdown.getSelectedValue(), encodingPresetDropdown.getSelectedValue(), @@ -386,13 +386,13 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { videoHeight.getInteger(), frameRateSlider.getValue() + 10, bitRateField.getInteger() << (10 * bitRateUnit.getSelected()), - saveOutputFile ? outputFile : null, + serialize ? null : outputFile, nametagCheckbox.isChecked(), - stabilizeYaw.isChecked(), - stabilizePitch.isChecked(), - stabilizeRoll.isChecked(), + stabilizeYaw.isChecked() && (serialize || stabilizeYaw.isEnabled()), + stabilizePitch.isChecked() && (serialize || stabilizePitch.isEnabled()), + stabilizeRoll.isChecked() && (serialize || stabilizeRoll.isEnabled()), chromaKeyingCheckbox.isChecked() ? chromaKeyingColor.getColor() : null, - inject360Metadata.isChecked(), + inject360Metadata.isChecked() && (serialize || inject360Metadata.isEnabled()), exportCommand.getText(), exportArguments.getText(), net.minecraft.client.gui.GuiScreen.isCtrlKeyDown() @@ -412,7 +412,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable { @Override public void close() { - RenderSettings settings = save(false); + RenderSettings settings = save(true); String json = new Gson().toJson(settings); Configuration config = ReplayModRender.instance.getConfiguration(); getConfigProperty(config).set(json); diff --git a/src/main/java/com/replaymod/replay/gui/screen/GuiReplayViewer.java b/src/main/java/com/replaymod/replay/gui/screen/GuiReplayViewer.java index 9132492c..307238f3 100755 --- a/src/main/java/com/replaymod/replay/gui/screen/GuiReplayViewer.java +++ b/src/main/java/com/replaymod/replay/gui/screen/GuiReplayViewer.java @@ -6,7 +6,12 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.mojang.realmsclient.gui.ChatFormatting; import com.replaymod.core.gui.GuiReplaySettings; +import com.replaymod.core.utils.Utils; import com.replaymod.replay.ReplayModReplay; +import com.replaymod.replaystudio.replay.ReplayFile; +import com.replaymod.replaystudio.replay.ReplayMetaData; +import com.replaymod.replaystudio.replay.ZipReplayFile; +import com.replaymod.replaystudio.studio.ReplayStudio; import de.johni0702.minecraft.gui.container.AbstractGuiContainer; import de.johni0702.minecraft.gui.container.GuiContainer; import de.johni0702.minecraft.gui.container.GuiPanel; @@ -20,11 +25,6 @@ import de.johni0702.minecraft.gui.layout.VerticalLayout; import de.johni0702.minecraft.gui.popup.GuiYesNoPopup; import de.johni0702.minecraft.gui.utils.Colors; import de.johni0702.minecraft.gui.utils.Consumer; -import com.replaymod.replaystudio.replay.ReplayFile; -import com.replaymod.replaystudio.replay.ReplayMetaData; -import com.replaymod.replaystudio.replay.ZipReplayFile; -import com.replaymod.replaystudio.studio.ReplayStudio; -import com.replaymod.core.utils.Utils; import net.minecraft.client.gui.GuiErrorScreen; import net.minecraft.client.resources.I18n; import net.minecraft.util.Util; @@ -54,6 +54,9 @@ public class GuiReplayViewer extends GuiScreen { @Override public void run() { replayButtonPanel.forEach(IGuiButton.class).setEnabled(list.getSelected() != null); + if (list.getSelected() != null && list.getSelected().incompatible) { + loadButton.setDisabled(); + } } }).onLoad(new Consumer>> () { @Override @@ -95,6 +98,10 @@ public class GuiReplayViewer extends GuiScreen { e.printStackTrace(); } } + }).onSelectionDoubleClicked(() -> { + if (this.loadButton.isEnabled()) { + this.loadButton.onClick(); + } }).setDrawShadow(true).setDrawSlider(true); public final GuiButton loadButton = new GuiButton().onClick(new Runnable() { @@ -270,6 +277,7 @@ public class GuiReplayViewer extends GuiScreen { public final GuiLabel date = new GuiLabel().setColor(Colors.LIGHT_GRAY); public final GuiPanel infoPanel = new GuiPanel(this).setLayout(new VerticalLayout().setSpacing(2)) .addElements(null, name, server, date); + public final GuiLabel version = new GuiLabel(this).setColor(Colors.RED); public final GuiImage thumbnail; public final GuiLabel duration = new GuiLabel(); public final GuiPanel durationPanel = new GuiPanel().setBackgroundColor(Colors.HALF_TRANSPARENT) @@ -287,6 +295,7 @@ public class GuiReplayViewer extends GuiScreen { }); private final long dateMillis; + private final boolean incompatible; public GuiReplayEntry(File file, ReplayMetaData metaData, BufferedImage thumbImage) { this.file = file; @@ -297,6 +306,10 @@ public class GuiReplayViewer extends GuiScreen { } else { server.setText(metaData.getServerName()); } + incompatible = !new ReplayStudio().isCompatible(metaData.getFileFormatVersion()); + if (incompatible) { + version.setText("Minecraft " + metaData.getMcVersion()); + } dateMillis = metaData.getDate(); date.setText(new SimpleDateFormat().format(new Date(dateMillis))); if (thumbImage == null) { @@ -316,6 +329,7 @@ public class GuiReplayViewer extends GuiScreen { y(durationPanel, height(thumbnail) - height(durationPanel)); pos(infoPanel, width(thumbnail) + 5, 0); + pos(version, width - width(version), 0); } @Override diff --git a/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java b/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java index 5ed8d7af..e130b408 100644 --- a/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java +++ b/src/main/java/com/replaymod/simplepathing/ReplayModSimplePathing.java @@ -84,6 +84,9 @@ public class ReplayModSimplePathing implements PathingRegistry { } public void setCurrentTimeline(Timeline currentTimeline) { + if (this.currentTimeline != currentTimeline) { + selectedKeyframe = null; + } this.currentTimeline = currentTimeline; } diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiKeyframeTimeline.java b/src/main/java/com/replaymod/simplepathing/gui/GuiKeyframeTimeline.java index f8617fb4..e9017265 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiKeyframeTimeline.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiKeyframeTimeline.java @@ -208,6 +208,7 @@ public class GuiKeyframeTimeline extends AbstractGuiTimeline