From 5025e760b5a47d879541c7d6dc8e51bf97efe4bc Mon Sep 17 00:00:00 2001 From: lantzelot-swe <75668734+lantzelot-swe@users.noreply.github.com> Date: Sat, 6 Apr 2024 12:28:30 +0200 Subject: [PATCH] feat: add menu option to fix corrupt saved states --- pom.xml | 2 +- src/main/java/se/lantz/gui/MenuManager.java | 57 ++++++++-- .../java/se/lantz/gui/SelectDirPanel.java | 101 +++++++++--------- .../exports/ImportExportProgressDialog.java | 12 ++- .../exports/ImportExportProgressPanel.java | 21 +++- .../FixCorruptSavedStatesDialog.java | 41 +++++++ .../FixCorruptSavedStatesPanel.java | 64 +++++++++++ .../FixCorruptSavedStatesWorker.java | 62 +++++++++++ .../se/lantz/manager/SavedStatesManager.java | 54 ++++++++++ 9 files changed, 346 insertions(+), 68 deletions(-) create mode 100644 src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java create mode 100644 src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java create mode 100644 src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java diff --git a/pom.xml b/pom.xml index 9efeca6..ff54e17 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 se.lantz PCUAEManager - 2.16.3 + 2.17.0 PCUAEManager Cp1252 diff --git a/src/main/java/se/lantz/gui/MenuManager.java b/src/main/java/se/lantz/gui/MenuManager.java index 2943b9d..41abfc6 100644 --- a/src/main/java/se/lantz/gui/MenuManager.java +++ b/src/main/java/se/lantz/gui/MenuManager.java @@ -37,6 +37,7 @@ import se.lantz.gui.exports.ExportSavedStatesDialog; import se.lantz.gui.exports.ExportSavedStatesWorker; import se.lantz.gui.exports.ExportWorker; import se.lantz.gui.exports.ImportExportProgressDialog; +import se.lantz.gui.exports.ImportExportProgressDialog.DIALOGTYPE; import se.lantz.gui.imports.CarouselImportWorker; import se.lantz.gui.imports.GamebaseImportWorker; import se.lantz.gui.imports.ImportOptionsDialog; @@ -45,6 +46,8 @@ import se.lantz.gui.imports.ImportSavedStatesDialog; import se.lantz.gui.imports.ImportSavedStatesWorker; import se.lantz.gui.install.ManagerDownloadDialog; import se.lantz.gui.preferences.PreferencesDialog; +import se.lantz.gui.savedstates.FixCorruptSavedStatesDialog; +import se.lantz.gui.savedstates.FixCorruptSavedStatesWorker; import se.lantz.manager.BackupManager; import se.lantz.manager.ExportManager; import se.lantz.manager.ImportManager; @@ -130,6 +133,7 @@ public class MenuManager private JMenuItem palNtscFixItem; private JMenuItem convertSavedStatesItem; private JMenuItem copySavedStatesItem; + private JMenuItem fixCorruptSavedStatesItem; private JMenuItem resetJoystickConfigItem; private JMenuItem enableAccurateDiskItem; private JMenuItem disableAccurateDiskItem; @@ -256,6 +260,8 @@ public class MenuManager toolsMenu.addSeparator(); toolsMenu.add(getConvertSavedStatesItem()); toolsMenu.add(getCopySavedStatesToFileLoaderItem()); + toolsMenu.add(getFixCorruptSavedStatesItem()); + toolsMenu.addSeparator(); toolsMenu.add(getResetJoystickConfigItem()); toolsMenu.add(getEnableAccurateDiskItem()); toolsMenu.add(getDisableAccurateDiskItem()); @@ -503,7 +509,8 @@ public class MenuManager KeyStroke keyStrokeCarouselPreview = KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK); carouselPreviewItem.setAccelerator(keyStrokeCarouselPreview); carouselPreviewItem.setMnemonic('W'); - carouselPreviewItem.addActionListener(e -> MainWindow.getInstance().getMainPanel().getListPanel().showCarouselPreview()); + carouselPreviewItem + .addActionListener(e -> MainWindow.getInstance().getMainPanel().getListPanel().showCarouselPreview()); return carouselPreviewItem; } @@ -995,8 +1002,8 @@ public class MenuManager if (dialog.showDialog()) { MainWindow.getInstance().setWaitCursor(true); - List selectedGameIds = MainWindow.getInstance().getMainPanel().getListPanel().getSelectedGameListData().stream() - .map(data -> data.getGameId()).collect(Collectors.toList()); + List selectedGameIds = MainWindow.getInstance().getMainPanel().getListPanel() + .getSelectedGameListData().stream().map(data -> data.getGameId()).collect(Collectors.toList()); uiModel.updatePrimaryJoystickPort(selectedGameIds, dialog.isPort1Primary()); @@ -1093,6 +1100,17 @@ public class MenuManager return copySavedStatesItem; } + private JMenuItem getFixCorruptSavedStatesItem() + { + if (fixCorruptSavedStatesItem == null) + { + fixCorruptSavedStatesItem = new JMenuItem("Fix corrupt Saved states..."); + fixCorruptSavedStatesItem.setMnemonic('o'); + fixCorruptSavedStatesItem.addActionListener(e -> fixCorruptSavedStates()); + } + return fixCorruptSavedStatesItem; + } + private JMenuItem getResetJoystickConfigItem() { if (resetJoystickConfigItem == null) @@ -1360,7 +1378,8 @@ public class MenuManager { savedStatesManager.setImportDirectory(importSavedStatesDialog.getTargetDirectory()); savedStatesManager.setImportOverwrite(importSavedStatesDialog.isImportOverwrite()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Import saved states", true); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Import saved states", DIALOGTYPE.IMPORT); ImportSavedStatesWorker worker = new ImportSavedStatesWorker(savedStatesManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1376,7 +1395,8 @@ public class MenuManager { savedStatesManager.setExportDirectory(exportSavedStatesDialog.getTargetDirectory()); savedStatesManager.setExportOverwrite(exportSavedStatesDialog.isExportOverwrite()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export saved states", false); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Export saved states", DIALOGTYPE.EXPORT); ExportSavedStatesWorker worker = new ExportSavedStatesWorker(savedStatesManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1398,7 +1418,8 @@ public class MenuManager exportManager.setGameViewsToExport(viewList); exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport()); exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT); ExportWorker worker = new ExportWorker(exportManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1412,7 +1433,8 @@ public class MenuManager exportManager.setGamesToExport(gamesList); exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport()); exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT); ExportWorker worker = new ExportWorker(exportManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1436,7 +1458,8 @@ public class MenuManager exportManager.setGameViewsToExport(viewList); exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport()); exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT); ExportFileLoaderWorker worker = new ExportFileLoaderWorker(exportManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1450,7 +1473,8 @@ public class MenuManager exportManager.setGamesToExport(gamesList); exportManager.setDeleteBeforeExport(exportSelectionDialog.deleteBeforeExport()); exportManager.setTargetDirectory(exportSelectionDialog.getTargetDirectory()); - ImportExportProgressDialog dialog = new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", false); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Export games", DIALOGTYPE.EXPORT); ExportFileLoaderWorker worker = new ExportFileLoaderWorker(exportManager, dialog); worker.execute(); dialog.setVisible(true); @@ -1690,7 +1714,22 @@ public class MenuManager uiModel.setSelectedGameView(null); } } + } + private void fixCorruptSavedStates() + { + FixCorruptSavedStatesDialog corruptedDialog = new FixCorruptSavedStatesDialog(); + corruptedDialog.pack(); + corruptedDialog.setLocationRelativeTo(MainWindow.getInstance()); + if (corruptedDialog.showDialog()) + { + savedStatesManager.setFixDirectory(corruptedDialog.getTargetDirectory()); + ImportExportProgressDialog dialog = + new ImportExportProgressDialog(MainWindow.getInstance(), "Fix corrupt saved states", DIALOGTYPE.FIX); + FixCorruptSavedStatesWorker worker = new FixCorruptSavedStatesWorker(savedStatesManager, dialog); + worker.execute(); + dialog.setVisible(true); + } } private void resetControllerConfigs() diff --git a/src/main/java/se/lantz/gui/SelectDirPanel.java b/src/main/java/se/lantz/gui/SelectDirPanel.java index f783f70..44c17e2 100644 --- a/src/main/java/se/lantz/gui/SelectDirPanel.java +++ b/src/main/java/se/lantz/gui/SelectDirPanel.java @@ -22,6 +22,7 @@ import java.util.stream.Stream; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; +import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; @@ -34,7 +35,6 @@ import org.slf4j.LoggerFactory; import se.lantz.util.ExceptionHandler; import se.lantz.util.FileManager; -import javax.swing.JLabel; public class SelectDirPanel extends JPanel { @@ -42,7 +42,8 @@ public class SelectDirPanel extends JPanel public enum Mode { - CAROUSEL_IMPORT, GB_IMPORT, CAROUSEL_EXPORT, FILELOADER_EXPORT, SAVEDSTATES_IMPORT, SAVEDSTATES_EXPORT + CAROUSEL_IMPORT, GB_IMPORT, CAROUSEL_EXPORT, FILELOADER_EXPORT, SAVEDSTATES_IMPORT, SAVEDSTATES_EXPORT, + FIX_CORRUPT_SAVEDSTATES } private static final Logger logger = LoggerFactory.getLogger(SelectDirPanel.class); @@ -52,6 +53,7 @@ public class SelectDirPanel extends JPanel private static final String FILELOADER_EXPORT_DIR_PROPERTY = "flexportDir"; private static final String SAVEDSTATES_IMPORT_DIR_PROPERTY = "savedStatesImportDir"; private static final String SAVEDSTATES_EXPORT_DIR_PROPERTY = "savedStatesExportDir"; + private static final String FIX_SAVEDSTATES_DIR_PROPERTY = "fixSavedStatesDir"; private JTextField dirTextField; private JButton selectDirButton; @@ -148,6 +150,17 @@ public class SelectDirPanel extends JPanel configuredDir = new File(".").getAbsolutePath(); } break; + case FIX_CORRUPT_SAVEDSTATES: + configuredDir = getUsbFilePath(true, false); + if (configuredDir.isEmpty()) + { + configuredDir = FileManager.getConfiguredProperties().getProperty(FIX_SAVEDSTATES_DIR_PROPERTY); + } + if (configuredDir == null) + { + configuredDir = new File(".").getAbsolutePath(); + } + break; default: break; } @@ -161,7 +174,7 @@ public class SelectDirPanel extends JPanel gbc_usbInfoLabel.gridy = 1; add(getUsbInfoLabel(), gbc_usbInfoLabel); } - + private String getUsbFilePath(boolean saveState, boolean fileLoader) { String usbDir = FileManager.getPCUAEUSBPath(saveState, fileLoader); @@ -217,6 +230,9 @@ public class SelectDirPanel extends JPanel case SAVEDSTATES_EXPORT: selectSavedStatesExportDirectory(); break; + case FIX_CORRUPT_SAVEDSTATES: + selectFixSavedStatesDirectory(); + break; default: break; } @@ -394,6 +410,31 @@ public class SelectDirPanel extends JPanel } } + private void selectFixSavedStatesDirectory() + { + final JFileChooser fileChooser = new JFileChooser() + { + @Override + protected JDialog createDialog(Component parent) throws HeadlessException + { + //Set parent to the export dialog + JDialog dlg = super.createDialog(SwingUtilities.getAncestorOfClass(JDialog.class, SelectDirPanel.this)); + return dlg; + } + }; + fileChooser.setDialogTitle("Select a directory containing saved states"); + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fileChooser.setCurrentDirectory(new File(configuredDir)); + int value = fileChooser.showDialog(this, "OK"); + if (value == JFileChooser.APPROVE_OPTION) + { + targetDirectory = fileChooser.getSelectedFile(); + configuredDir = targetDirectory.toPath().toString(); + FileManager.getConfiguredProperties().put(FIX_SAVEDSTATES_DIR_PROPERTY, configuredDir); + getDirTextField().setText(configuredDir); + } + } + public File getTargetDirectory() { return targetDirectory; @@ -417,7 +458,8 @@ public class SelectDirPanel extends JPanel List foundCarousels = Collections.EMPTY_LIST; try (Stream filePathStream = Files.walk(folder, 1)) { - foundCarousels = filePathStream.filter(Files::isDirectory).filter(dir -> isCarouselFolder(dir)).collect(Collectors.toList()); + foundCarousels = + filePathStream.filter(Files::isDirectory).filter(dir -> isCarouselFolder(dir)).collect(Collectors.toList()); } catch (IOException e) { @@ -425,56 +467,13 @@ public class SelectDirPanel extends JPanel } return foundCarousels.size() > 0; } - -// //Assume a games subfolder is available -// Path srcParentFolder = folder.resolve("games"); -// Path srcCoversFolder = srcParentFolder.resolve("covers"); -// Path srcGamesFolder = srcParentFolder.resolve("games"); -// Path srcScreensFolder = srcParentFolder.resolve("screens"); -// -// logger.debug("parent folder: {}", srcParentFolder); -// logger.debug("covers folder: {}", srcCoversFolder); -// logger.debug("games folder: {}", srcGamesFolder); -// logger.debug("screens folder: {}", srcScreensFolder); -// -// // Verify that subfolders are available -// if (Files.exists(srcParentFolder, LinkOption.NOFOLLOW_LINKS) && -// Files.exists(srcCoversFolder, LinkOption.NOFOLLOW_LINKS) && -// Files.exists(srcGamesFolder, LinkOption.NOFOLLOW_LINKS) && -// Files.exists(srcScreensFolder, LinkOption.NOFOLLOW_LINKS)) -// { -// logger.debug("A valid directory!"); -// -// return true; -// } -// else -// { -// //Check if there is no games subfolder, but valid structure -// srcCoversFolder = folder.resolve("covers"); -// srcGamesFolder = folder.resolve("games"); -// srcScreensFolder = folder.resolve("screens"); -// if (Files.exists(srcCoversFolder, LinkOption.NOFOLLOW_LINKS) && -// Files.exists(srcGamesFolder, LinkOption.NOFOLLOW_LINKS) && -// Files.exists(srcScreensFolder, LinkOption.NOFOLLOW_LINKS)) -// { -// logger.debug("A valid directory!"); -// -// return true; -// } -// else -// { -// logger.debug("An ivalid directory!"); -// return false; -// } -// } } - - + private boolean isCarouselFolder(Path folder) { - return Files.exists(folder.resolve("covers"), LinkOption.NOFOLLOW_LINKS) && - Files.exists(folder.resolve("screens"), LinkOption.NOFOLLOW_LINKS) && - Files.exists(folder.resolve("games"), LinkOption.NOFOLLOW_LINKS); + return Files.exists(folder.resolve("covers"), LinkOption.NOFOLLOW_LINKS) && + Files.exists(folder.resolve("screens"), LinkOption.NOFOLLOW_LINKS) && + Files.exists(folder.resolve("games"), LinkOption.NOFOLLOW_LINKS); } public void registerGBFileSelectedActionListener(ActionListener listener) diff --git a/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java b/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java index 6a5ac76..dccad10 100644 --- a/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java +++ b/src/main/java/se/lantz/gui/exports/ImportExportProgressDialog.java @@ -7,16 +7,20 @@ import javax.swing.WindowConstants; public class ImportExportProgressDialog extends JDialog { + public enum DIALOGTYPE + { + IMPORT, EXPORT, FIX + } private static final long serialVersionUID = 1L; private ImportExportProgressPanel panel; - private final boolean isImport; + private final DIALOGTYPE type; - public ImportExportProgressDialog(Frame frame, String title, boolean isImport) + public ImportExportProgressDialog(Frame frame, String title, DIALOGTYPE type) { super(frame, title, true); - this.isImport = isImport; + this.type = type; this.add(getExportProgressPanel()); setSize(900, 600); setLocationRelativeTo(frame); @@ -31,7 +35,7 @@ public class ImportExportProgressDialog extends JDialog public void finish() { - getExportProgressPanel().finish(isImport); + getExportProgressPanel().finish(type); } public ImportExportProgressPanel getExportProgressPanel() diff --git a/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java b/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java index e835881..b46aa40 100644 --- a/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java +++ b/src/main/java/se/lantz/gui/exports/ImportExportProgressPanel.java @@ -10,6 +10,8 @@ import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import se.lantz.gui.exports.ImportExportProgressDialog.DIALOGTYPE; + public class ImportExportProgressPanel extends JPanel { private JProgressBar progressBar; @@ -88,7 +90,7 @@ public class ImportExportProgressPanel extends JPanel getTextArea().append(infoText); } - public void finish(boolean isImport) + public void finish(DIALOGTYPE type) { getCloseButton().setEnabled(true); getProgressBar().setIndeterminate(false); @@ -96,14 +98,27 @@ public class ImportExportProgressPanel extends JPanel //Check for errors String text = getTextArea().getText(); int count = text.length() - text.replace("ERROR:", "").length(); - if (isImport) + switch (type) + { + case IMPORT: { getTextArea().append("\nImport "); + break; } - else + case EXPORT: { getTextArea().append("\nExport "); + break; } + case FIX: + { + getTextArea().append("\nFix "); + break; + } + default: + //Do nothing + } + if (count > 0) { getTextArea().append("ended with " + count/6 + " errors. See pcusb.log for details."); diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java new file mode 100644 index 0000000..2f1a608 --- /dev/null +++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesDialog.java @@ -0,0 +1,41 @@ +package se.lantz.gui.savedstates; + +import java.awt.Dimension; +import java.io.File; + +import se.lantz.gui.BaseDialog; +import se.lantz.gui.MainWindow; + +public class FixCorruptSavedStatesDialog extends BaseDialog +{ + FixCorruptSavedStatesPanel panel; + + public FixCorruptSavedStatesDialog() + { + super(MainWindow.getInstance()); + addContent(getImportSavedStatesPanel()); + setTitle("Fix corrupt saved states"); + this.setPreferredSize(new Dimension(435, 310)); + // getOkButton().setText(""); + this.setResizable(false); + } + + private FixCorruptSavedStatesPanel getImportSavedStatesPanel() + { + if (panel == null) + { + panel = new FixCorruptSavedStatesPanel(); + } + return panel; + } + + public File getTargetDirectory() + { + return getImportSavedStatesPanel().getTargetDirectory(); + } + + // public boolean isImportOverwrite() + // { + // return getImportSavedStatesPanel().isImportOverwrite(); + // } +} diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java new file mode 100644 index 0000000..1ee1e89 --- /dev/null +++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesPanel.java @@ -0,0 +1,64 @@ +package se.lantz.gui.savedstates; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.io.File; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import se.lantz.gui.SelectDirPanel; +import se.lantz.gui.SelectDirPanel.Mode; + +public class FixCorruptSavedStatesPanel extends JPanel +{ + private JLabel infoLabel; + private SelectDirPanel selectDirPanel; + + public FixCorruptSavedStatesPanel() + { + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_infoLabel = new GridBagConstraints(); + gbc_infoLabel.fill = GridBagConstraints.HORIZONTAL; + gbc_infoLabel.anchor = GridBagConstraints.WEST; + gbc_infoLabel.insets = new Insets(10, 10, 0, 10); + gbc_infoLabel.gridx = 0; + gbc_infoLabel.gridy = 0; + add(getInfoLabel(), gbc_infoLabel); + GridBagConstraints gbc_selectDirPanel = new GridBagConstraints(); + gbc_selectDirPanel.anchor = GridBagConstraints.NORTHWEST; + gbc_selectDirPanel.weighty = 1.0; + gbc_selectDirPanel.weightx = 1.0; + gbc_selectDirPanel.insets = new Insets(0, 5, 5, 0); + gbc_selectDirPanel.fill = GridBagConstraints.HORIZONTAL; + gbc_selectDirPanel.gridx = 0; + gbc_selectDirPanel.gridy = 1; + add(getSelectDirPanel(), gbc_selectDirPanel); + } + + private JLabel getInfoLabel() + { + if (infoLabel == null) + { + infoLabel = + new JLabel("Sometimes the saved states on a USB stick can become corrupt and cannot be loaded (a yellow triangle is shown over the screenshot in the saved states UI). This can be fixed by recreating the .mta file.

Select a folder containing saved states to fix any corrupt files:"); + } + return infoLabel; + } + + private SelectDirPanel getSelectDirPanel() + { + if (selectDirPanel == null) + { + selectDirPanel = new SelectDirPanel(Mode.FIX_CORRUPT_SAVEDSTATES); + } + return selectDirPanel; + } + + File getTargetDirectory() + { + return getSelectDirPanel().getTargetDirectory(); + } +} diff --git a/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java new file mode 100644 index 0000000..7244b8f --- /dev/null +++ b/src/main/java/se/lantz/gui/savedstates/FixCorruptSavedStatesWorker.java @@ -0,0 +1,62 @@ +package se.lantz.gui.savedstates; + +import java.util.List; + +import javax.swing.SwingWorker; + +import se.lantz.gui.exports.ImportExportProgressDialog; +import se.lantz.gui.exports.PublishWorker; +import se.lantz.manager.SavedStatesManager; +import se.lantz.util.ExceptionHandler; + +public class FixCorruptSavedStatesWorker extends SwingWorker implements PublishWorker +{ + + private SavedStatesManager savedStatesManager; + private ImportExportProgressDialog dialog; + + public FixCorruptSavedStatesWorker(SavedStatesManager savedStatesManager, ImportExportProgressDialog dialog) + { + this.savedStatesManager = savedStatesManager; + this.dialog = dialog; + } + + @Override + protected Void doInBackground() throws Exception + { + publish("Processing saved states...\n"); + savedStatesManager.fixCorruptSavedStates(this); + publish("Processed " + savedStatesManager.getNumberOfFixedSavedStates() + " saved states."); + publish("Done!"); + return null; + } + + @Override + protected void process(List chunks) + { + for (String value : chunks) + { + dialog.updateProgress(value + "\n"); + } + } + + @Override + protected void done() + { + try + { + get(); + } + catch (Exception e) + { + ExceptionHandler.handleException(e, "Error during fixing corrupt saved states"); + } + dialog.finish(); + } + + @Override + public void publishMessage(String message) + { + publish(message); + } +} diff --git a/src/main/java/se/lantz/manager/SavedStatesManager.java b/src/main/java/se/lantz/manager/SavedStatesManager.java index c357b91..d6f2171 100644 --- a/src/main/java/se/lantz/manager/SavedStatesManager.java +++ b/src/main/java/se/lantz/manager/SavedStatesManager.java @@ -64,11 +64,13 @@ public class SavedStatesManager private File exportDir; private File importDir; + private File fixDir; private boolean exportOverwrite; private boolean importOverwrite; private int noFilesCopied = 0; + private int noSavedStatesFixed = 0; /** * Map holding available saved states with fileName (subfolder) as key and number of saved states available as value @@ -328,6 +330,11 @@ public class SavedStatesManager { this.importDir = importDir; } + + public void setFixDirectory(File fixDir) + { + this.fixDir = fixDir; + } public void setImportOverwrite(boolean importOverwrite) { @@ -498,17 +505,64 @@ public class SavedStatesManager //Update model list after import model.getGameListModel().notifyChange(); } + + public void fixCorruptSavedStates(PublishWorker worker) + { + noSavedStatesFixed = 0; + + try (Stream stream = Files.walk(fixDir.toPath().toAbsolutePath())) + { + stream.forEachOrdered(sourcePath -> { + try + { + if (!isValidSaveStateMtaFilePath(sourcePath)) + { + return; + } + + worker.publishMessage("Fixing " + sourcePath); + //Read the mta file and keep track of the time + String playTime = readPlayTime(sourcePath); + //Copy the template file + FileUtils.copyInputStreamToFile(getClass().getResourceAsStream("/se/lantz/template.mta"), sourcePath.toFile()); + //Write the time from the old file + storePlayTime(sourcePath, playTime); + noSavedStatesFixed++; + } + catch (Exception e) + { + worker.publishMessage("Could not fix " + sourcePath.toString()); + ExceptionHandler.logException(e, "Could not fix " + sourcePath.toString()); + } + }); + } + catch (IOException e1) + { + ExceptionHandler.handleException(e1, "Could not fix saved states files."); + } + } private boolean isValidSaveStatePath(Path path) { PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.{mta,png,vsz}"); return matcher.matches(path) || path.toFile().isDirectory(); } + + private boolean isValidSaveStateMtaFilePath(Path path) + { + PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.{mta}"); + return matcher.matches(path); + } public int getNumberOfFilesCopied() { return noFilesCopied; } + + public int getNumberOfFixedSavedStates() + { + return noSavedStatesFixed; + } public void readSavedStatesAndUpdateMap() {