package net.oni2.aeinstaller.backend.oni; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Scanner; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import java.util.regex.Pattern; import net.oni2.aeinstaller.AEInstaller2; import net.oni2.aeinstaller.backend.CaseInsensitiveFile; import net.oni2.aeinstaller.backend.Paths; import net.oni2.aeinstaller.backend.Settings; import net.oni2.aeinstaller.backend.Settings.Platform; import net.oni2.aeinstaller.backend.appexecution.AppExecutionResult; import net.oni2.aeinstaller.backend.packages.EBSLInstallType; import net.oni2.aeinstaller.backend.packages.Package; import net.oni2.aeinstaller.backend.packages.PackageManager; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.RegexFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; import org.javabuilders.swing.SwingJavaBuilder; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.StaxDriver; /** * @author Christian Illy */ public class Installer { private static FileFilter dirFileFilter = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }; /** * @return Is Edition Core initialized */ public static boolean isEditionInitialized() { return Paths.getVanillaOnisPath().exists(); } private static void createEmptyPath(File path) throws IOException { if (path.exists()) FileUtils.deleteDirectory(path); path.mkdirs(); } /** * @return list of currently installed mods */ public static Vector getInstalledMods() { File installCfg = new File(Paths.getEditionGDF(), "installed_mods.xml"); return PackageManager.getInstance().loadModSelection(installCfg); } /** * @return Currently installed tools */ @SuppressWarnings("unchecked") public static TreeSet getInstalledTools() { File installCfg = new File(Paths.getInstallerPath(), "installed_tools.xml"); TreeSet res = new TreeSet(); try { if (installCfg.exists()) { FileInputStream fis = new FileInputStream(installCfg); XStream xs = new XStream(new StaxDriver()); Object obj = xs.fromXML(fis); if (obj instanceof TreeSet) res = (TreeSet) obj; fis.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return res; } private static void writeInstalledTools(TreeSet tools) { File installCfg = new File(Paths.getInstallerPath(), "installed_tools.xml"); try { FileOutputStream fos = new FileOutputStream(installCfg); XStream xs = new XStream(new StaxDriver()); xs.toXML(tools, fos); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * @param tools * Tools to (un)install * @param uninstall * Uninstall tools or install? */ public static void installTools(TreeSet tools, boolean uninstall) { TreeSet installed = getInstalledTools(); for (Package m : tools) { if (!uninstall || installed.contains(m.getPackageNumber())) { File plain = CaseInsensitiveFile.getCaseInsensitiveFile( m.getLocalPath(), "plain"); if (plain.exists()) { if (m.hasSeparatePlatformDirs()) { File plainCommon = CaseInsensitiveFile .getCaseInsensitiveFile(plain, "common"); File plainMac = CaseInsensitiveFile .getCaseInsensitiveFile(plain, "mac_only"); File plainWin = CaseInsensitiveFile .getCaseInsensitiveFile(plain, "win_only"); if (plainCommon.exists()) copyRemoveToolsFiles(plainCommon, Paths.getEditionBasePath(), uninstall); if (Settings.getPlatform() == Platform.MACOS && plainMac.exists()) copyRemoveToolsFiles(plainMac, Paths.getEditionBasePath(), uninstall); else if (plainWin.exists()) copyRemoveToolsFiles(plainWin, Paths.getEditionBasePath(), uninstall); } else { copyRemoveToolsFiles(plain, Paths.getEditionBasePath(), uninstall); } } } if (uninstall) installed.remove(m.getPackageNumber()); else installed.add(m.getPackageNumber()); } writeInstalledTools(installed); } private static void copyRemoveToolsFiles(File srcFolder, File targetFolder, boolean remove) { for (File f : srcFolder.listFiles()) { try { if (f.isDirectory()) copyRemoveToolsFiles(f, CaseInsensitiveFile.getCaseInsensitiveFile( targetFolder, f.getName()), remove); else { File targetFile = CaseInsensitiveFile .getCaseInsensitiveFile(targetFolder, f.getName()); if (remove) { if (targetFile.exists()) targetFile.delete(); } else { if (!targetFile.getName().equals(f.getName())) targetFile.delete(); FileUtils.copyFileToDirectory(f, targetFolder); } } } catch (IOException e) { e.printStackTrace(); } } if (remove) if (targetFolder.list().length == 0) targetFolder.delete(); } /** * Install the given set of mods * * @param mods * Mods to install * @param listener * Listener for install progress updates */ public static void install(TreeSet mods, InstallProgressListener listener) { File logFile = new File(Paths.getInstallerPath(), "Installation.log"); PrintWriter log = null; try { log = new PrintWriter(logFile); } catch (FileNotFoundException e) { e.printStackTrace(); } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date start = new Date(); log.println("Installation of mods started at " + sdf.format(start)); log.println(); log.println("AEI2 version: " + SwingJavaBuilder.getConfig().getResource("appversion")); log.println("Installed tools:"); for (Package t : PackageManager.getInstance().getInstalledTools()) { log.println(String.format(" - %s (%s)", t.getName(), t.getVersion())); } log.println("Installing mods:"); for (Package m : mods) { log.println(String.format(" - %s (%s)", m.getName(), m.getVersion())); } log.println(); Paths.getEditionGDF().mkdirs(); for (File f : Paths.getEditionGDF().listFiles(new FilenameFilter() { public boolean accept(File arg0, String arg1) { String s = arg1.toLowerCase(); return s.endsWith(".dat") || s.endsWith(".raw") || s.endsWith(".sep") || (s.equals("intro.bik") && !Settings.getInstance() .get("copyintro", false)) || (s.equals("outro.bik") && !Settings.getInstance() .get("copyoutro", false)); } })) { f.delete(); } File IGMD = new File(Paths.getEditionGDF(), "IGMD"); if (IGMD.exists()) { for (File f : IGMD.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } })) { File ignore = CaseInsensitiveFile.getCaseInsensitiveFile(f, "ignore.txt"); if (!ignore.exists()) { try { FileUtils.deleteDirectory(f); } catch (IOException e) { e.printStackTrace(); } } } } File installCfg = new File(Paths.getEditionGDF(), "installed_mods.xml"); PackageManager.getInstance().saveModSelection(installCfg, mods); TreeSet unlockLevels = new TreeSet(); Vector foldersOni = new Vector(); foldersOni.add(Paths.getVanillaOnisPath()); Vector foldersPatches = new Vector(); for (Package m : mods) { for (int lev : m.getUnlockLevels()) unlockLevels.add(lev); File oni = CaseInsensitiveFile.getCaseInsensitiveFile( m.getLocalPath(), "oni"); if (oni.exists()) { if (m.hasSeparatePlatformDirs()) { File oniCommon = CaseInsensitiveFile .getCaseInsensitiveFile(oni, "common"); File oniMac = CaseInsensitiveFile.getCaseInsensitiveFile( oni, "mac_only"); File oniWin = CaseInsensitiveFile.getCaseInsensitiveFile( oni, "win_only"); if (oniCommon.exists()) foldersOni.add(oniCommon); if (Settings.getPlatform() == Platform.MACOS && oniMac.exists()) foldersOni.add(oniMac); else if (oniWin.exists()) foldersOni.add(oniWin); } else { foldersOni.add(oni); } } File patches = CaseInsensitiveFile.getCaseInsensitiveFile( m.getLocalPath(), "patches"); if (patches.exists()) { if (m.hasSeparatePlatformDirs()) { File patchesCommon = CaseInsensitiveFile .getCaseInsensitiveFile(patches, "common"); File patchesMac = CaseInsensitiveFile .getCaseInsensitiveFile(patches, "mac_only"); File patchesWin = CaseInsensitiveFile .getCaseInsensitiveFile(patches, "win_only"); if (patchesCommon.exists()) foldersPatches.add(patchesCommon); if (Settings.getPlatform() == Platform.MACOS && patchesMac.exists()) foldersPatches.add(patchesMac); else if (patchesWin.exists()) foldersPatches.add(patchesWin); } else { foldersPatches.add(patches); } } } TreeMap> levels = new TreeMap>(); for (File path : foldersOni) { for (File levelF : path.listFiles()) { String fn = levelF.getName().toLowerCase(); String levelN = null; if (levelF.isDirectory()) { levelN = fn; } else if (fn.endsWith(".dat")) { levelN = fn.substring(0, fn.lastIndexOf('.')).toLowerCase(); } if (levelN != null) { if (!levels.containsKey(levelN)) levels.put(levelN, new Vector()); levels.get(levelN).add(levelF); } } } applyPatches(levels, foldersPatches, listener, log); combineBinaryFiles(levels, listener, log); combineBSLFolders(mods, listener, log); copyVideos(log); if (unlockLevels.size() > 0) { unlockLevels(unlockLevels, log); } log.println(); Date end = new Date(); log.println("Initialization ended at " + sdf.format(end)); log.println("Process took " + ((end.getTime() - start.getTime()) / 1000) + " seconds"); log.close(); } private static void combineBSLFolders(TreeSet mods, InstallProgressListener listener, PrintWriter log) { listener.installProgressUpdate(95, 100, "Installing BSL files"); log.println("Installing BSL files"); HashMap> modsToInclude = new HashMap>(); modsToInclude.put(EBSLInstallType.NORMAL, new Vector()); modsToInclude.put(EBSLInstallType.ADDON, new Vector()); for (Package m : mods.descendingSet()) { File bsl = CaseInsensitiveFile.getCaseInsensitiveFile( m.getLocalPath(), "bsl"); if (bsl.exists()) { if (m.hasSeparatePlatformDirs()) { File bslCommon = CaseInsensitiveFile .getCaseInsensitiveFile(bsl, "common"); File bslMac = CaseInsensitiveFile.getCaseInsensitiveFile( bsl, "mac_only"); File bslWin = CaseInsensitiveFile.getCaseInsensitiveFile( bsl, "win_only"); if ((Settings.getPlatform() == Platform.MACOS && bslMac .exists()) || ((Settings.getPlatform() == Platform.WIN || Settings .getPlatform() == Platform.LINUX) && bslWin .exists()) || bslCommon.exists()) { modsToInclude.get(m.getBSLInstallType()).add(m); } } else { modsToInclude.get(m.getBSLInstallType()).add(m); } } } for (Package m : modsToInclude.get(EBSLInstallType.NORMAL)) { copyBSL(m, false); } Vector addons = modsToInclude.get(EBSLInstallType.ADDON); for (int i = addons.size() - 1; i >= 0; i--) { copyBSL(addons.get(i), true); } } private static void copyBSL(Package sourceMod, boolean addon) { File targetBaseFolder = new File(Paths.getEditionGDF(), "IGMD"); if (!targetBaseFolder.exists()) targetBaseFolder.mkdir(); Vector sources = new Vector(); File bsl = CaseInsensitiveFile.getCaseInsensitiveFile( sourceMod.getLocalPath(), "bsl"); if (sourceMod.hasSeparatePlatformDirs()) { File bslCommon = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, "common"); File bslMac = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, "mac_only"); File bslWin = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, "win_only"); if (Settings.getPlatform() == Platform.MACOS && bslMac.exists()) { for (File f : bslMac.listFiles(dirFileFilter)) { File targetBSL = new File(targetBaseFolder, f.getName()); if (addon || !targetBSL.exists()) sources.add(f); } } if ((Settings.getPlatform() == Platform.WIN || Settings .getPlatform() == Platform.LINUX) && bslWin.exists()) { for (File f : bslWin.listFiles(dirFileFilter)) { File targetBSL = new File(targetBaseFolder, f.getName()); if (addon || !targetBSL.exists()) sources.add(f); } } if (bslCommon.exists()) { for (File f : bslCommon.listFiles(dirFileFilter)) { File targetBSL = new File(targetBaseFolder, f.getName()); if (addon || !targetBSL.exists()) sources.add(f); } } } else { for (File f : bsl.listFiles(dirFileFilter)) { File targetBSL = new File(targetBaseFolder, f.getName()); if (addon || !targetBSL.exists()) sources.add(f); } } System.out.println("For mod: " + sourceMod.getName() + " install BSL folders: " + sources.toString()); for (File f : sources) { File targetPath = new File(targetBaseFolder, f.getName()); if (!targetPath.exists()) targetPath.mkdir(); if (!(CaseInsensitiveFile.getCaseInsensitiveFile(targetPath, "ignore.txt").exists())) { for (File fbsl : f.listFiles()) { if (fbsl.getName().toLowerCase().endsWith(".bsl")) { File targetFile = new File(targetPath, fbsl.getName()); if (addon || !targetFile.exists()) { try { FileUtils.copyFile(fbsl, targetFile); } catch (IOException e) { e.printStackTrace(); } } } } } } } private static void applyPatches( TreeMap> oniLevelFolders, List patchFolders, InstallProgressListener listener, PrintWriter log) { log.println(); log.println("Applying XML patches"); listener.installProgressUpdate(0, 1, "Applying XML patches"); long startMS = new Date().getTime(); String tmpFolderName = "installrun_temp-" + new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss") .format(new Date()); File tmpFolder = new File(Paths.getTempPath(), tmpFolderName); tmpFolder.mkdir(); HashMap> patches = new HashMap>(); for (File patchFolder : patchFolders) { for (File levelFolder : patchFolder.listFiles(dirFileFilter)) { String lvlName = levelFolder.getName().toLowerCase(); for (File f : FileUtils.listFiles(levelFolder, new String[] { "oni-patch" }, true)) { if (!patches.containsKey(lvlName)) patches.put(lvlName, new Vector()); patches.get(lvlName).add(f); } } } for (String level : patches.keySet()) { File levelFolder = new File(tmpFolder, level); levelFolder.mkdir(); log.println("\t\tPatches for " + level); Vector exportPatterns = new Vector(); // Get files to be patched from vanilla.dat for (File patch : patches.get(level)) { String patternWildcard = patch.getName(); patternWildcard = patternWildcard.substring(0, patternWildcard.indexOf(".oni-patch")); patternWildcard = patternWildcard.replace('-', '*'); exportPatterns.add(patternWildcard); } for (File srcFolder : oniLevelFolders.get(level)) { if (srcFolder.isFile()) { if (srcFolder.getPath().toLowerCase().contains("vanilla")) { // Extract from .dat AppExecutionResult res = OniSplit.export(levelFolder, srcFolder, exportPatterns); logAppOutput(res, log); } } } // Get files to be patched from packages for (File patch : patches.get(level)) { String patternWildcard = patch.getName(); patternWildcard = patternWildcard.substring(0, patternWildcard.indexOf(".oni-patch")); patternWildcard = patternWildcard.replace('-', '*'); patternWildcard = patternWildcard + ".oni"; Vector patterns = new Vector(); patterns.add(patternWildcard); final Pattern patternRegex = Pattern.compile( patternWildcard.replaceAll("\\*", ".\\*"), Pattern.CASE_INSENSITIVE); for (File srcFolder : oniLevelFolders.get(level)) { if (srcFolder.isFile()) { if (!srcFolder.getPath().toLowerCase() .contains("vanilla")) { // Extract from .dat AppExecutionResult res = OniSplit.export( levelFolder, srcFolder, patterns); logAppOutput(res, log); } } else { // Copy from folder with overwrite for (File f : FileUtils.listFiles(srcFolder, new RegexFileFilter(patternRegex), TrueFileFilter.TRUE)) { try { FileUtils.copyFileToDirectory(f, levelFolder); } catch (IOException e) { e.printStackTrace(); } } } } } // Extract files to XML File levelFolderXML = new File(levelFolder, "xml"); Vector files = new Vector(); files.add(new File(levelFolder, "*.oni")); AppExecutionResult res = OniSplit.convertOniToXML(levelFolderXML, files); logAppOutput(res, log); // Apply patches in levelFolderXML for (File patch : patches.get(level)) { String patternWildcard = patch.getName(); patternWildcard = patternWildcard.substring(0, patternWildcard.indexOf(".oni-patch")); patternWildcard = patternWildcard + ".xml"; patternWildcard = patternWildcard.replace('-', '*'); res = XMLTools.patch(patch, new File(levelFolderXML, patternWildcard)); logAppOutput(res, log); } // Create .oni files from XML files.clear(); files.add(new File(levelFolderXML, "*.xml")); res = OniSplit.convertXMLtoOni(levelFolder, files); logAppOutput(res, log); // Remove XML folder as import will only require .oni's // try { // FileUtils.deleteDirectory(levelFolderXML); // } catch (IOException e) { // e.printStackTrace(); // } oniLevelFolders.get(level).add(levelFolder); } log.println("Applying XML patches took " + (new Date().getTime() - startMS) + " ms"); } private static void combineBinaryFiles( TreeMap> oniLevelFolders, InstallProgressListener listener, PrintWriter log) { long startMS = new Date().getTime(); int totalSteps = 0; int stepsDone = 0; for (@SuppressWarnings("unused") String s : oniLevelFolders.keySet()) totalSteps++; totalSteps++; log.println(); log.println("Importing levels"); for (String l : oniLevelFolders.keySet()) { log.println("\tLevel " + l); listener.installProgressUpdate(stepsDone, totalSteps, "Installing level " + l); AppExecutionResult res = OniSplit.packLevel(oniLevelFolders.get(l), new File(Paths.getEditionGDF(), sanitizeLevelName(l) + ".dat")); logAppOutput(res, log); stepsDone++; } log.println("Importing levels took " + (new Date().getTime() - startMS) + " ms"); log.println(); } private static void copyVideos(PrintWriter log) { if (Settings.getInstance().get("copyintro", false)) { File src = new File(Paths.getVanillaGDF(), "intro.bik"); log.println("Copying intro"); if (src.exists()) { try { FileUtils.copyFileToDirectory(src, Paths.getEditionGDF()); } catch (IOException e) { e.printStackTrace(); } } } else { log.println("NOT copying intro"); } if (Settings.getInstance().get("copyoutro", true)) { File src = new File(Paths.getVanillaGDF(), "outro.bik"); log.println("Copying outro"); if (src.exists()) { try { FileUtils.copyFileToDirectory(src, Paths.getEditionGDF()); } catch (IOException e) { e.printStackTrace(); } } } else { log.println("NOT copying outro"); } } private static void unlockLevels(TreeSet unlockLevels, PrintWriter log) { File dat = new File(Paths.getEditionBasePath(), "persist.dat"); log.println("Unlocking levels: " + unlockLevels.toString()); if (!dat.exists()) { InputStream is = AEInstaller2.class .getResourceAsStream("/net/oni2/aeinstaller/resources/persist.dat"); try { FileUtils.copyInputStreamToFile(is, dat); } catch (IOException e) { e.printStackTrace(); } } PersistDat save = new PersistDat(dat); HashSet currentlyUnlocked = save.getUnlockedLevels(); currentlyUnlocked.addAll(unlockLevels); save.setUnlockedLevels(currentlyUnlocked); save.close(); } /** * Initializes the Edition core * * @param listener * Listener for status updates */ public static void initializeEdition(InstallProgressListener listener) { File init = new File(Paths.getTempPath(), "init"); int totalSteps = 0; int stepsDone = 0; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (@SuppressWarnings("unused") File f : Paths.getVanillaGDF().listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".dat"); } })) { totalSteps++; } totalSteps = totalSteps * 2 + 2; try { File logFile = new File(Paths.getInstallerPath(), "Initialization.log"); PrintWriter log = new PrintWriter(logFile); Date start = new Date(); log.println("Initialization of Edition core started at " + sdf.format(start)); log.println("Cleaning directories"); listener.installProgressUpdate(stepsDone, totalSteps, "Cleaning up directories"); createEmptyPath(Paths.getVanillaOnisPath()); createEmptyPath(init); File level0Folder = new File(init, "level0_Final"); createEmptyPath(level0Folder); stepsDone++; log.println("Exporting levels and moving files to level0"); for (File f : Paths.getVanillaGDF().listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".dat"); } })) { String levelName = f.getName().substring(0, f.getName().indexOf('.')); Scanner fi = new Scanner(levelName); int levelNumber = Integer.parseInt(fi.findInLine("[0-9]+")); log.println("\t" + levelName + ":"); log.println("\t\tExporting"); listener.installProgressUpdate(stepsDone, totalSteps, "Exporting vanilla level " + levelNumber); // Edition/GameDataFolder/level*_Final/ File tempLevelFolder = new File(init, levelName); // Export Vanilla-Level-Dat -> Temp/Level AppExecutionResult res = OniSplit.export(tempLevelFolder, f); logAppOutput(res, log); log.println("\t\tMoving files"); handleFileGlobalisation(tempLevelFolder, level0Folder, levelNumber); stepsDone++; log.println(); } log.println("Reimporting levels"); for (File f : init.listFiles()) { String levelName = f.getName(); log.println("\t" + levelName); listener.installProgressUpdate(stepsDone, totalSteps, "Creating globalized " + levelName); Vector folders = new Vector(); folders.add(f); AppExecutionResult res = OniSplit .importLevel(folders, new File(Paths.getVanillaOnisPath(), levelName + ".dat")); logAppOutput(res, log); log.println(); stepsDone++; } listener.installProgressUpdate(stepsDone, totalSteps, "Copying basic files"); // Copy Oni-configs File persistVanilla = new File(Paths.getOniBasePath(), "persist.dat"); File persistEdition = new File(Paths.getEditionBasePath(), "persist.dat"); File keyConfVanilla = new File(Paths.getOniBasePath(), "key_config.txt"); File keyConfEdition = new File(Paths.getEditionBasePath(), "key_config.txt"); if (persistVanilla.exists() && !persistEdition.exists()) FileUtils.copyFile(persistVanilla, persistEdition); if (keyConfVanilla.exists() && !keyConfEdition.exists()) FileUtils.copyFile(keyConfVanilla, keyConfEdition); FileUtils.deleteDirectory(init); Date end = new Date(); log.println("Initialization ended at " + sdf.format(end)); log.println("Process took " + ((end.getTime() - start.getTime()) / 1000) + " seconds"); log.close(); } catch (IOException e) { e.printStackTrace(); } } private static void moveFileToTargetOrDelete(File source, File target) { if (source.equals(target)) return; if (!target.exists()) { if (!source.renameTo(target)) { System.err.println("File " + source.getPath() + " not moved!"); } } else if (!source.delete()) { System.err.println("File " + source.getPath() + " not deleted!"); } } private static void handleFileGlobalisation(File tempFolder, File level0Folder, int levelNumber) { // Move AKEV and related files to subfolder so they're not globalized: if (levelNumber != 0) { File akevFolder = new File(tempFolder, "AKEV"); akevFolder.mkdir(); OniSplit.move(akevFolder, tempFolder.getPath() + "/AKEV*.oni", "overwrite"); } for (File f : tempFolder.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile(); } })) { // Move matching files to subfolder NoGlobal: if (f.getName().startsWith("TXMPfail") || f.getName().startsWith("TXMPlevel") || (f.getName().startsWith("TXMP") && f.getName().contains( "intro")) || f.getName().startsWith("TXMB") || f.getName().equals("M3GMpowerup_lsi.oni") || f.getName().equals("TXMPlsi_icon.oni") || (f.getName().startsWith("TXMB") && f.getName().contains( "splash_screen.oni"))) { File noGlobal = new File(tempFolder, "NoGlobal"); noGlobal.mkdir(); File noGlobalFile = new File(noGlobal, f.getName()); moveFileToTargetOrDelete(f, noGlobalFile); } // Move matching files to level0_Animations/level0_TRAC else if (f.getName().startsWith("TRAC")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to level0_Animations/level0_TRAM else if (f.getName().startsWith("TRAM")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to level0_Textures else if (f.getName().startsWith("ONSK") || f.getName().startsWith("TXMP")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to *VANILLA*/level0_Characters else if (f.getName().startsWith("ONCC") || f.getName().startsWith("TRBS") || f.getName().startsWith("ONCV") || f.getName().startsWith("ONVL") || f.getName().startsWith("TRMA") || f.getName().startsWith("TRSC") || f.getName().startsWith("TRAS")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to level0_Sounds else if (f.getName().startsWith("OSBD") || f.getName().startsWith("SNDD")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to level0_Particles else if (f.getName().startsWith("BINA3") || f.getName().startsWith("M3GMdebris") || f.getName().equals("M3GMtoxic_bubble.oni") || f.getName().startsWith("M3GMelec") || f.getName().startsWith("M3GMrat") || f.getName().startsWith("M3GMjet") || f.getName().startsWith("M3GMbomb_") || f.getName().equals("M3GMbarab_swave.oni") || f.getName().equals("M3GMbloodyfoot.oni")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } // Move matching files to Archive (aka delete them) else if (f.getName().startsWith("AGDB") || f.getName().startsWith("TRCM")) { f.delete(); } // Move matching files to /level0_Final/ else if (f.getName().startsWith("ONWC")) { File level0File = new File(level0Folder, f.getName()); moveFileToTargetOrDelete(f, level0File); } } } private static String sanitizeLevelName(String ln) { int ind = ln.indexOf("_"); String res = ln.substring(0, ind + 1); res += ln.substring(ind + 1, ind + 2).toUpperCase(); res += ln.substring(ind + 2); return res; } /** * Verify that the Edition is within a subfolder to vanilla Oni * (..../Oni/Edition/AEInstaller) * * @return true if GDF can be found in the parent's parent-path */ public static boolean verifyRunningDirectory() { return Paths.getVanillaGDF().exists() && Paths.getVanillaGDF().isDirectory(); } private static void logAppOutput(AppExecutionResult result, PrintWriter log) { if (result != null) { log.println("\t\t\tCalled:"); for (String s : result.cmdLine) log.println("\t\t\t\t" + s); log.println("\t\t\tReturned: " + result.errorCode); for (String s : result.output) log.println("\t\t\t\t" + s); log.println("\t\t\tDuration: " + result.time + " ms"); log.println(); } } }