Add rename/discard options to "Replay Saving" gui (closes #319)
This commit is contained in:
@@ -14,6 +14,7 @@ import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
||||
import com.replaymod.replaystudio.stream.IteratorStream;
|
||||
import com.replaymod.replaystudio.studio.ReplayStudio;
|
||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
||||
import com.replaymod.replaystudio.util.Utils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
@@ -106,9 +107,13 @@ public class MarkerProcessor {
|
||||
return suffixes;
|
||||
}
|
||||
|
||||
public static void apply(Path path, Consumer<Float> progress) throws IOException {
|
||||
public static List<Pair<Path, ReplayMetaData>> apply(Path path, Consumer<Float> progress) throws IOException {
|
||||
if (!hasWork(path)) {
|
||||
return;
|
||||
ReplayMetaData metaData;
|
||||
try (ZipReplayFile inputReplayFile = new ZipReplayFile(new ReplayStudio(), path.toFile())) {
|
||||
metaData = inputReplayFile.getMetaData();
|
||||
}
|
||||
return Collections.singletonList(new Pair<>(path, metaData));
|
||||
}
|
||||
|
||||
String replayName = FilenameUtils.getBaseName(path.getFileName().toString());
|
||||
@@ -119,6 +124,8 @@ public class MarkerProcessor {
|
||||
SquashFilter squashFilter = new SquashFilter();
|
||||
squashFilter.init(studio, null);
|
||||
|
||||
List<Pair<Path, ReplayMetaData>> outputPaths = new ArrayList<>();
|
||||
|
||||
Path inputPath = path.resolveSibling("raw").resolve(path.getFileName());
|
||||
Files.createDirectories(inputPath.getParent());
|
||||
Files.move(path, inputPath);
|
||||
@@ -139,7 +146,8 @@ public class MarkerProcessor {
|
||||
Marker nextMarker = markerIterator.next();
|
||||
|
||||
while (nextPacket != null && outputFileSuffixes.hasNext()) {
|
||||
File outputFile = path.resolveSibling(replayName + outputFileSuffixes.next() + ".mcpr").toFile();
|
||||
Path outputPath = path.resolveSibling(replayName + outputFileSuffixes.next() + ".mcpr");
|
||||
File outputFile = outputPath.toFile();
|
||||
try (ZipReplayFile outputReplayFile = new ZipReplayFile(studio, null, outputFile)) {
|
||||
long duration = 0;
|
||||
Set<Marker> outputMarkers = new HashSet<>();
|
||||
@@ -237,6 +245,8 @@ public class MarkerProcessor {
|
||||
}
|
||||
|
||||
outputReplayFile.save();
|
||||
|
||||
outputPaths.add(new Pair(outputPath, metaData));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,5 +255,7 @@ public class MarkerProcessor {
|
||||
cutFilter.release();
|
||||
}
|
||||
}
|
||||
|
||||
return outputPaths;
|
||||
}
|
||||
}
|
||||
|
||||
161
src/main/java/com/replaymod/recording/gui/GuiSavingReplay.java
Normal file
161
src/main/java/com/replaymod/recording/gui/GuiSavingReplay.java
Normal file
@@ -0,0 +1,161 @@
|
||||
package com.replaymod.recording.gui;
|
||||
|
||||
import com.replaymod.core.ReplayMod;
|
||||
import com.replaymod.core.utils.Utils;
|
||||
import com.replaymod.replay.gui.screen.GuiReplayViewer;
|
||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
||||
import de.johni0702.minecraft.gui.container.GuiContainer;
|
||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||
import de.johni0702.minecraft.gui.element.GuiLabel;
|
||||
import de.johni0702.minecraft.gui.element.GuiTextField;
|
||||
import de.johni0702.minecraft.gui.element.GuiTooltip;
|
||||
import de.johni0702.minecraft.gui.element.advanced.GuiProgressBar;
|
||||
import de.johni0702.minecraft.gui.function.Focusable;
|
||||
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
||||
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
||||
import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
||||
import de.johni0702.minecraft.gui.utils.Colors;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.crash.CrashReport;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.replaymod.core.versions.MCVer.getMinecraft;
|
||||
import static de.johni0702.minecraft.gui.utils.Utils.link;
|
||||
|
||||
public class GuiSavingReplay {
|
||||
|
||||
private static final MinecraftClient mc = getMinecraft();
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
private final GuiLabel label = new GuiLabel()
|
||||
.setI18nText("replaymod.gui.replaysaving.title")
|
||||
.setColor(Colors.BLACK);
|
||||
|
||||
private final GuiProgressBar progressBar = new GuiProgressBar()
|
||||
.setHeight(14);
|
||||
|
||||
private final GuiPanel panel = new GuiPanel()
|
||||
.setLayout(new VerticalLayout().setSpacing(2))
|
||||
.addElements(new VerticalLayout.Data(0.5), label, progressBar);
|
||||
|
||||
private final ReplayMod core;
|
||||
private final List<Runnable> apply = new ArrayList<>();
|
||||
|
||||
public GuiSavingReplay(ReplayMod core) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
core.getBackgroundProcesses().addProcess(panel);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
core.getBackgroundProcesses().removeProcess(panel);
|
||||
}
|
||||
|
||||
public GuiProgressBar getProgressBar() {
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
public void presentRenameDialog(List<Pair<Path, ReplayMetaData>> outputPaths) {
|
||||
panel.removeElement(progressBar);
|
||||
|
||||
link(outputPaths.stream().map(it -> addOutput(it.getKey(), it.getValue())).toArray(Focusable[]::new));
|
||||
|
||||
GuiButton applyButton = new GuiButton()
|
||||
.setSize(150, 20)
|
||||
.setI18nLabel("replaymod.gui.done")
|
||||
.onClick(() -> {
|
||||
apply.forEach(Runnable::run);
|
||||
close();
|
||||
});
|
||||
|
||||
panel.addElements(new VerticalLayout.Data(0.5), applyButton);
|
||||
}
|
||||
|
||||
private GuiTextField addOutput(Path path, ReplayMetaData metaData) {
|
||||
String originalName = Utils.fileNameToReplayName(path.getFileName().toString());
|
||||
GuiTextField textField = new GuiTextField()
|
||||
.setSize(130, 20)
|
||||
.setText(originalName)
|
||||
.setI18nHint("replaymod.gui.delete")
|
||||
.setTextColorDisabled(Colors.RED)
|
||||
.setTooltip(createTooltip(path, metaData));
|
||||
GuiButton clearButton = new GuiButton()
|
||||
.setSize(20, 20)
|
||||
.setLabel("X")
|
||||
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.delete"))
|
||||
.onClick(() -> textField.setText(""));
|
||||
GuiPanel row = new GuiPanel()
|
||||
.setLayout(new HorizontalLayout())
|
||||
.addElements(null, textField, clearButton);
|
||||
panel.addElements(new VerticalLayout.Data(0.5), row);
|
||||
|
||||
apply.add(() -> {
|
||||
String newName = textField.getText();
|
||||
if (newName.equals(originalName)) {
|
||||
return;
|
||||
}
|
||||
applyOutput(path, newName);
|
||||
});
|
||||
|
||||
return textField;
|
||||
}
|
||||
|
||||
private GuiPanel createTooltip(Path path, ReplayMetaData metaData) {
|
||||
GuiTooltip tooltip = new GuiTooltip();
|
||||
GuiReplayViewer.GuiReplayEntry entry = new GuiReplayViewer.GuiReplayEntry(path.toFile(), metaData, null);
|
||||
return new GuiPanel().setLayout(new CustomLayout<GuiPanel>() {
|
||||
@Override
|
||||
protected void layout(GuiPanel container, int width, int height) {
|
||||
pos(entry, 4, 4);
|
||||
size(entry, width - 8, height - 8);
|
||||
size(tooltip, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadableDimension calcMinSize(GuiContainer<?> container) {
|
||||
ReadableDimension size = entry.calcMinSize();
|
||||
return new Dimension(size.getWidth() + 8, size.getHeight() + 8);
|
||||
}
|
||||
}).addElements(null, tooltip, entry);
|
||||
}
|
||||
|
||||
private void applyOutput(Path path, String newName) {
|
||||
if (newName.isEmpty()) {
|
||||
try {
|
||||
Files.delete(path);
|
||||
} catch (IOException e) {
|
||||
logger.error("Deleting replay file:", e);
|
||||
CrashReport crashReport = CrashReport.create(e, "Deleting replay file");
|
||||
core.runLater(() -> Utils.error(logger, VanillaGuiScreen.setup(mc.currentScreen), crashReport, () -> {}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Path newPath = path.resolveSibling(Utils.replayNameToFileName(newName));
|
||||
if (Files.exists(newPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Files.move(path, newPath);
|
||||
} catch (IOException e) {
|
||||
logger.error("Renaming replay file:", e);
|
||||
CrashReport crashReport = CrashReport.create(e, "Renaming replay file");
|
||||
core.runLater(() -> Utils.error(logger, VanillaGuiScreen.setup(mc.currentScreen), crashReport, () -> {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.replaymod.core.versions.MCVer;
|
||||
import com.replaymod.editor.gui.MarkerProcessor;
|
||||
import com.replaymod.recording.ReplayModRecording;
|
||||
import com.replaymod.recording.Setting;
|
||||
import com.replaymod.recording.gui.GuiSavingReplay;
|
||||
import com.replaymod.recording.handler.ConnectionEventHandler;
|
||||
import com.replaymod.recording.mixin.SPacketSpawnMobAccessor;
|
||||
import com.replaymod.recording.mixin.SPacketSpawnPlayerAccessor;
|
||||
@@ -19,12 +20,8 @@ import com.replaymod.replaystudio.data.Marker;
|
||||
import com.replaymod.replaystudio.io.ReplayOutputStream;
|
||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
||||
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
||||
import de.johni0702.minecraft.gui.element.GuiLabel;
|
||||
import de.johni0702.minecraft.gui.element.advanced.GuiProgressBar;
|
||||
import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
||||
import de.johni0702.minecraft.gui.utils.Colors;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -70,7 +67,9 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -248,13 +247,9 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
});
|
||||
|
||||
GuiLabel label = new GuiLabel().setI18nText("replaymod.gui.replaysaving.title").setColor(Colors.BLACK);
|
||||
GuiProgressBar progressBar = new GuiProgressBar().setHeight(14);
|
||||
GuiPanel savingProcess = new GuiPanel()
|
||||
.setLayout(new VerticalLayout())
|
||||
.addElements(new VerticalLayout.Data(0.5), label, progressBar);
|
||||
GuiSavingReplay guiSavingReplay = new GuiSavingReplay(core);
|
||||
new Thread(() -> {
|
||||
core.runLater(() -> core.getBackgroundProcesses().addProcess(savingProcess));
|
||||
core.runLater(guiSavingReplay::open);
|
||||
|
||||
saveService.shutdown();
|
||||
try {
|
||||
@@ -268,22 +263,26 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
||||
logger.error("Failed to close packet output stream:", e);
|
||||
}
|
||||
|
||||
List<Pair<Path, ReplayMetaData>> outputPaths;
|
||||
synchronized (replayFile) {
|
||||
try {
|
||||
replayFile.save();
|
||||
replayFile.close();
|
||||
|
||||
if (core.getSettingsRegistry().get(Setting.AUTO_POST_PROCESS) && !ReplayMod.isMinimalMode()) {
|
||||
MarkerProcessor.apply(outputPath, progressBar::setProgress);
|
||||
outputPaths = MarkerProcessor.apply(outputPath, guiSavingReplay.getProgressBar()::setProgress);
|
||||
} else {
|
||||
outputPaths = Collections.singletonList(new Pair<>(outputPath, metaData));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Saving replay file:", e);
|
||||
CrashReport crashReport = CrashReport.create(e, "Saving replay file");
|
||||
core.runLater(() -> Utils.error(logger, VanillaGuiScreen.setup(mc.currentScreen), crashReport, () -> {}));
|
||||
core.runLater(() -> Utils.error(logger, VanillaGuiScreen.setup(mc.currentScreen), crashReport, guiSavingReplay::close));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
core.runLater(() -> core.getBackgroundProcesses().removeProcess(savingProcess));
|
||||
core.runLater(() -> guiSavingReplay.presentRenameDialog(outputPaths));
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user