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.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.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 @@ private void setupMenues() 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 @@ JMenuItem getCarouselPreviewMenuItem() 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 @@ private JMenuItem getPrimaryJoystickItem() 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 @@ private JMenuItem getCopySavedStatesToFileLoaderItem() 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 @@ private void importSavedStates() { 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 @@ private void exportSavedStates() { 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 @@ private void exportGames() 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 @@ private void exportGames() 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 @@ private void exportGamesToFileLoader() 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 @@ private void exportGamesToFileLoader() 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 @@ private void copySavedStatesFromCarouselToFileLoader() 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 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 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 enum Mode 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 SelectDirPanel(Mode mode) 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 SelectDirPanel(Mode mode) 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 void actionPerformed(ActionEvent e) case SAVEDSTATES_EXPORT: selectSavedStatesExportDirectory(); break; + case FIX_CORRUPT_SAVEDSTATES: + selectFixSavedStatesDirectory(); + break; default: break; } @@ -394,6 +410,31 @@ protected JDialog createDialog(Component parent) throws HeadlessException } } + 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 @@ private boolean checkSelectedFolder(Path folder) 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 @@ private boolean checkSelectedFolder(Path folder) } 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 @@ 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 void updateProgress(String infoText) 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.JScrollPane; import javax.swing.JTextArea; +import se.lantz.gui.exports.ImportExportProgressDialog.DIALOGTYPE; + public class ImportExportProgressPanel extends JPanel { private JProgressBar progressBar; @@ -88,7 +90,7 @@ void updateProgress(String infoText) getTextArea().append(infoText); } - public void finish(boolean isImport) + public void finish(DIALOGTYPE type) { getCloseButton().setEnabled(true); getProgressBar().setIndeterminate(false); @@ -96,14 +98,27 @@ public void finish(boolean isImport) //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 void setImportDirectory(File importDir) { this.importDir = importDir; } + + public void setFixDirectory(File fixDir) + { + this.fixDir = fixDir; + } public void setImportOverwrite(boolean importOverwrite) { @@ -498,17 +505,64 @@ public void importSavedStates(PublishWorker worker) //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() {