From 1772fab2f3ecc8f35c896e68be069bb8ed1e305e Mon Sep 17 00:00:00 2001 From: lantzelot-swe <75668734+lantzelot-swe@users.noreply.github.com> Date: Mon, 13 Dec 2021 19:01:55 +0100 Subject: [PATCH] Improved file name generation and handling of duplicate titles fix: generated file names for covers, screens and game files is improved to consider more characters to avoid that two games point to the same files. fix: When adding a new game where the file names becomes equal to an existing game in the db an additional index is added to the file name as a suffix. fix: file names are re-calculated when a game is saved and renamed if not matching the new rules. --- src/main/java/se/lantz/db/DbConnector.java | 25 +++++++-- .../java/se/lantz/manager/ImportManager.java | 2 +- .../se/lantz/manager/SavedStatesManager.java | 22 ++++---- src/main/java/se/lantz/model/InfoModel.java | 55 +++++++++---------- .../java/se/lantz/model/MainViewModel.java | 20 +++---- src/main/java/se/lantz/util/FileManager.java | 33 +++++------ 6 files changed, 82 insertions(+), 75 deletions(-) diff --git a/src/main/java/se/lantz/db/DbConnector.java b/src/main/java/se/lantz/db/DbConnector.java index d2d6a64..2027274 100644 --- a/src/main/java/se/lantz/db/DbConnector.java +++ b/src/main/java/se/lantz/db/DbConnector.java @@ -24,6 +24,7 @@ import se.lantz.model.data.GameView; import se.lantz.model.data.ViewFilter; import se.lantz.util.DbConstants; import se.lantz.util.ExceptionHandler; +import se.lantz.util.FileManager; import se.lantz.util.GameListDataComparator; public class DbConnector @@ -755,12 +756,19 @@ public class DbConnector return returnValue; } - public int getGameDuplicateIndexToUse(String title) + public int getGameDuplicateIndexToUse(String title, String gameId) { + //This is only called when the title changes for an existing game or when adding a new game + //Use generated name, that is what decides if a duplicate index needs to be used. + //Look at the coverFile column since all covers have the same name ending. + String fileName = FileManager.generateFileNameFromTitle(title, 0); + StringBuilder sqlBuilder = new StringBuilder(); - sqlBuilder.append("SELECT Duplicate FROM gameinfo WHERE title LIKE \""); - sqlBuilder.append(title); - sqlBuilder.append("\";"); + sqlBuilder.append("SELECT rowId, Duplicate FROM gameinfo WHERE Coverfile GLOB \'"); + sqlBuilder.append(fileName); + sqlBuilder.append("-cover*\' OR CoverFile GLOB \'"); + sqlBuilder.append(fileName); + sqlBuilder.append("[0-9][0-9]-cover*\';"); String sql = sqlBuilder.toString(); logger.debug("Checking if game is in db already: {}", sql); int returnIndex = 0; @@ -769,8 +777,13 @@ public class DbConnector ResultSet rs = pstmt.executeQuery(); while (rs.next()) { - //Increase one to the available index since it's the one supposed to be used. - returnIndex = Math.max(returnIndex, rs.getInt(DbConstants.DUPLICATE_INDEX) + 1); + int rowId = rs.getInt("rowId"); + //Ignore the current game if the query matches it + if (gameId.isEmpty() || rowId != Integer.parseInt(gameId)) + { + //Increase one to the available index since it's the one supposed to be used. + returnIndex = Math.max(returnIndex, rs.getInt(DbConstants.DUPLICATE_INDEX) + 1); + } } } catch (SQLException e) diff --git a/src/main/java/se/lantz/manager/ImportManager.java b/src/main/java/se/lantz/manager/ImportManager.java index 3775cb2..2b41ea9 100644 --- a/src/main/java/se/lantz/manager/ImportManager.java +++ b/src/main/java/se/lantz/manager/ImportManager.java @@ -468,7 +468,7 @@ public class ImportManager int duplicateIndex = 0; if (selectedOption == Options.ADD) { - duplicateIndex = uiModel.getDbConnector().getGameDuplicateIndexToUse(title); + duplicateIndex = uiModel.getDbConnector().getGameDuplicateIndexToUse(title, ""); } //Check any duplicates in added rows, always use this otherwise duplicates uses same names. duplicateIndex = duplicateIndex + getDbRowDuplicate(title); diff --git a/src/main/java/se/lantz/manager/SavedStatesManager.java b/src/main/java/se/lantz/manager/SavedStatesManager.java index 6bb9150..54640d2 100644 --- a/src/main/java/se/lantz/manager/SavedStatesManager.java +++ b/src/main/java/se/lantz/manager/SavedStatesManager.java @@ -99,15 +99,13 @@ public class SavedStatesManager } //If the game has been renamed, make sure to rename the saves folder also - if (model.getInfoModel().isTitleChanged()) + String oldFileName = model.getInfoModel().getOldGamesFile(); + String newFileName = model.getInfoModel().getGamesFile(); + File oldSaveFolder = new File(SAVES + oldFileName); + if (!oldFileName.equals(newFileName) && oldSaveFolder.exists()) { - String oldFileName = model.getInfoModel().getOldGamesFile(); - File oldSaveFolder = new File(SAVES + oldFileName); - if (oldSaveFolder.exists()) - { - //Rename old folder to new name - oldSaveFolder.renameTo(new File(SAVES + model.getInfoModel().getGamesFile())); - } + //Rename old folder to new name + oldSaveFolder.renameTo(new File(SAVES + model.getInfoModel().getGamesFile())); } String fileName = model.getInfoModel().getGamesFile(); @@ -557,11 +555,11 @@ public class SavedStatesManager { return savedStatesMap.get(gameFileName) != null ? savedStatesMap.get(gameFileName) : 0; } - + public void checkEnablementOfPalNtscMenuItem(boolean check) { boolean palNtscItemEnabled = false; - + if (check) { //Check if current game has a 0.vsf file and the current game file is a snapshot @@ -583,13 +581,13 @@ public class SavedStatesManager } palNtscFixMenuItem.setEnabled(palNtscItemEnabled); } - + public boolean swapGameFileAndSavedState() { String gamesFile = model.getInfoModel().getGamesFile(); Path gameFilePath = new File(FileManager.GAMES + gamesFile).toPath(); Path firstSavedStatePath = new File(SAVES + gamesFile).toPath().resolve(VSZ0); - + Path tempFilePath = new File(FileManager.GAMES + "temp.gz").toPath(); try { diff --git a/src/main/java/se/lantz/model/InfoModel.java b/src/main/java/se/lantz/model/InfoModel.java index 8f14387..bb7d788 100644 --- a/src/main/java/se/lantz/model/InfoModel.java +++ b/src/main/java/se/lantz/model/InfoModel.java @@ -367,39 +367,34 @@ public class InfoModel extends AbstractModel } } - public boolean updateFileNames() + public void updateFileNames() { - if (isNewGame() || isTitleChanged() || screenNamesNeedsUpdate()) - { - //Keep track of the old names, used when renaming files when saving - oldCoverFile = getCoverFile(); - oldScreens1File = getScreens1File(); - oldScreens2File = getScreens2File(); - oldGamesFile = getGamesFile(); + //Keep track of the old names, used when renaming files when saving + oldCoverFile = getCoverFile(); + oldScreens1File = getScreens1File(); + oldScreens2File = getScreens2File(); + oldGamesFile = getGamesFile(); - disableChangeNotification(true); - String fileName = FileManager.generateFileNameFromTitle(this.title, getDuplicateIndex()); - if (!getCoverFile().isEmpty() || getCoverImage() != null) - { - setCoverFile(fileName + "-cover.png"); - } - if (!getScreens1File().isEmpty() || getScreen1Image() != null) - { - setScreens1File(fileName + "-00.png"); - } - if (!getScreens2File().isEmpty() || getScreen2Image() != null) - { - setScreens2File(fileName + "-01.png"); - } - if (!getGamesFile().isEmpty()) - { - String fileEnding = getGamesFile().substring(getGamesFile().indexOf(".")); - setGamesFile(fileName + fileEnding); - } - disableChangeNotification(false); - return true; + disableChangeNotification(true); + String fileName = FileManager.generateFileNameFromTitle(this.title, getDuplicateIndex()); + if (!getCoverFile().isEmpty() || getCoverImage() != null) + { + setCoverFile(fileName + "-cover.png"); } - return false; + if (!getScreens1File().isEmpty() || getScreen1Image() != null) + { + setScreens1File(fileName + "-00.png"); + } + if (!getScreens2File().isEmpty() || getScreen2Image() != null) + { + setScreens2File(fileName + "-01.png"); + } + if (!getGamesFile().isEmpty()) + { + String fileEnding = getGamesFile().substring(getGamesFile().indexOf(".")); + setGamesFile(fileName + fileEnding); + } + disableChangeNotification(false); } public void updateCoverAndScreensIfEmpty(boolean isC64) diff --git a/src/main/java/se/lantz/model/MainViewModel.java b/src/main/java/se/lantz/model/MainViewModel.java index 9da4323..0cb5865 100644 --- a/src/main/java/se/lantz/model/MainViewModel.java +++ b/src/main/java/se/lantz/model/MainViewModel.java @@ -8,7 +8,6 @@ import java.util.Collections; import java.util.List; import javax.swing.DefaultComboBoxModel; -import javax.swing.ListModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,12 +71,12 @@ public class MainViewModel extends AbstractModel private GameListData selectedData; Scraper scraper = new MobyGamesScraper(); - + public void setSavedStatesManager(SavedStatesManager savedStatesManager) { this.stateManager = savedStatesManager; } - + public SavedStatesManager getSavedStatesManager() { return this.stateManager; @@ -256,7 +255,7 @@ public class MainViewModel extends AbstractModel } //Read available saved states stateManager.readSavedStates(); - + disableChangeNotification(false); notifyChangeForAllModels(); //Do not reset unsaved for new entry @@ -322,7 +321,7 @@ public class MainViewModel extends AbstractModel { return systemModel; } - + public SavedStatesModel getSavedStatesModel() { return stateModel; @@ -492,7 +491,8 @@ public class MainViewModel extends AbstractModel if (infoModel.isNewGame() || infoModel.isTitleChanged()) { //Update duplicate index - infoModel.setDuplicateIndex(dbConnector.getGameDuplicateIndexToUse(infoModel.getTitle())); + infoModel.setDuplicateIndex(dbConnector.getGameDuplicateIndexToUse(infoModel.getTitle(), + this.selectedData.getGameId())); } if (!validateRequiredFields().isEmpty()) @@ -589,7 +589,7 @@ public class MainViewModel extends AbstractModel fileManager.saveFiles(); stateManager.saveSavedStates(); - + //Reset and images that where added previously infoModel.resetImagesAndOldFileNames(); //Reset all models @@ -835,14 +835,14 @@ public class MainViewModel extends AbstractModel { fileManager.runViceWithoutGame(); } - + public void runSnapshotInVice(SavedStatesModel.SAVESTATE saveState) { fileManager.runSnapshotInVice(saveState); } - + public void checkEnablementOfPalNtscMenuItem(boolean check) { - stateManager.checkEnablementOfPalNtscMenuItem(check); + stateManager.checkEnablementOfPalNtscMenuItem(check); } } diff --git a/src/main/java/se/lantz/util/FileManager.java b/src/main/java/se/lantz/util/FileManager.java index 3d88315..05ed1ee 100644 --- a/src/main/java/se/lantz/util/FileManager.java +++ b/src/main/java/se/lantz/util/FileManager.java @@ -113,12 +113,8 @@ public class FileManager public void saveFiles() { - //Check if title is different that in db, then rename existing files! - if (infoModel.isTitleChanged() || infoModel.isAnyScreenRenamed()) - { - //Rename existing covers and screens and game file - renameFiles(); - } + //Rename existing covers and screens and game file if needed + renameFiles(); //Fetch images that has been added BufferedImage cover = infoModel.getCoverImage(); @@ -352,14 +348,7 @@ public class FileManager public static String generateFileNameFromTitle(String title, int duplicateIndex) { // All uppercase letters - // No spaces or special characters - //The maxi game tool seems to work like this: truncate to 23 characters and then remove all special characters. - if (title.length() > 23) - { - title = title.substring(0, 23); - logger.debug("FileName: truncating to : {}", title); - } - // Do the conversion + // No spaces or special characters, remove them first List forbiddenCharsList = " ,:'�-.!+*<>()/[]?|".chars().mapToObj(item -> (char) item).collect(Collectors.toList()); @@ -367,11 +356,23 @@ public class FileManager title.chars().mapToObj(item -> (char) item).filter(character -> !forbiddenCharsList.contains(character)) .map(Character::toUpperCase).collect(Collectors.toList()); String newNameString = newName.stream().map(String::valueOf).collect(Collectors.joining()); - if (duplicateIndex > 0) + + //The maxi game tool seems to truncate to a maximum length of 23 characters. Let's do the same here. + if (newNameString.length() > 23) + { + newNameString = newNameString.substring(0, 23); + logger.debug("FileName: truncating to : {}", title); + } + + //Just add the duplicate index if there are several games with the same name + if (duplicateIndex > 0 && duplicateIndex < 10) { - //Just add the duplicate index if there are several games with the same name newNameString = newNameString + "0" + duplicateIndex; } + else if (duplicateIndex > 9) + { + newNameString = newNameString + duplicateIndex; + } logger.debug("Game title: \"{}\" ---- New fileName: \"{}\"", title, newNameString); return newNameString;