add in analysis for layout, preferences, and gauntlet files

allow items to be deselected in the migration dialog so people can look at a single set at a time to see how the mapping works
This commit is contained in:
myk
2013-03-12 04:16:27 +00:00
parent e42cc8d4d4
commit 1f863298af
4 changed files with 261 additions and 132 deletions

View File

@@ -160,7 +160,7 @@ public class DialogMigrateProfile {
@Override public void run() { btnCancel.requestFocusInWindow(); } @Override public void run() { btnCancel.requestFocusInWindow(); }
}); });
_AnalyzerUpdater analyzer = new _AnalyzerUpdater(srcDir, !emptySrcDir); _AnalyzerUpdater analyzer = new _AnalyzerUpdater(srcDir);
analyzer.execute(); analyzer.execute();
} }
@@ -195,7 +195,7 @@ public class DialogMigrateProfile {
// used to ensure we only have one UI update pending at a time // used to ensure we only have one UI update pending at a time
private volatile boolean _uiUpdateAck; private volatile boolean _uiUpdateAck;
public _AnalyzerUpdater(String srcDir, boolean forced) { public _AnalyzerUpdater(String srcDir) {
_srcDir = srcDir; _srcDir = srcDir;
_selectionPanel.removeAll(); _selectionPanel.removeAll();
@@ -208,12 +208,12 @@ public class DialogMigrateProfile {
JPanel knownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2")); JPanel knownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2"));
knownDeckPanel.setOpaque(false); knownDeckPanel.setOpaque(false);
knownDeckPanel.add(new FLabel.Builder().text("Decks").build(), "wrap"); knownDeckPanel.add(new FLabel.Builder().text("Decks").build(), "wrap");
_addSelectionWidget(knownDeckPanel, forced, OpType.CONSTRUCTED_DECK, "Constructed decks"); _addSelectionWidget(knownDeckPanel, OpType.CONSTRUCTED_DECK, "Constructed decks");
_addSelectionWidget(knownDeckPanel, forced, OpType.DRAFT_DECK, "Draft decks"); _addSelectionWidget(knownDeckPanel, OpType.DRAFT_DECK, "Draft decks");
_addSelectionWidget(knownDeckPanel, forced, OpType.PLANAR_DECK, "Planar decks"); _addSelectionWidget(knownDeckPanel, OpType.PLANAR_DECK, "Planar decks");
_addSelectionWidget(knownDeckPanel, forced, OpType.SCHEME_DECK, "Scheme decks"); _addSelectionWidget(knownDeckPanel, OpType.SCHEME_DECK, "Scheme decks");
_addSelectionWidget(knownDeckPanel, forced, OpType.SEALED_DECK, "Sealed decks"); _addSelectionWidget(knownDeckPanel, OpType.SEALED_DECK, "Sealed decks");
_addSelectionWidget(knownDeckPanel, forced, OpType.UNKNOWN_DECK, "Unknown decks"); _addSelectionWidget(knownDeckPanel, OpType.UNKNOWN_DECK, "Unknown decks");
JPanel unknownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5")); JPanel unknownDeckPanel = new JPanel(new MigLayout("insets 0, gap 5"));
unknownDeckPanel.setOpaque(false); unknownDeckPanel.setOpaque(false);
_unknownDeckCombo = new JComboBox(); _unknownDeckCombo = new JComboBox();
@@ -231,20 +231,20 @@ public class DialogMigrateProfile {
JPanel dataPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap")); JPanel dataPanel = new JPanel(new MigLayout("insets 0, gap 5, wrap"));
dataPanel.setOpaque(false); dataPanel.setOpaque(false);
dataPanel.add(new FLabel.Builder().text("Other data").build()); dataPanel.add(new FLabel.Builder().text("Other data").build());
_addSelectionWidget(dataPanel, forced, OpType.GAUNTLET_DATA, "Gauntlet data"); _addSelectionWidget(dataPanel, OpType.GAUNTLET_DATA, "Gauntlet data");
_addSelectionWidget(dataPanel, forced, OpType.QUEST_DATA, "Quest saves"); _addSelectionWidget(dataPanel, OpType.QUEST_DATA, "Quest saves");
_addSelectionWidget(dataPanel, forced, OpType.PREFERENCE_FILE, "Preference files"); _addSelectionWidget(dataPanel, OpType.PREFERENCE_FILE, "Preference files");
cbPanel.add(dataPanel, "aligny top"); cbPanel.add(dataPanel, "aligny top");
// add cacheDir data elements // add cacheDir data elements
JPanel cachePanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2")); JPanel cachePanel = new JPanel(new MigLayout("insets 0, gap 5, wrap 2"));
cachePanel.setOpaque(false); cachePanel.setOpaque(false);
cachePanel.add(new FLabel.Builder().text("Cached data").build(), "wrap"); cachePanel.add(new FLabel.Builder().text("Cached data").build(), "wrap");
_addSelectionWidget(cachePanel, forced, OpType.DEFAULT_CARD_PIC, "Default card pics"); _addSelectionWidget(cachePanel, OpType.DEFAULT_CARD_PIC, "Default card pics");
_addSelectionWidget(cachePanel, forced, OpType.SET_CARD_PIC, "Set-specific card pics"); _addSelectionWidget(cachePanel, OpType.SET_CARD_PIC, "Set-specific card pics");
_addSelectionWidget(cachePanel, forced, OpType.TOKEN_PIC, "Card token pics"); _addSelectionWidget(cachePanel, OpType.TOKEN_PIC, "Card token pics");
_addSelectionWidget(cachePanel, forced, OpType.QUEST_PIC, "Quest-related pics"); _addSelectionWidget(cachePanel, OpType.QUEST_PIC, "Quest-related pics");
_addSelectionWidget(cachePanel, forced, OpType.DB_FILE, "Database files"); _addSelectionWidget(cachePanel, OpType.DB_FILE, "Database files");
cbPanel.add(cachePanel, "aligny top"); cbPanel.add(cachePanel, "aligny top");
_selectionPanel.add(cbPanel, "center"); _selectionPanel.add(cbPanel, "center");
@@ -285,11 +285,10 @@ public class DialogMigrateProfile {
_updateUI(); _updateUI();
} }
private void _addSelectionWidget(JPanel parent, boolean forced, OpType type, String name) { private void _addSelectionWidget(JPanel parent, OpType type, String name) {
FCheckBox cb = new FCheckBox(); FCheckBox cb = new FCheckBox();
cb.setName(name); cb.setName(name);
cb.setSelected(true); cb.setSelected(true);
cb.setEnabled(!forced);
cb.addChangeListener(_stateChangedListener); cb.addChangeListener(_stateChangedListener);
// use a skip list map instead of a regular hashmap so that the files are sorted alphabetically // use a skip list map instead of a regular hashmap so that the files are sorted alphabetically

View File

@@ -82,9 +82,7 @@ public class MigrationSourceAnalyzer {
public int getNumFilesAnalyzed() { return _numFilesAnalyzed; } public int getNumFilesAnalyzed() { return _numFilesAnalyzed; }
public void doAnalysis() { public void doAnalysis() {
// TODO: analyze source path tree and populate operation sets // TODO: determine if this is really the res dir
// ensure we ignore data that is already in the destination directory
_analyzeResDir(_source); _analyzeResDir(_source);
} }
@@ -93,27 +91,91 @@ public class MigrationSourceAnalyzer {
// //
private void _analyzeResDir(File root) { private void _analyzeResDir(File root) {
for (File file : root.listFiles()) { _analyzeDir(root, new _Analyzer() {
if (_cb.checkCancel()) { return; } @Override boolean onDir(File dir) {
String dirname = dir.getName();
if ("pics".equals(file.getName())) { if ("decks".equals(dirname)) {
_analyzeCardPicsDir(file); _analyzeDecksDir(dir);
} else if ("gauntlet".equals(dirname)) {
_analyzeGauntletDataDir(dir);
} else if ("layouts".equals(dirname)) {
_analyzeLayoutsDir(dir);
} else if ("pics".equals(dirname)) {
_analyzeCardPicsDir(dir);
} else if ("pics_product".equals(dirname)) {
_analyzeProductPicsDir(dir);
} else if ("preferences".equals(dirname)) {
_analyzePreferencesDir(dir);
} else if ("quest".equals(dirname)) {
_analyzeQuestDir(dir);
} else {
return false;
}
return true;
} }
});
}
// ignore other files //////////////////////////////////////////////////////////////////////////
if (file.isFile()) { // decks
++_numFilesAnalyzed; //
} else if (file.isDirectory()) {
_numFilesAnalyzed += _countFiles(file); private void _analyzeDecksDir(File root) {
System.out.println("analyzing decks directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
} }
} @Override boolean onDir(File dir) {
return false;
}
});
}
//////////////////////////////////////////////////////////////////////////
// gauntlet
//
private void _analyzeGauntletDataDir(File root) {
System.out.println("analyzing gauntlet data directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
// find *.dat files, but exclude LOCKED_*
String filename = file.getName();
if (filename.endsWith(".dat") && !filename.startsWith("LOCKED_")) {
File targetFile = new File(NewConstants.GAUNTLET_DIR.userPrefLoc, file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(OpType.GAUNTLET_DATA, file, targetFile);
}
}
}
});
}
//////////////////////////////////////////////////////////////////////////
// gauntlet
//
private void _analyzeLayoutsDir(File root) {
System.out.println("analyzing layouts directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
// find *_preferred.xml files
String filename = file.getName();
if (filename.endsWith("_preferred.xml")) {
File targetFile = new File(NewConstants.USER_PREFS_DIR, file.getName().replace("_preferred", ""));
if (!file.equals(targetFile)) {
_cb.addOp(OpType.PREFERENCE_FILE, file, targetFile);
}
}
}
});
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// default card pics // default card pics
// //
private static String _oldCleanString(final String in) { private static String _oldCleanString(String in) {
final StringBuffer out = new StringBuffer(); final StringBuffer out = new StringBuffer();
char c; char c;
for (int i = 0; i < in.length(); i++) { for (int i = 0; i < in.length(); i++) {
@@ -170,34 +232,27 @@ public class MigrationSourceAnalyzer {
} }
System.out.println("analyzing default card pics directory: " + root); System.out.println("analyzing default card pics directory: " + root);
for (File file : root.listFiles()) { _analyzeListedDir(root, NewConstants.CACHE_CARD_PICS_DIR, new _ListedAnalyzer() {
if (_cb.checkCancel()) { return; } @Override public String map(String filename) {
if (_defaultPicOldNameToCurrentName.containsKey(filename)) {
if (file.isFile()) { return _defaultPicOldNameToCurrentName.get(filename);
++_numFilesAnalyzed;
String fileName = file.getName();
if (_defaultPicOldNameToCurrentName.containsKey(fileName)) {
fileName = _defaultPicOldNameToCurrentName.get(fileName);
} else if (!_defaultPicNames.contains(fileName)) {
System.out.println("skipping umappable default pic file: " + file);
_unmappableFiles.add(file);
continue;
}
File targetFile = new File(NewConstants.CACHE_CARD_PICS_DIR, fileName);
if (!file.equals(targetFile)) {
_cb.addOp(OpType.DEFAULT_CARD_PIC, file, targetFile);
}
} else if (file.isDirectory()) {
if ("icons".equals(file.getName())) {
_analyzeIconsPicsDir(file);
} else if ("tokens".equals(file.getName())) {
_analyzeTokenPicsDir(file);
} else {
_analyzeCardPicsSetDir(file);
} }
return _defaultPicNames.contains(filename) ? filename : null;
} }
}
@Override public OpType getOpType(String filename) { return OpType.DEFAULT_CARD_PIC; }
@Override boolean onDir(File dir) {
if ("icons".equals(dir.getName())) {
_analyzeIconsPicsDir(dir);
} else if ("tokens".equals(dir.getName())) {
_analyzeTokenPicsDir(dir);
} else {
_analyzeCardPicsSetDir(dir);
}
return true;
}
});
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -237,28 +292,16 @@ public class MigrationSourceAnalyzer {
_numFilesAnalyzed += _countFiles(root); _numFilesAnalyzed += _countFiles(root);
return; return;
} }
editionCode = edition.getCode2();
Set<String> validFilenames = _cardFileNamesBySet.get(editionCode); final String editionCode2 = edition.getCode2();
for (File file : root.listFiles()) { final Set<String> validFilenames = _cardFileNamesBySet.get(editionCode2);
if ( _cb.checkCancel()) { return; } _analyzeListedDir(root, NewConstants.CACHE_CARD_PICS_DIR, new _ListedAnalyzer() {
@Override public String map(String filename) {
if (file.isFile()) { filename = editionCode2 + "/" + filename;
++_numFilesAnalyzed; return validFilenames.contains(filename) ? filename : null;
if (validFilenames.contains(editionCode + "/" + file.getName())) {
File targetFile = new File(NewConstants.CACHE_CARD_PICS_DIR, editionCode + "/" + file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(OpType.SET_CARD_PIC, file, targetFile);
}
} else {
System.out.println("skipping umappable set pic file: " + file);
_unmappableFiles.add(file);
}
} else if (file.isDirectory()) {
System.out.println("skipping umappable subdirectory: " + file);
_numFilesAnalyzed += _countFiles(file);
} }
} @Override public OpType getOpType(String filename) { return OpType.SET_CARD_PIC; }
});
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@@ -278,26 +321,10 @@ public class MigrationSourceAnalyzer {
} }
System.out.println("analyzing icon pics directory: " + root); System.out.println("analyzing icon pics directory: " + root);
for (File file : root.listFiles()) { _analyzeListedDir(root, NewConstants.CACHE_ICON_PICS_DIR, new _ListedAnalyzer() {
if (_cb.checkCancel()) { return; } @Override public String map(String filename) { return _iconFileNames.contains(filename) ? filename : null; }
@Override public OpType getOpType(String filename) { return OpType.QUEST_PIC; }
if (file.isFile()) { });
++_numFilesAnalyzed;
if (!_iconFileNames.contains(file.getName())) {
System.out.println("skipping umappable icon pic file: " + file);
_unmappableFiles.add(file);
continue;
}
File targetFile = new File(NewConstants.CACHE_ICON_PICS_DIR, file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(OpType.QUEST_DATA, file, targetFile);
}
} else if (file.isDirectory()) {
System.out.println("skipping umappable subdirectory: " + file);
_numFilesAnalyzed += _countFiles(file);
}
}
} }
Set<String> _tokenFileNames; Set<String> _tokenFileNames;
@@ -315,33 +342,136 @@ public class MigrationSourceAnalyzer {
} }
System.out.println("analyzing token pics directory: " + root); System.out.println("analyzing token pics directory: " + root);
for (File file : root.listFiles()) { _analyzeListedDir(root, NewConstants.CACHE_TOKEN_PICS_DIR, new _ListedAnalyzer() {
if (_cb.checkCancel()) { return; } @Override public String map(String filename) {
return (_questTokenFileNames.contains(filename) || _tokenFileNames.contains(filename)) ? filename : null;
if (file.isFile()) {
++_numFilesAnalyzed;
boolean isQuestToken = _questTokenFileNames.contains(file.getName());
if (!isQuestToken && !_tokenFileNames.contains(file.getName())) {
System.out.println("skipping umappable token pic file: " + file);
_unmappableFiles.add(file);
continue;
}
File targetFile = new File(NewConstants.CACHE_TOKEN_PICS_DIR, file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(isQuestToken ? OpType.QUEST_PIC : OpType.TOKEN_PIC, file, targetFile);
}
} else if (file.isDirectory()) {
System.out.println("skipping umappable subdirectory: " + file);
_numFilesAnalyzed += _countFiles(file);
} }
} @Override public OpType getOpType(String filename) {
return _questTokenFileNames.contains(filename) ? OpType.QUEST_PIC : OpType.TOKEN_PIC;
}
});
}
private void _analyzeProductPicsDir(File root) {
System.out.println("analyzing product pics directory: " + root);
// we don't care about files in the root dir -- the new files are .png, not the current .jpg ones
_analyzeDir(root, new _Analyzer() {
@Override boolean onDir(File dir) {
if ("booster".equals(dir.getName())) {
} else if ("fatpacks".equals(dir.getName())) {
} else if ("precons".equals(dir.getName())) {
} else if ("tournamentpacks".equals(dir.getName())) {
} else {
return false;
}
return true;
}
});
}
//////////////////////////////////////////////////////////////////////////
// preferences
//
private void _analyzePreferencesDir(File root) {
System.out.println("analyzing preferences directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
String filename = file.getName();
if ("editor.preferences".equals(filename) || "forge.preferences".equals(filename)) {
File targetFile = new File(NewConstants.USER_PREFS_DIR, file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(OpType.PREFERENCE_FILE, file, targetFile);
}
}
}
});
}
//////////////////////////////////////////////////////////////////////////
// quest data
//
private void _analyzeQuestDir(File root) {
System.out.println("analyzing quest directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override boolean onDir(File dir) {
if ("data".equals(dir.getName())) {
_analyzeQuestDataDir(dir);
return true;
}
return false;
}
});
}
private void _analyzeQuestDataDir(File root) {
System.out.println("analyzing quest data directory: " + root);
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
if (file.getName().endsWith(".dat")) {
File targetFile = new File(NewConstants.QUEST_SAVE_DIR, file.getName());
if (!file.equals(targetFile)) {
_cb.addOp(OpType.QUEST_DATA, file, targetFile);
}
}
}
});
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// utility functions // utility functions
// //
private class _Analyzer {
void onFile(File file) { }
// returns whether the directory has been handled
boolean onDir(File dir) { return false; }
}
private void _analyzeDir(File root, _Analyzer analyzer) {
for (File file : root.listFiles()) {
if (_cb.checkCancel()) { return; }
if (file.isFile()) {
++_numFilesAnalyzed;
analyzer.onFile(file);
} else if (file.isDirectory()) {
if (!analyzer.onDir(file)) {
_numFilesAnalyzed += _countFiles(file);
}
}
}
}
private abstract class _ListedAnalyzer {
abstract String map(String filename);
abstract OpType getOpType(String filename);
// returns whether the directory has been handled
boolean onDir(File dir) { return false; }
}
private void _analyzeListedDir(File root, final String targetDir, final _ListedAnalyzer listedAnalyzer) {
_analyzeDir(root, new _Analyzer() {
@Override void onFile(File file) {
String filename = listedAnalyzer.map(file.getName());
if (null == filename) {
System.out.println("skipping umappable pic file: " + file);
_unmappableFiles.add(file);
} else {
File targetFile = new File(targetDir, filename);
if (!file.equals(targetFile)) {
_cb.addOp(listedAnalyzer.getOpType(filename), file, targetFile);
}
}
}
@Override boolean onDir(File dir) { return listedAnalyzer.onDir(dir); }
});
}
private int _countFiles(File root) { private int _countFiles(File root) {
int count = 0; int count = 0;
for (File file : root.listFiles()) { for (File file : root.listFiles()) {

View File

@@ -58,8 +58,8 @@ public final class NewConstants {
} }
// data that is only in the profile dirs // data that is only in the profile dirs
private static final String _USER_QUEST_DIR = USER_DIR + "quest/"; public static final String USER_QUEST_DIR = USER_DIR + "quest/";
private static final String _USER_PREFS_DIR = USER_DIR + "preferences/"; public static final String USER_PREFS_DIR = USER_DIR + "preferences/";
public static final String LOG_FILE = USER_DIR + "forge.log"; public static final String LOG_FILE = USER_DIR + "forge.log";
public static final String DECK_BASE_DIR = USER_DIR + "decks/"; public static final String DECK_BASE_DIR = USER_DIR + "decks/";
public static final String DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/"; public static final String DECK_CONSTRUCTED_DIR = DECK_BASE_DIR + "constructed/";
@@ -67,17 +67,17 @@ public final class NewConstants {
public static final String DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/"; public static final String DECK_SEALED_DIR = DECK_BASE_DIR + "sealed/";
public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/"; public static final String DECK_SCHEME_DIR = DECK_BASE_DIR + "scheme/";
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/"; public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";
public static final String QUEST_SAVE_DIR = _USER_QUEST_DIR + "saves/"; public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/";
public static final String MAIN_PREFS_FILE = _USER_PREFS_DIR + "forge.preferences"; public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
public static final String QUEST_PREFS_FILE = _USER_PREFS_DIR + "quest.preferences"; public static final String QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences";
// data that has defaults in the program dir but overrides/additions in the user dir // data that has defaults in the program dir but overrides/additions in the user dir
private static final String _DEFAULTS_DIR = _RES_ROOT + "defaults/"; private static final String _DEFAULTS_DIR = _RES_ROOT + "defaults/";
public static final FileLocation EDITOR_PREFERENCES_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "editor.preferences"); public static final FileLocation EDITOR_PREFERENCES_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.preferences");
public static final FileLocation HOME_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "home.xml"); public static final FileLocation HOME_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "home.xml");
public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "match.xml"); public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "match.xml");
public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, _USER_PREFS_DIR, "editor.xml"); public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.xml");
public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/"); public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/");
// data that is only in the cached dir // data that is only in the cached dir
@@ -96,7 +96,7 @@ public final class NewConstants {
USER_DIR, USER_DIR,
CACHE_DIR, CACHE_DIR,
CACHE_CARD_PICS_DIR, CACHE_CARD_PICS_DIR,
_USER_PREFS_DIR, USER_PREFS_DIR,
_DB_DIR, _DB_DIR,
DECK_CONSTRUCTED_DIR, DECK_CONSTRUCTED_DIR,
DECK_DRAFT_DIR, DECK_DRAFT_DIR,

View File

@@ -135,7 +135,7 @@ public enum FView {
// check quickly whether we have any data to migrate // check quickly whether we have any data to migrate
boolean hasData = false; boolean hasData = false;
for (String resDir : Lists.newArrayList("decks", "gauntlet", "pics", "pics_product", "preferences", "quest/data")) { for (String resDir : Lists.newArrayList("decks", "gauntlet", "layouts", "pics", "pics_product", "preferences", "quest/data")) {
File f = new File("res", resDir); File f = new File("res", resDir);
if (f.exists() && !profileDirs.contains(f)) { if (f.exists() && !profileDirs.contains(f)) {
System.out.println("profile data found in obsolete location: " + f.getAbsolutePath()); System.out.println("profile data found in obsolete location: " + f.getAbsolutePath());