feat: add support for saved states for games exported to file loader
-Add option in preferences to show saved states for file loader -Add tool to copy saved states for the 1.5.2 Carousel to File Loader fix: trim and remove any " character from the title, author and composer fileds when saving a game.
This commit is contained in:
parent
24fd322d53
commit
97d1c0aa6f
|
@ -42,6 +42,7 @@ import se.lantz.gui.translation.TranslationProgressDialog;
|
|||
import se.lantz.gui.translation.TranslationWorker;
|
||||
import se.lantz.manager.ScraperManager;
|
||||
import se.lantz.model.MainViewModel;
|
||||
import se.lantz.model.PreferencesModel;
|
||||
import se.lantz.model.data.GameListData;
|
||||
import se.lantz.model.data.ScraperFields;
|
||||
import se.lantz.util.FileManager;
|
||||
|
@ -506,7 +507,12 @@ public class GameDetailsBackgroundPanel extends JPanel
|
|||
public void updateSavedStatesTabTitle()
|
||||
{
|
||||
String carouselVersion = FileManager.getConfiguredSavedStatesCarouselVersion();
|
||||
getSystemSavesTabbedPane().setTitleAt(1, "Saved States (Carousel " + carouselVersion + ")");
|
||||
String title = "Saved States (Carousel " + carouselVersion + ")";
|
||||
if (carouselVersion.equals(PreferencesModel.FILE_LOADER))
|
||||
{
|
||||
title = "Saved States (File Loader)";
|
||||
}
|
||||
getSystemSavesTabbedPane().setTitleAt(1, title);
|
||||
getSavesBackgroundPanel().resetCurrentGameReference();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ public class GameListDataRenderer extends DefaultListCellRenderer
|
|||
}
|
||||
else
|
||||
{
|
||||
int numberOfSavedStates = savedStatesManager.getNumberOfSavedStatesForGame(listData.getGameFileName());
|
||||
int numberOfSavedStates = savedStatesManager.getNumberOfSavedStatesForGame(listData.getGameFileName(), listData.getTitle());
|
||||
if (numberOfSavedStates == 1)
|
||||
{
|
||||
this.setIcon(saves1Icon);
|
||||
|
|
|
@ -114,6 +114,7 @@ public class MenuManager
|
|||
private JMenuItem validateDbItem;
|
||||
private JMenuItem palNtscFixItem;
|
||||
private JMenuItem convertSavedStatesItem;
|
||||
private JMenuItem copySavedStatesItem;
|
||||
private JMenuItem resetJoystickConfigItem;
|
||||
|
||||
private JMenuItem installPCUAEItem;
|
||||
|
@ -209,6 +210,7 @@ public class MenuManager
|
|||
toolsMenu.add(getDeleteGamesForViewMenuItem());
|
||||
toolsMenu.addSeparator();
|
||||
toolsMenu.add(getConvertSavedStatesItem());
|
||||
toolsMenu.add(getCopySavedStatesToFileLoaderItem());
|
||||
toolsMenu.add(getResetJoystickConfigItem());
|
||||
toolsMenu.addSeparator();
|
||||
toolsMenu.add(getPalNtscFixMenuItem());
|
||||
|
@ -815,6 +817,18 @@ public class MenuManager
|
|||
}
|
||||
return convertSavedStatesItem;
|
||||
}
|
||||
|
||||
private JMenuItem getCopySavedStatesToFileLoaderItem()
|
||||
{
|
||||
|
||||
if (copySavedStatesItem == null)
|
||||
{
|
||||
copySavedStatesItem = new JMenuItem("Copy Saved states to File Loader...");
|
||||
copySavedStatesItem.setMnemonic('f');
|
||||
copySavedStatesItem.addActionListener(e -> copySavedStatesFromCarouselToFileLoader());
|
||||
}
|
||||
return copySavedStatesItem;
|
||||
}
|
||||
|
||||
private JMenuItem getResetJoystickConfigItem()
|
||||
{
|
||||
|
@ -1289,6 +1303,52 @@ public class MenuManager
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copySavedStatesFromCarouselToFileLoader()
|
||||
{
|
||||
|
||||
JOptionPane.showMessageDialog(MainWindow.getInstance().getMainPanel(),
|
||||
"<html>A Carousel saves the saved states for a game in a folder named after the game file name.<br>When exporting games to File Loader the " +
|
||||
"file name will be based on the title for the game, so the carousel saved states<br>will not be available for exported games.<p><p>With this " +
|
||||
"function you can copy existing saved states for the games in the carousel to a new folder that the File loader will find. <br>It will check all " +
|
||||
"imported saved states and match them towards available games in the manager and create a new folder in the saves directory.<br>You can then export the saved states to your USB stick to use them in the File Loader. <p><p>Press OK to check for saved states that can be copied.</html>",
|
||||
"Copy saved states to File Loader",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
|
||||
|
||||
int numberOfSavesNotAvailableForFileLoader = savedStatesManager.checkForSavedStatesToCopyToFileLoader();
|
||||
|
||||
if (numberOfSavesNotAvailableForFileLoader == 0)
|
||||
{
|
||||
JOptionPane.showMessageDialog(MainWindow.getInstance().getMainPanel(),
|
||||
"No carousel saved states exists that are not available for File Loader. All is up to date.",
|
||||
"Copy saved states to File Loader",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
String message = String
|
||||
.format("<html>There are %s games that have saved states used by the Carousel version 1.5.2 or later.<br>Do you want to copy them to the File Loader format so that they are accessible from the File Loader?</html>",
|
||||
Integer.valueOf(numberOfSavesNotAvailableForFileLoader));
|
||||
int option = JOptionPane.showConfirmDialog(MainWindow.getInstance().getMainPanel(),
|
||||
message,
|
||||
"Copy saved states to File Loader",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE);
|
||||
if (option == JOptionPane.YES_OPTION)
|
||||
{
|
||||
savedStatesManager.copyFromCarouselToFileLoader();
|
||||
//Refresh after converting
|
||||
MainWindow.getInstance().refreshMenuAndUI();
|
||||
//Refresh game views
|
||||
uiModel.reloadGameViews();
|
||||
//Set all games as selected
|
||||
uiModel.setSelectedGameView(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void resetJoystickConfigs()
|
||||
{
|
||||
|
|
|
@ -311,7 +311,7 @@ public class SaveStatePanel extends JPanel
|
|||
BufferedImage image = null;
|
||||
if (!filename.isEmpty())
|
||||
{
|
||||
String fileName = SavedStatesManager.getGameFolderName(model.getInfoModel().getGamesFile());
|
||||
String fileName = SavedStatesManager.getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle());
|
||||
logger.debug(fileName.toString());
|
||||
|
||||
Path saveFolderPath = new File("./saves/" + fileName).toPath();
|
||||
|
|
|
@ -16,7 +16,7 @@ public class PreferencesDialog extends BaseDialog
|
|||
addContent(getPreferencesTabPanel());
|
||||
getOkButton().setText("Save");
|
||||
getOkButton().setPreferredSize(null);
|
||||
this.setPreferredSize(new Dimension(366, 580));
|
||||
this.setPreferredSize(new Dimension(366, 630));
|
||||
this.setResizable(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ public class SaveStatePrefPanel extends JPanel
|
|||
private JRadioButton v152RadioButton;
|
||||
private final ButtonGroup buttonGroup = new ButtonGroup();
|
||||
private PreferencesModel model;
|
||||
private JRadioButton fileLoaderRadioButton;
|
||||
|
||||
public SaveStatePrefPanel(PreferencesModel model)
|
||||
{
|
||||
|
@ -43,13 +44,21 @@ public class SaveStatePrefPanel extends JPanel
|
|||
gbc_v132RadioButton.gridy = 1;
|
||||
add(getV132RadioButton(), gbc_v132RadioButton);
|
||||
GridBagConstraints gbc_v152RadioButton = new GridBagConstraints();
|
||||
gbc_v152RadioButton.weighty = 1.0;
|
||||
gbc_v152RadioButton.insets = new Insets(0, 40, 10, 0);
|
||||
gbc_v152RadioButton.weighty = 0.0;
|
||||
gbc_v152RadioButton.insets = new Insets(0, 40, 0, 0);
|
||||
gbc_v152RadioButton.anchor = GridBagConstraints.NORTHWEST;
|
||||
gbc_v152RadioButton.weightx = 1.0;
|
||||
gbc_v152RadioButton.gridx = 0;
|
||||
gbc_v152RadioButton.gridy = 2;
|
||||
add(getV152RadioButton(), gbc_v152RadioButton);
|
||||
GridBagConstraints gbc_fileLoaderRadioButton = new GridBagConstraints();
|
||||
gbc_fileLoaderRadioButton.insets = new Insets(0, 40, 10, 0);
|
||||
gbc_fileLoaderRadioButton.anchor = GridBagConstraints.NORTHWEST;
|
||||
gbc_fileLoaderRadioButton.gridx = 0;
|
||||
gbc_fileLoaderRadioButton.gridy = 3;
|
||||
gbc_fileLoaderRadioButton.weightx = 1.0;
|
||||
gbc_fileLoaderRadioButton.weighty = 1.0;
|
||||
add(getFileLoaderRadioButton(), gbc_fileLoaderRadioButton);
|
||||
if (!Beans.isDesignTime())
|
||||
{
|
||||
model.addPropertyChangeListener(e -> modelChanged());
|
||||
|
@ -63,8 +72,8 @@ public class SaveStatePrefPanel extends JPanel
|
|||
if (infoLabel == null)
|
||||
{
|
||||
String info = "<html>Different versions of the Carousel adds the saved states in different folders. " +
|
||||
"You have to choose which version of the Carousel you want the manager to read the saved states for. " +
|
||||
"Only saved states for one carousel version at a time is shown for the games in the gamelist views.</html>";
|
||||
"You have to choose which version of the Carousel (or the File Loader) you want the manager to read the saved states for. " +
|
||||
"Only saved states for one option at a time is shown for the games in the gamelist views. Saved states for the File loader is located in a folder mathching the game title.</html>";
|
||||
infoLabel = new JLabel(info);
|
||||
}
|
||||
return infoLabel;
|
||||
|
@ -111,8 +120,30 @@ public class SaveStatePrefPanel extends JPanel
|
|||
return v152RadioButton;
|
||||
}
|
||||
|
||||
private JRadioButton getFileLoaderRadioButton()
|
||||
{
|
||||
if (fileLoaderRadioButton == null)
|
||||
{
|
||||
fileLoaderRadioButton = new JRadioButton("File Loader");
|
||||
buttonGroup.add(fileLoaderRadioButton);
|
||||
fileLoaderRadioButton.addItemListener(new ItemListener()
|
||||
{
|
||||
public void itemStateChanged(ItemEvent e)
|
||||
{
|
||||
if (fileLoaderRadioButton.isSelected())
|
||||
{
|
||||
model.setSavedStatesCarouselVersion(PreferencesModel.FILE_LOADER);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return fileLoaderRadioButton;
|
||||
}
|
||||
|
||||
private void modelChanged()
|
||||
{
|
||||
getV132RadioButton().setSelected(model.getSavedStatesCarouselVersion().equals(PreferencesModel.CAROUSEL_132));
|
||||
getV152RadioButton().setSelected(model.getSavedStatesCarouselVersion().equals(PreferencesModel.CAROUSEL_152));
|
||||
getFileLoaderRadioButton().setSelected(model.getSavedStatesCarouselVersion().equals(PreferencesModel.FILE_LOADER));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.nio.file.FileSystems;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
@ -33,6 +34,7 @@ import se.lantz.model.MainViewModel;
|
|||
import se.lantz.model.PreferencesModel;
|
||||
import se.lantz.model.SavedStatesModel;
|
||||
import se.lantz.model.SavedStatesModel.SAVESTATE;
|
||||
import se.lantz.model.data.GameValidationDetails;
|
||||
import se.lantz.util.ExceptionHandler;
|
||||
import se.lantz.util.FileManager;
|
||||
|
||||
|
@ -107,15 +109,16 @@ public class SavedStatesManager
|
|||
//If the game has been renamed, make sure to rename the saves folder also
|
||||
String oldFileName = model.getInfoModel().getOldGamesFile();
|
||||
String newFileName = model.getInfoModel().getGamesFile();
|
||||
File oldSaveFolder = new File(SAVES + getGameFolderName(oldFileName));
|
||||
File oldSaveFolder = new File(SAVES + getGameFolderName(oldFileName, model.getInfoModel().getTitle()));
|
||||
if (!oldFileName.equals(newFileName) && oldSaveFolder.exists())
|
||||
{
|
||||
//Rename old folder to new name
|
||||
oldSaveFolder.renameTo(new File(SAVES + getGameFolderName(model.getInfoModel().getGamesFile())));
|
||||
oldSaveFolder.renameTo(new File(SAVES +
|
||||
getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle())));
|
||||
}
|
||||
|
||||
String fileName = model.getInfoModel().getGamesFile();
|
||||
Path saveFolder = new File(SAVES + getGameFolderName(fileName)).toPath();
|
||||
Path saveFolder = new File(SAVES + getGameFolderName(fileName, model.getInfoModel().getTitle())).toPath();
|
||||
int numberofSaves = 0;
|
||||
//Check which ones are available
|
||||
Path mta0Path = saveFolder.resolve(MTA0);
|
||||
|
@ -166,9 +169,10 @@ public class SavedStatesManager
|
|||
{
|
||||
savedStatesModel.resetProperties();
|
||||
//Read from state directory, update model
|
||||
String fileName = getGameFolderName(model.getInfoModel().getGamesFile());
|
||||
String fileName = getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle());
|
||||
if (!fileName.isEmpty())
|
||||
{
|
||||
fileName = fileName.trim();
|
||||
//Check if folder is available
|
||||
Path saveFolder = new File(SAVES + fileName).toPath();
|
||||
if (Files.exists(saveFolder))
|
||||
|
@ -335,7 +339,7 @@ public class SavedStatesManager
|
|||
|
||||
private void deleteSavedState(SAVESTATE state)
|
||||
{
|
||||
String fileName = getGameFolderName(model.getInfoModel().getGamesFile());
|
||||
String fileName = getGameFolderName(model.getInfoModel().getGamesFile(), model.getInfoModel().getTitle());
|
||||
Path saveFolder = new File(SAVES + fileName).toPath();
|
||||
try
|
||||
{
|
||||
|
@ -557,10 +561,18 @@ public class SavedStatesManager
|
|||
}
|
||||
}
|
||||
|
||||
public int getNumberOfSavedStatesForGame(String gameFileName)
|
||||
public int getNumberOfSavedStatesForGame(String gameFileName, String title)
|
||||
{
|
||||
String fileName = getGameFolderName(gameFileName);
|
||||
return savedStatesMap.get(fileName) != null ? savedStatesMap.get(fileName) : 0;
|
||||
String fileName = getGameFolderName(gameFileName, title);
|
||||
if (savedStatesMap.get(fileName) == null)
|
||||
{
|
||||
//Check with only uppercase also
|
||||
return savedStatesMap.get(fileName.toUpperCase()) != null ? savedStatesMap.get(fileName.toUpperCase()) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return savedStatesMap.get(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkEnablementOfPalNtscMenuItem(boolean check)
|
||||
|
@ -574,7 +586,7 @@ public class SavedStatesManager
|
|||
if (!fileName.isEmpty() && fileName.contains(".vsf"))
|
||||
{
|
||||
//Check if folder is available
|
||||
Path saveFolder = new File(SAVES + getGameFolderName(fileName)).toPath();
|
||||
Path saveFolder = new File(SAVES + getGameFolderName(fileName, model.getInfoModel().getTitle())).toPath();
|
||||
if (Files.exists(saveFolder))
|
||||
{
|
||||
//Check which ones are available
|
||||
|
@ -593,7 +605,8 @@ public class SavedStatesManager
|
|||
{
|
||||
String gamesFile = model.getInfoModel().getGamesFile();
|
||||
Path gameFilePath = new File(FileManager.GAMES + gamesFile).toPath();
|
||||
Path firstSavedStatePath = new File(SAVES + getGameFolderName(gamesFile)).toPath().resolve(VSZ0);
|
||||
Path firstSavedStatePath =
|
||||
new File(SAVES + getGameFolderName(gamesFile, model.getInfoModel().getTitle())).toPath().resolve(VSZ0);
|
||||
|
||||
Path tempFilePath = new File(FileManager.GAMES + "temp.gz").toPath();
|
||||
try
|
||||
|
@ -620,7 +633,7 @@ public class SavedStatesManager
|
|||
return false;
|
||||
}
|
||||
|
||||
public static String getGameFolderName(String fileName)
|
||||
public static String getGameFolderName(String fileName, String gameTitle)
|
||||
{
|
||||
String returnValue = "";
|
||||
switch (FileManager.getConfiguredSavedStatesCarouselVersion())
|
||||
|
@ -634,6 +647,12 @@ public class SavedStatesManager
|
|||
returnValue = fileName.substring(0, fileName.indexOf("."));
|
||||
}
|
||||
break;
|
||||
case PreferencesModel.FILE_LOADER:
|
||||
if (fileName.length() > 0)
|
||||
{
|
||||
returnValue = FileManager.generateSavedStatesFolderNameForFileLoader(gameTitle, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -727,6 +746,82 @@ public class SavedStatesManager
|
|||
}
|
||||
}
|
||||
|
||||
public void copyFromCarouselToFileLoader()
|
||||
{
|
||||
//1. look through all folders and try to find a game in the db that matches the file name.
|
||||
//2. for all that matches, get the title and copy the existing folder to a folder named as the title
|
||||
File saveFolder = new File(SAVES);
|
||||
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
|
||||
{
|
||||
List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation();
|
||||
|
||||
List<Path> filteredPathList = getMatchingCarousel152FoldersThatCanBeCopied(stream, allGamesDetailsList);
|
||||
//Copy for all
|
||||
filteredPathList.stream().forEachOrdered(sourcePath -> {
|
||||
try
|
||||
{
|
||||
File originalDir = sourcePath.toFile();
|
||||
String fileName = originalDir.getName();
|
||||
|
||||
GameValidationDetails gameDetails = allGamesDetailsList.stream()
|
||||
.filter(game -> fileName.equals(get152VersionFileName(game.getGame()))).findAny().orElse(null);
|
||||
|
||||
if (gameDetails != null)
|
||||
{
|
||||
File newDir = new File(originalDir.getParent() + "\\" +
|
||||
FileManager.generateSavedStatesFolderNameForFileLoader(gameDetails.getTitle(), 0));
|
||||
copyDirectory(sourcePath.toString(), newDir.toPath().toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExceptionHandler.logException(e, "Could not copy available saved states for " + sourcePath.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
ExceptionHandler.handleException(e1, "Could not copy saved states");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) throws IOException
|
||||
{
|
||||
Files.walk(Paths.get(sourceDirectoryLocation)).forEach(source -> {
|
||||
Path destination =
|
||||
Paths.get(destinationDirectoryLocation, source.toString().substring(sourceDirectoryLocation.length()));
|
||||
try
|
||||
{
|
||||
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
ExceptionHandler.logException(e, "Could not copy available saved states from " + sourceDirectoryLocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean is152VersionFolderName(Path folderPath)
|
||||
{
|
||||
String folderName = folderPath.toFile().getName();
|
||||
String newName = folderName;
|
||||
if (folderName.indexOf(".") > -1)
|
||||
{
|
||||
newName = folderName.substring(0, folderName.indexOf("."));
|
||||
}
|
||||
return newName.equalsIgnoreCase(folderName);
|
||||
}
|
||||
|
||||
private String get152VersionFileName(String fileName)
|
||||
{
|
||||
String newName = fileName;
|
||||
if (fileName.indexOf(".") > -1)
|
||||
{
|
||||
newName = fileName.substring(0, fileName.indexOf("."));
|
||||
}
|
||||
return newName;
|
||||
}
|
||||
|
||||
public int checkFor132SavedStates()
|
||||
{
|
||||
File saveFolder = new File(SAVES);
|
||||
|
@ -754,4 +849,41 @@ public class SavedStatesManager
|
|||
}
|
||||
return (int) returnValue;
|
||||
}
|
||||
|
||||
public int checkForSavedStatesToCopyToFileLoader()
|
||||
{
|
||||
//1. look through all folders and try to find a game in the db that matches the file name.
|
||||
//2. for all that matches, get the title and check so that no folder exists already
|
||||
File saveFolder = new File(SAVES);
|
||||
try (Stream<Path> stream = Files.walk(saveFolder.toPath().toAbsolutePath(), 1))
|
||||
{
|
||||
List<GameValidationDetails> allGamesDetailsList = this.model.getDbConnector().fetchAllGamesForDbValdation();
|
||||
List<Path> filteredPathList = getMatchingCarousel152FoldersThatCanBeCopied(stream, allGamesDetailsList);
|
||||
return filteredPathList.size();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
ExceptionHandler.handleException(e1, "Could not check saved states for File Loader");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private List<Path> getMatchingCarousel152FoldersThatCanBeCopied(Stream<Path> stream,
|
||||
List<GameValidationDetails> allGamesDetailsList)
|
||||
{
|
||||
List<Path> filteredPathList = stream.filter(sourcePath -> is152VersionFolderName(sourcePath)).filter(sourcePath -> {
|
||||
File originalDir = sourcePath.toFile();
|
||||
String fileName = originalDir.getName();
|
||||
GameValidationDetails gameDetails = allGamesDetailsList.stream()
|
||||
.filter(game -> fileName.equals(get152VersionFileName(game.getGame()))).findAny().orElse(null);
|
||||
if (gameDetails != null)
|
||||
{
|
||||
File newDir = new File(originalDir.getParent() + "\\" +
|
||||
FileManager.generateSavedStatesFolderNameForFileLoader(gameDetails.getTitle(), 0));
|
||||
return !newDir.exists();
|
||||
}
|
||||
return false;
|
||||
}).collect(Collectors.toList());
|
||||
return filteredPathList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ public class InfoModel extends AbstractModel implements CommonInfoModel
|
|||
public void setTitle(String title)
|
||||
{
|
||||
String old = getTitle();
|
||||
this.title = title;
|
||||
//Remove all " since that messes with the SQL
|
||||
this.title = title.replace("\"", "").trim();
|
||||
if (!Objects.equals(old, title))
|
||||
{
|
||||
notifyChange();
|
||||
|
@ -213,7 +214,8 @@ public class InfoModel extends AbstractModel implements CommonInfoModel
|
|||
public void setComposer(String composer)
|
||||
{
|
||||
String old = getComposer();
|
||||
this.composer = composer;
|
||||
//Remove all " since that messes with the SQL
|
||||
this.composer = composer.replace("\"", "").trim();
|
||||
if (!Objects.equals(old, composer))
|
||||
{
|
||||
notifyChange();
|
||||
|
@ -228,7 +230,8 @@ public class InfoModel extends AbstractModel implements CommonInfoModel
|
|||
public void setAuthor(String author)
|
||||
{
|
||||
String old = getAuthor();
|
||||
this.author = author;
|
||||
//Remove all " since that messes with the SQL
|
||||
this.author = author.replace("\"", "").trim();
|
||||
if (!Objects.equals(old, author))
|
||||
{
|
||||
notifyChange();
|
||||
|
|
|
@ -9,6 +9,7 @@ public class PreferencesModel extends AbstractModel implements CommonInfoModel
|
|||
{
|
||||
public static final String CAROUSEL_132 = "1.3.2";
|
||||
public static final String CAROUSEL_152 = "1.5.2";
|
||||
public static final String FILE_LOADER = "fl";
|
||||
|
||||
public static final String PCUAE_VERSION_CHECK = "checkForPCUAEVersion";
|
||||
public static final String MANGER_VERSION_CHECK = "checkForManagerVersion";
|
||||
|
|
|
@ -619,7 +619,7 @@ public class FileManager
|
|||
public static String generateFileNameFromTitleForFileLoader(String title, int duplicateIndex)
|
||||
{
|
||||
List<Character> forbiddenCharsList =
|
||||
":,'<27>!+*<>/[]?|".chars().mapToObj(item -> (char) item).collect(Collectors.toList());
|
||||
":,'<27>!+*<>/[]?|\"".chars().mapToObj(item -> (char) item).collect(Collectors.toList());
|
||||
|
||||
List<Character> newName = title.chars().mapToObj(item -> (char) item)
|
||||
.filter(character -> !forbiddenCharsList.contains(character)).collect(Collectors.toList());
|
||||
|
@ -629,10 +629,29 @@ public class FileManager
|
|||
//Just add the duplicate index if there are several games with the same name
|
||||
newNameString = newNameString + "_" + duplicateIndex;
|
||||
}
|
||||
newNameString = newNameString.trim();
|
||||
|
||||
logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString);
|
||||
return newNameString;
|
||||
}
|
||||
|
||||
public static String generateSavedStatesFolderNameForFileLoader(String title, int duplicateIndex)
|
||||
{
|
||||
String name = generateFileNameFromTitleForFileLoader(title, duplicateIndex);
|
||||
//Special handling of titles where dots occur, e.g. G.A.C.C.R.R. or H.E.R.O.
|
||||
int dotCount = (int)name.chars().filter(ch -> ch == '.').count();
|
||||
if (dotCount > 4)
|
||||
{
|
||||
//Strip string to only include 4 dots, seems to be a limit there
|
||||
int endIndex = StringUtils.ordinalIndexOf(name, ".", 5);
|
||||
name = name.substring(0, endIndex);
|
||||
}
|
||||
if (name.endsWith("."))
|
||||
{
|
||||
name = name.substring(0, name.lastIndexOf("."));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public void exportGameInfoFile(GameDetails gameDetails, File targetDir, PublishWorker worker, boolean fileLoader)
|
||||
{
|
||||
|
@ -769,7 +788,7 @@ public class FileManager
|
|||
}
|
||||
else
|
||||
{
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile()) +
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
|
||||
"/" + savedStatesModel.getState1File();
|
||||
}
|
||||
}
|
||||
|
@ -783,7 +802,7 @@ public class FileManager
|
|||
}
|
||||
else
|
||||
{
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile()) +
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
|
||||
"/" + savedStatesModel.getState2File();
|
||||
}
|
||||
break;
|
||||
|
@ -796,7 +815,7 @@ public class FileManager
|
|||
}
|
||||
else
|
||||
{
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile()) +
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
|
||||
"/" + savedStatesModel.getState3File();
|
||||
}
|
||||
break;
|
||||
|
@ -809,7 +828,7 @@ public class FileManager
|
|||
}
|
||||
else
|
||||
{
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile()) +
|
||||
gamePathString = SavedStatesManager.SAVES + SavedStatesManager.getGameFolderName(infoModel.getGamesFile(), infoModel.getTitle()) +
|
||||
"/" + savedStatesModel.getState4File();
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue