| 1 | package net.oni2.aeinstaller.backend.oni.management; | 
 
 
 
 
 | 2 |  | 
 
 
 
 
 | 3 | import java.io.File; | 
 
 
 
 
 | 4 | import java.io.FileFilter; | 
 
 
 
 
 | 5 | import java.io.FileNotFoundException; | 
 
 
 
 
 | 6 | import java.io.FileOutputStream; | 
 
 
 
 
 | 7 | import java.io.FilenameFilter; | 
 
 
 
 
 | 8 | import java.io.IOException; | 
 
 
 
 
 | 9 | import java.io.InputStream; | 
 
 
 
 
 | 10 | import java.io.OutputStreamWriter; | 
 
 
 
 
 | 11 | import java.io.PrintWriter; | 
 
 
 
 
 | 12 | import java.io.UnsupportedEncodingException; | 
 
 
 
 
 | 13 | import java.text.SimpleDateFormat; | 
 
 
 
 
 | 14 | import java.util.Date; | 
 
 
 
 
 | 15 | import java.util.HashSet; | 
 
 
 
 
 | 16 | import java.util.List; | 
 
 
 
 
 | 17 | import java.util.TreeMap; | 
 
 
 
 
 | 18 | import java.util.TreeSet; | 
 
 
 
 
 | 19 | import java.util.Vector; | 
 
 
 
 
 | 20 | import java.util.regex.Pattern; | 
 
 
 
 
 | 21 |  | 
 
 
 
 
 | 22 | import net.oni2.SettingsManager; | 
 
 
 
 
 | 23 | import net.oni2.aeinstaller.AEInstaller2; | 
 
 
 
 
 | 24 | import net.oni2.aeinstaller.backend.CaseInsensitiveFile; | 
 
 
 
 
 | 25 | import net.oni2.aeinstaller.backend.Paths; | 
 
 
 
 
 | 26 | import net.oni2.aeinstaller.backend.RuntimeOptions; | 
 
 
 
 
 | 27 | import net.oni2.aeinstaller.backend.oni.OniSplit; | 
 
 
 
 
 | 28 | import net.oni2.aeinstaller.backend.oni.PersistDat; | 
 
 
 
 
 | 29 | import net.oni2.aeinstaller.backend.oni.XMLTools; | 
 
 
 
 
 | 30 | import net.oni2.aeinstaller.backend.oni.management.tools.ToolFileIterator; | 
 
 
 
 
 | 31 | import net.oni2.aeinstaller.backend.oni.management.tools.ToolFileIteratorEntry; | 
 
 
 
 
 | 32 | import net.oni2.aeinstaller.backend.oni.management.tools.ToolInstallationList; | 
 
 
 
 
 | 33 | import net.oni2.aeinstaller.backend.packages.EBSLInstallType; | 
 
 
 
 
 | 34 | import net.oni2.aeinstaller.backend.packages.Package; | 
 
 
 
 
 | 35 | import net.oni2.aeinstaller.backend.packages.PackageManager; | 
 
 
 
 
 | 36 | import net.oni2.platformtools.PlatformInformation; | 
 
 
 
 
 | 37 | import net.oni2.platformtools.PlatformInformation.Platform; | 
 
 
 
 
 | 38 | import net.oni2.platformtools.applicationinvoker.ApplicationInvocationResult; | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | import org.apache.commons.io.FileUtils; | 
 
 
 
 
 | 41 | import org.apache.commons.io.filefilter.RegexFileFilter; | 
 
 
 
 
 | 42 | import org.apache.commons.io.filefilter.TrueFileFilter; | 
 
 
 
 
 | 43 | import org.javabuilders.swing.SwingJavaBuilder; | 
 
 
 
 
 | 44 |  | 
 
 
 
 
 | 45 | import com.paour.NaturalOrderComparator; | 
 
 
 
 
 | 46 |  | 
 
 
 
 
 | 47 | /** | 
 
 
 
 
 | 48 | * @author Christian Illy | 
 
 
 
 
 | 49 | */ | 
 
 
 
 
 | 50 | public class Installer { | 
 
 
 
 
 | 51 | private static FileFilter dirFileFilter = new FileFilter() { | 
 
 
 
 
 | 52 | @Override | 
 
 
 
 
 | 53 | public boolean accept(File pathname) { | 
 
 
 
 
 | 54 | return pathname.isDirectory(); | 
 
 
 
 
 | 55 | } | 
 
 
 
 
 | 56 | }; | 
 
 
 
 
 | 57 |  | 
 
 
 
 
 | 58 | /** | 
 
 
 
 
 | 59 | * Verify that the Edition is within a subfolder to vanilla Oni | 
 
 
 
 
 | 60 | * (..../Oni/Edition/AEInstaller) | 
 
 
 
 
 | 61 | * | 
 
 
 
 
 | 62 | * @return true if GDF can be found in the parent's parent-path | 
 
 
 
 
 | 63 | */ | 
 
 
 
 
 | 64 | public static boolean verifyRunningDirectory() { | 
 
 
 
 
 | 65 | return Paths.getVanillaGDF().exists() | 
 
 
 
 
 | 66 | && Paths.getVanillaGDF().isDirectory(); | 
 
 
 
 
 | 67 | } | 
 
 
 
 
 | 68 |  | 
 
 
 
 
 | 69 | /** | 
 
 
 
 
 | 70 | * @return Is Edition Core initialized | 
 
 
 
 
 | 71 | */ | 
 
 
 
 
 | 72 | public static boolean isEditionInitialized() { | 
 
 
 
 
 | 73 | return Paths.getVanillaOnisPath().exists(); | 
 
 
 
 
 | 74 | } | 
 
 
 
 
 | 75 |  | 
 
 
 
 
 | 76 | /** | 
 
 
 
 
 | 77 | * Install the given set of mods | 
 
 
 
 
 | 78 | * | 
 
 
 
 
 | 79 | * @param mods | 
 
 
 
 
 | 80 | *            Mods to install | 
 
 
 
 
 | 81 | * @param listener | 
 
 
 
 
 | 82 | *            Listener for install progress updates | 
 
 
 
 
 | 83 | */ | 
 
 
 
 
 | 84 | public static void install(TreeSet<Package> mods, | 
 
 
 
 
 | 85 | InstallProgressListener listener) { | 
 
 
 
 
 | 86 | File logFile = new File(Paths.getInstallerPath(), "Installation.log"); | 
 
 
 
 
 | 87 | Logger log = null; | 
 
 
 
 
 | 88 | try { | 
 
 
 
 
 | 89 | log = new Logger(logFile); | 
 
 
 
 
 | 90 | } catch (FileNotFoundException e) { | 
 
 
 
 
 | 91 | e.printStackTrace(); | 
 
 
 
 
 | 92 | } | 
 
 
 
 
 | 93 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 
 
 
 
 
 | 94 | Date start = new Date(); | 
 
 
 
 
 | 95 | log.println("Installation of mods started at " + sdf.format(start)); | 
 
 
 
 
 | 96 |  | 
 
 
 
 
 | 97 | log.println(); | 
 
 
 
 
 | 98 | log.println("AEI2 version: " | 
 
 
 
 
 | 99 | + SwingJavaBuilder.getConfig().getResource("appversion")); | 
 
 
 
 
 | 100 |  | 
 
 
 
 
 | 101 | ToolInstallationList til = ToolInstallationList.getInstance(); | 
 
 
 
 
 | 102 | log.println("Installed tools:"); | 
 
 
 
 
 | 103 | for (Package t : PackageManager.getInstance().getInstalledTools()) { | 
 
 
 
 
 | 104 | log.println(String.format(" - %s (%s)", t.getName(), t.getVersion()) | 
 
 
 
 
 | 105 | + (til.isModified(t.getPackageNumber()) ? " (! LOCALLY MODIFIED !)" | 
 
 
 
 
 | 106 | : "")); | 
 
 
 
 
 | 107 | } | 
 
 
 
 
 | 108 | log.println("Core mods:"); | 
 
 
 
 
 | 109 | for (Package m : mods) { | 
 
 
 
 
 | 110 | if (m.isCorePackage()) { | 
 
 
 
 
 | 111 | log.println(String.format(" - %s (%s)", m.getName(), m.getVersion())); | 
 
 
 
 
 | 112 | } | 
 
 
 
 
 | 113 | } | 
 
 
 
 
 | 114 | log.println("Selected mods:"); | 
 
 
 
 
 | 115 | for (Package m : mods) { | 
 
 
 
 
 | 116 | if (!m.isCorePackage()) { | 
 
 
 
 
 | 117 | log.println(String.format(" - %s (%s)", m.getName(), m.getVersion())); | 
 
 
 
 
 | 118 | } | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 | log.println(); | 
 
 
 
 
 | 121 |  | 
 
 
 
 
 | 122 | HashSet<String> levelsAffectedBefore = null; | 
 
 
 
 
 | 123 | if (ModInstallationList.getInstance().isLoadedFromFile()) { | 
 
 
 
 
 | 124 | levelsAffectedBefore = ModInstallationList.getInstance() | 
 
 
 
 
 | 125 | .getAffectedLevels(); | 
 
 
 
 
 | 126 | } | 
 
 
 
 
 | 127 | HashSet<String> levelsAffectedNow = new HashSet<String>(); | 
 
 
 
 
 | 128 |  | 
 
 
 
 
 | 129 | File IGMD = new File(Paths.getEditionGDF(), "IGMD"); | 
 
 
 
 
 | 130 | if (IGMD.exists()) { | 
 
 
 
 
 | 131 | for (File f : IGMD.listFiles(new FileFilter() { | 
 
 
 
 
 | 132 | @Override | 
 
 
 
 
 | 133 | public boolean accept(File pathname) { | 
 
 
 
 
 | 134 | return pathname.isDirectory(); | 
 
 
 
 
 | 135 | } | 
 
 
 
 
 | 136 | })) { | 
 
 
 
 
 | 137 | File ignore = CaseInsensitiveFile.getCaseInsensitiveFile(f, | 
 
 
 
 
 | 138 | "ignore.txt"); | 
 
 
 
 
 | 139 | if (!ignore.exists()) { | 
 
 
 
 
 | 140 | try { | 
 
 
 
 
 | 141 | FileUtils.deleteDirectory(f); | 
 
 
 
 
 | 142 | } catch (IOException e) { | 
 
 
 
 
 | 143 | e.printStackTrace(); | 
 
 
 
 
 | 144 | } | 
 
 
 
 
 | 145 | } | 
 
 
 
 
 | 146 | } | 
 
 
 
 
 | 147 | } | 
 
 
 
 
 | 148 |  | 
 
 
 
 
 | 149 | TreeSet<Integer> unlockLevels = new TreeSet<Integer>(); | 
 
 
 
 
 | 150 |  | 
 
 
 
 
 | 151 | Vector<File> foldersOni = new Vector<File>(); | 
 
 
 
 
 | 152 | foldersOni.add(Paths.getVanillaOnisPath()); | 
 
 
 
 
 | 153 |  | 
 
 
 
 
 | 154 | Vector<File> foldersPatches = new Vector<File>(); | 
 
 
 
 
 | 155 |  | 
 
 
 
 
 | 156 | for (Package m : mods) { | 
 
 
 
 
 | 157 | for (int lev : m.getUnlockLevels()) | 
 
 
 
 
 | 158 | unlockLevels.add(lev); | 
 
 
 
 
 | 159 |  | 
 
 
 
 
 | 160 | File oni = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 161 | m.getLocalPath(), "oni"); | 
 
 
 
 
 | 162 | if (oni.exists()) { | 
 
 
 
 
 | 163 | if (m.hasSeparatePlatformDirs()) { | 
 
 
 
 
 | 164 | File oniCommon = CaseInsensitiveFile | 
 
 
 
 
 | 165 | .getCaseInsensitiveFile(oni, "common"); | 
 
 
 
 
 | 166 | File oniMac = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 167 | oni, "mac_only"); | 
 
 
 
 
 | 168 | File oniWin = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 169 | oni, "win_only"); | 
 
 
 
 
 | 170 | if (oniCommon.exists()) | 
 
 
 
 
 | 171 | foldersOni.add(oniCommon); | 
 
 
 
 
 | 172 | if (PlatformInformation.getPlatform() == Platform.MACOS | 
 
 
 
 
 | 173 | && oniMac.exists()) | 
 
 
 
 
 | 174 | foldersOni.add(oniMac); | 
 
 
 
 
 | 175 | else if (oniWin.exists()) | 
 
 
 
 
 | 176 | foldersOni.add(oniWin); | 
 
 
 
 
 | 177 | } else { | 
 
 
 
 
 | 178 | foldersOni.add(oni); | 
 
 
 
 
 | 179 | } | 
 
 
 
 
 | 180 | } | 
 
 
 
 
 | 181 |  | 
 
 
 
 
 | 182 | File patches = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 183 | m.getLocalPath(), "patches"); | 
 
 
 
 
 | 184 | if (patches.exists()) { | 
 
 
 
 
 | 185 | if (m.hasSeparatePlatformDirs()) { | 
 
 
 
 
 | 186 | File patchesCommon = CaseInsensitiveFile | 
 
 
 
 
 | 187 | .getCaseInsensitiveFile(patches, "common"); | 
 
 
 
 
 | 188 | File patchesMac = CaseInsensitiveFile | 
 
 
 
 
 | 189 | .getCaseInsensitiveFile(patches, "mac_only"); | 
 
 
 
 
 | 190 | File patchesWin = CaseInsensitiveFile | 
 
 
 
 
 | 191 | .getCaseInsensitiveFile(patches, "win_only"); | 
 
 
 
 
 | 192 | if (patchesCommon.exists()) | 
 
 
 
 
 | 193 | foldersPatches.add(patchesCommon); | 
 
 
 
 
 | 194 | if (PlatformInformation.getPlatform() == Platform.MACOS | 
 
 
 
 
 | 195 | && patchesMac.exists()) | 
 
 
 
 
 | 196 | foldersPatches.add(patchesMac); | 
 
 
 
 
 | 197 | else if (patchesWin.exists()) | 
 
 
 
 
 | 198 | foldersPatches.add(patchesWin); | 
 
 
 
 
 | 199 | } else { | 
 
 
 
 
 | 200 | foldersPatches.add(patches); | 
 
 
 
 
 | 201 | } | 
 
 
 
 
 | 202 | } | 
 
 
 
 
 | 203 | } | 
 
 
 
 
 | 204 |  | 
 
 
 
 
 | 205 | TreeMap<String, Vector<File>> levels = new TreeMap<String, Vector<File>>( | 
 
 
 
 
 | 206 | new NaturalOrderComparator()); | 
 
 
 
 
 | 207 | log.println("Building sources list"); | 
 
 
 
 
 | 208 | for (File path : foldersOni) { | 
 
 
 
 
 | 209 | log.println("\tFolder " + path.getPath()); | 
 
 
 
 
 | 210 | for (File levelF : path.listFiles()) { | 
 
 
 
 
 | 211 | boolean isSecondaryFile = false; | 
 
 
 
 
 | 212 | log.println("\t\tFolder/file " + levelF.getPath()); | 
 
 
 
 
 | 213 | String fn = levelF.getName().toLowerCase(); | 
 
 
 
 
 | 214 | String levelN = null; | 
 
 
 
 
 | 215 | if (levelF.isDirectory()) { | 
 
 
 
 
 | 216 | levelN = fn; | 
 
 
 
 
 | 217 | levelsAffectedNow.add(fn.toLowerCase()); | 
 
 
 
 
 | 218 | } else if (fn.endsWith(".dat")) { | 
 
 
 
 
 | 219 | levelN = fn.substring(0, fn.lastIndexOf('.')).toLowerCase(); | 
 
 
 
 
 | 220 | } else if (fn.endsWith(".raw") || fn.endsWith(".sep")) { | 
 
 
 
 
 | 221 | isSecondaryFile = true; | 
 
 
 
 
 | 222 | } | 
 
 
 
 
 | 223 | if (levelN != null) { | 
 
 
 
 
 | 224 | log.println("\t\t\tAdded for level " + levelN); | 
 
 
 
 
 | 225 | if (!levels.containsKey(levelN)) | 
 
 
 
 
 | 226 | levels.put(levelN, new Vector<File>()); | 
 
 
 
 
 | 227 | levels.get(levelN).add(levelF); | 
 
 
 
 
 | 228 | } else if (!isSecondaryFile) { | 
 
 
 
 
 | 229 | if (fn.equalsIgnoreCase(".DS_Store")) { | 
 
 
 
 
 | 230 | // Ignore OSX bullshit | 
 
 
 
 
 | 231 | } else { | 
 
 
 
 
 | 232 | log.println("\t\t\tNot a level file!?"); | 
 
 
 
 
 | 233 | } | 
 
 
 
 
 | 234 | } | 
 
 
 
 
 | 235 | } | 
 
 
 
 
 | 236 | } | 
 
 
 
 
 | 237 |  | 
 
 
 
 
 | 238 | Paths.getEditionGDF().mkdirs(); | 
 
 
 
 
 | 239 | for (File f : Paths.getEditionGDF().listFiles(new FilenameFilter() { | 
 
 
 
 
 | 240 | public boolean accept(File arg0, String arg1) { | 
 
 
 
 
 | 241 | String s = arg1.toLowerCase(); | 
 
 
 
 
 | 242 | return s.endsWith(".dat") | 
 
 
 
 
 | 243 | || s.endsWith(".raw") | 
 
 
 
 
 | 244 | || s.endsWith(".sep") | 
 
 
 
 
 | 245 | || (s.equals("intro.bik") && !SettingsManager | 
 
 
 
 
 | 246 | .getInstance().get("copyintro", false)) | 
 
 
 
 
 | 247 | || (s.equals("outro.bik") && !SettingsManager | 
 
 
 
 
 | 248 | .getInstance().get("copyoutro", false)); | 
 
 
 
 
 | 249 | } | 
 
 
 
 
 | 250 | })) { | 
 
 
 
 
 | 251 | String l = f.getName().toLowerCase(); | 
 
 
 
 
 | 252 | l = l.substring(0, l.length() - 4); | 
 
 
 
 
 | 253 | if ((levelsAffectedBefore == null) | 
 
 
 
 
 | 254 | || levelsAffectedBefore.contains(l) | 
 
 
 
 
 | 255 | || levelsAffectedNow.contains(l)) | 
 
 
 
 
 | 256 | f.delete(); | 
 
 
 
 
 | 257 | } | 
 
 
 
 
 | 258 |  | 
 
 
 
 
 | 259 | applyPatches(levels, foldersPatches, listener, log); | 
 
 
 
 
 | 260 |  | 
 
 
 
 
 | 261 | TreeSet<String> levelsAffectedBoth = null; | 
 
 
 
 
 | 262 | if (levelsAffectedBefore != null) { | 
 
 
 
 
 | 263 | levelsAffectedBoth = new TreeSet<String>(); | 
 
 
 
 
 | 264 | levelsAffectedBoth.addAll(levelsAffectedBefore); | 
 
 
 
 
 | 265 | levelsAffectedBoth.addAll(levelsAffectedNow); | 
 
 
 
 
 | 266 | } | 
 
 
 
 
 | 267 |  | 
 
 
 
 
 | 268 | combineBinaryFiles(levels, levelsAffectedBoth, listener, log); | 
 
 
 
 
 | 269 |  | 
 
 
 
 
 | 270 | try { | 
 
 
 
 
 | 271 | combineBSLFolders(mods, listener, log); | 
 
 
 
 
 | 272 | } catch (IOException e) { | 
 
 
 
 
 | 273 | log.println("Failed installing BSL files, see aei-output.log for stacktrace"); | 
 
 
 
 
 | 274 | e.printStackTrace(); | 
 
 
 
 
 | 275 | } | 
 
 
 
 
 | 276 |  | 
 
 
 
 
 | 277 | copyPlainFiles (log, mods, listener); | 
 
 
 
 
 | 278 |  | 
 
 
 
 
 | 279 | copyVideos(log); | 
 
 
 
 
 | 280 |  | 
 
 
 
 
 | 281 | if (unlockLevels.size() > 0) { | 
 
 
 
 
 | 282 | unlockLevels(unlockLevels, log); | 
 
 
 
 
 | 283 | } | 
 
 
 
 
 | 284 |  | 
 
 
 
 
 | 285 | ModInstallationList mil = ModInstallationList.getInstance(); | 
 
 
 
 
 | 286 | mil.setAffectedLevels(levelsAffectedNow); | 
 
 
 
 
 | 287 | TreeSet<Integer> modsInstalled = new TreeSet<Integer>(); | 
 
 
 
 
 | 288 | for (Package p : mods) { | 
 
 
 
 
 | 289 | modsInstalled.add(p.getPackageNumber()); | 
 
 
 
 
 | 290 | } | 
 
 
 
 
 | 291 | mil.setInstalledMods(modsInstalled); | 
 
 
 
 
 | 292 | mil.saveList(); | 
 
 
 
 
 | 293 |  | 
 
 
 
 
 | 294 | log.println(); | 
 
 
 
 
 | 295 | Date end = new Date(); | 
 
 
 
 
 | 296 | log.println("Installation ended at " + sdf.format(end)); | 
 
 
 
 
 | 297 | log.println("Process took " | 
 
 
 
 
 | 298 | + ((end.getTime() - start.getTime()) / 1000) + " seconds"); | 
 
 
 
 
 | 299 | log.close(); | 
 
 
 
 
 | 300 | } | 
 
 
 
 
 | 301 |  | 
 
 
 
 
 | 302 | private static void combineBSLFolders(TreeSet<Package> mods, | 
 
 
 
 
 | 303 | InstallProgressListener listener, Logger log) throws IOException { | 
 
 
 
 
 | 304 | listener.installProgressUpdate(95, 100, AEInstaller2.globalBundle.getString("modInstaller.installBsl")); | 
 
 
 
 
 | 305 | log.println(); | 
 
 
 
 
 | 306 | log.println("Installing BSL files"); | 
 
 
 
 
 | 307 |  | 
 
 
 
 
 | 308 | // First install core non-addon mods | 
 
 
 
 
 | 309 | log.println("\tCore, non-addon"); | 
 
 
 
 
 | 310 | for (Package m : mods) { | 
 
 
 
 
 | 311 | if (m.isCorePackage() && m.getBSLInstallType() == EBSLInstallType.NORMAL) { | 
 
 
 
 
 | 312 | handleModBsl (m, log, null); | 
 
 
 
 
 | 313 | } | 
 
 
 
 
 | 314 | } | 
 
 
 
 
 | 315 |  | 
 
 
 
 
 | 316 | // Now overwrite / add files coming from core addons | 
 
 
 
 
 | 317 | log.println("\tCore, addon"); | 
 
 
 
 
 | 318 | for (Package m : mods) { | 
 
 
 
 
 | 319 | if (m.isCorePackage() && m.getBSLInstallType() == EBSLInstallType.ADDON) { | 
 
 
 
 
 | 320 | handleModBsl (m, log, null); | 
 
 
 
 
 | 321 | } | 
 
 
 
 
 | 322 | } | 
 
 
 
 
 | 323 |  | 
 
 
 
 
 | 324 | // Install non-core non-addon mods (levels affected here are first cleaned up) | 
 
 
 
 
 | 325 | log.println("\tNon-core, non-addon"); | 
 
 
 
 
 | 326 | HashSet<String> clearedFolders = new HashSet<String>(); | 
 
 
 
 
 | 327 | for (Package m : mods) { | 
 
 
 
 
 | 328 | if (!m.isCorePackage() && m.getBSLInstallType() == EBSLInstallType.NORMAL) { | 
 
 
 
 
 | 329 | handleModBsl (m, log, clearedFolders); | 
 
 
 
 
 | 330 | } | 
 
 
 
 
 | 331 | } | 
 
 
 
 
 | 332 |  | 
 
 
 
 
 | 333 | // Lastly overwrite / add files coming from non-core addons | 
 
 
 
 
 | 334 | log.println("\tNon-core, addon"); | 
 
 
 
 
 | 335 | for (Package m : mods) { | 
 
 
 
 
 | 336 | if (!m.isCorePackage() && m.getBSLInstallType() == EBSLInstallType.ADDON) { | 
 
 
 
 
 | 337 | handleModBsl (m, log, null); | 
 
 
 
 
 | 338 | } | 
 
 
 
 
 | 339 | } | 
 
 
 
 
 | 340 |  | 
 
 
 
 
 | 341 |  | 
 
 
 
 
 | 342 |  | 
 
 
 
 
 | 343 | } | 
 
 
 
 
 | 344 |  | 
 
 
 
 
 | 345 | private static void handleModBsl(Package sourceMod, Logger log, HashSet<String> clearedFolders) throws IOException { | 
 
 
 
 
 | 346 | File bslFolder = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 347 | sourceMod.getLocalPath(), "bsl"); | 
 
 
 
 
 | 348 | if (bslFolder.exists()) { | 
 
 
 
 
 | 349 | if (sourceMod.hasSeparatePlatformDirs()) { | 
 
 
 
 
 | 350 | File bslCommonFolder = CaseInsensitiveFile | 
 
 
 
 
 | 351 | .getCaseInsensitiveFile(bslFolder, "common"); | 
 
 
 
 
 | 352 | File bslMacFolder = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 353 | bslFolder, "mac_only"); | 
 
 
 
 
 | 354 | File bslWinFolder = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 355 | bslFolder, "win_only"); | 
 
 
 
 
 | 356 |  | 
 
 
 
 
 | 357 | if (bslCommonFolder.exists()) { | 
 
 
 
 
 | 358 | copyBsl(sourceMod, log, bslCommonFolder, sourceMod.getBSLInstallType() == EBSLInstallType.ADDON, clearedFolders); | 
 
 
 
 
 | 359 | } | 
 
 
 
 
 | 360 |  | 
 
 
 
 
 | 361 | if (bslWinFolder.exists() && (PlatformInformation.getPlatform() == Platform.WIN || PlatformInformation | 
 
 
 
 
 | 362 | .getPlatform() == Platform.LINUX)) { | 
 
 
 
 
 | 363 | copyBsl(sourceMod, log, bslWinFolder, sourceMod.getBSLInstallType() == EBSLInstallType.ADDON, clearedFolders); | 
 
 
 
 
 | 364 | } | 
 
 
 
 
 | 365 |  | 
 
 
 
 
 | 366 | if (bslMacFolder.exists() && PlatformInformation.getPlatform() == Platform.MACOS) { | 
 
 
 
 
 | 367 | copyBsl(sourceMod, log, bslMacFolder, sourceMod.getBSLInstallType() == EBSLInstallType.ADDON, clearedFolders); | 
 
 
 
 
 | 368 | } | 
 
 
 
 
 | 369 | } else { | 
 
 
 
 
 | 370 | copyBsl(sourceMod, log, bslFolder, sourceMod.getBSLInstallType() == EBSLInstallType.ADDON, clearedFolders); | 
 
 
 
 
 | 371 | } | 
 
 
 
 
 | 372 | } | 
 
 
 
 
 | 373 |  | 
 
 
 
 
 | 374 | } | 
 
 
 
 
 | 375 |  | 
 
 
 
 
 | 376 | private static void copyBsl(Package sourceMod, Logger log, File sourceModFolder, boolean overwriteFiles, HashSet<String> clearedFolders) throws IOException { | 
 
 
 
 
 | 377 | File targetBaseFolder = new File(Paths.getEditionGDF(), "IGMD"); | 
 
 
 
 
 | 378 | if (!targetBaseFolder.exists()) | 
 
 
 
 
 | 379 | targetBaseFolder.mkdir(); | 
 
 
 
 
 | 380 |  | 
 
 
 
 
 | 381 | log.println("\t\tMod \"" + sourceMod.getName() + "\" (from " + sourceModFolder.getName() + ")"); | 
 
 
 
 
 | 382 | for (File sourceLevelFolder : sourceModFolder.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 383 | log.println("\t\t\t" + sourceLevelFolder.getName()); | 
 
 
 
 
 | 384 |  | 
 
 
 
 
 | 385 | File targetLevelFolder = new File(targetBaseFolder, sourceLevelFolder.getName()); | 
 
 
 
 
 | 386 |  | 
 
 
 
 
 | 387 | if ((CaseInsensitiveFile.getCaseInsensitiveFile(targetLevelFolder, | 
 
 
 
 
 | 388 | "ignore.txt").exists())) { | 
 
 
 
 
 | 389 | // Ignore feature: Don't apply any changes to the target level folder if it contains an "ignore.txt" file | 
 
 
 
 
 | 390 | log.println("\t\t\t\tSkipping level, target contains an \"ignore.txt\" file"); | 
 
 
 
 
 | 391 | continue; | 
 
 
 
 
 | 392 | } | 
 
 
 
 
 | 393 |  | 
 
 
 
 
 | 394 | if (clearedFolders != null && targetLevelFolder.exists() && !clearedFolders.contains(targetLevelFolder.getName())) { | 
 
 
 
 
 | 395 | // We are in a clear-folders step and this target folder hasn't been cleared so far -> clear (aka delete) the target folder | 
 
 
 
 
 | 396 | log.println("\t\t\t\tClearing target, first non-core mod that applies changes to this level"); | 
 
 
 
 
 | 397 | FileUtils.deleteDirectory(targetLevelFolder); | 
 
 
 
 
 | 398 | } | 
 
 
 
 
 | 399 |  | 
 
 
 
 
 | 400 | if (!targetLevelFolder.exists()) { | 
 
 
 
 
 | 401 | targetLevelFolder.mkdir(); | 
 
 
 
 
 | 402 | if (clearedFolders != null) { | 
 
 
 
 
 | 403 | // Clear-folders step and the target folder did not exist (or was removed for clearing) -> this folder counts as cleared | 
 
 
 
 
 | 404 | clearedFolders.add(targetLevelFolder.getName()); | 
 
 
 
 
 | 405 | } | 
 
 
 
 
 | 406 | } | 
 
 
 
 
 | 407 |  | 
 
 
 
 
 | 408 | for (File sourceBslFile : sourceLevelFolder.listFiles()) { | 
 
 
 
 
 | 409 | if (sourceBslFile.getName().toLowerCase().endsWith(".bsl")) { | 
 
 
 
 
 | 410 | File targetFile = new File(targetLevelFolder, sourceBslFile.getName()); | 
 
 
 
 
 | 411 | if (overwriteFiles || !targetFile.exists()) { | 
 
 
 
 
 | 412 | // Copy every BSL file from source to target if it either does not yet exist in target or we're currently applying addons (thus overwriting files): | 
 
 
 
 
 | 413 | if (targetFile.exists()) { | 
 
 
 
 
 | 414 | log.println("\t\t\t\tOverwriting file from addon: \"" + sourceBslFile.getName() + "\""); | 
 
 
 
 
 | 415 | } | 
 
 
 
 
 | 416 | FileUtils.copyFile(sourceBslFile, targetFile); | 
 
 
 
 
 | 417 | } else { | 
 
 
 
 
 | 418 | // Non-addon mod, target already exists, skip file | 
 
 
 
 
 | 419 | log.println("\t\t\t\tSkipping file \"" + sourceBslFile.getName() + "\", target already exists"); | 
 
 
 
 
 | 420 | } | 
 
 
 
 
 | 421 | } | 
 
 
 
 
 | 422 | } | 
 
 
 
 
 | 423 |  | 
 
 
 
 
 | 424 | } | 
 
 
 
 
 | 425 |  | 
 
 
 
 
 | 426 | } | 
 
 
 
 
 | 427 |  | 
 
 
 
 
 | 428 | /* | 
 
 
 
 
 | 429 | private static void copyBSL(Package sourceMod, boolean addon, Logger log) { | 
 
 
 
 
 | 430 | File targetBaseFolder = new File(Paths.getEditionGDF(), "IGMD"); | 
 
 
 
 
 | 431 | if (!targetBaseFolder.exists()) | 
 
 
 
 
 | 432 | targetBaseFolder.mkdir(); | 
 
 
 
 
 | 433 |  | 
 
 
 
 
 | 434 | Vector<File> sources = new Vector<File>(); | 
 
 
 
 
 | 435 | File bsl = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 436 | sourceMod.getLocalPath(), "bsl"); | 
 
 
 
 
 | 437 | if (sourceMod.hasSeparatePlatformDirs()) { | 
 
 
 
 
 | 438 | File bslCommon = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, | 
 
 
 
 
 | 439 | "common"); | 
 
 
 
 
 | 440 | File bslMac = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, | 
 
 
 
 
 | 441 | "mac_only"); | 
 
 
 
 
 | 442 | File bslWin = CaseInsensitiveFile.getCaseInsensitiveFile(bsl, | 
 
 
 
 
 | 443 | "win_only"); | 
 
 
 
 
 | 444 | if (PlatformInformation.getPlatform() == Platform.MACOS | 
 
 
 
 
 | 445 | && bslMac.exists()) { | 
 
 
 
 
 | 446 | for (File f : bslMac.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 447 | File targetBSL = new File(targetBaseFolder, f.getName()); | 
 
 
 
 
 | 448 | if (addon || !targetBSL.exists()) | 
 
 
 
 
 | 449 | sources.add(f); | 
 
 
 
 
 | 450 | } | 
 
 
 
 
 | 451 | } | 
 
 
 
 
 | 452 | if ((PlatformInformation.getPlatform() == Platform.WIN || PlatformInformation | 
 
 
 
 
 | 453 | .getPlatform() == Platform.LINUX) && bslWin.exists()) { | 
 
 
 
 
 | 454 | for (File f : bslWin.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 455 | File targetBSL = new File(targetBaseFolder, f.getName()); | 
 
 
 
 
 | 456 | if (addon || !targetBSL.exists()) | 
 
 
 
 
 | 457 | sources.add(f); | 
 
 
 
 
 | 458 | } | 
 
 
 
 
 | 459 | } | 
 
 
 
 
 | 460 | if (bslCommon.exists()) { | 
 
 
 
 
 | 461 | for (File f : bslCommon.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 462 | File targetBSL = new File(targetBaseFolder, f.getName()); | 
 
 
 
 
 | 463 | if (addon || !targetBSL.exists()) | 
 
 
 
 
 | 464 | sources.add(f); | 
 
 
 
 
 | 465 | } | 
 
 
 
 
 | 466 | } | 
 
 
 
 
 | 467 | } else { | 
 
 
 
 
 | 468 | for (File f : bsl.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 469 | File targetBSL = new File(targetBaseFolder, f.getName()); | 
 
 
 
 
 | 470 | if (addon || !targetBSL.exists()) | 
 
 
 
 
 | 471 | sources.add(f); | 
 
 
 
 
 | 472 | } | 
 
 
 
 
 | 473 | } | 
 
 
 
 
 | 474 |  | 
 
 
 
 
 | 475 | log.println("\tMod \"" + sourceMod.getName() + "\""); | 
 
 
 
 
 | 476 | for (File f : sources) { | 
 
 
 
 
 | 477 | log.println("\t\t" + f.getName()); | 
 
 
 
 
 | 478 | File targetPath = new File(targetBaseFolder, f.getName()); | 
 
 
 
 
 | 479 | if (!targetPath.exists()) | 
 
 
 
 
 | 480 | targetPath.mkdir(); | 
 
 
 
 
 | 481 | if (!(CaseInsensitiveFile.getCaseInsensitiveFile(targetPath, | 
 
 
 
 
 | 482 | "ignore.txt").exists())) { | 
 
 
 
 
 | 483 | for (File fbsl : f.listFiles()) { | 
 
 
 
 
 | 484 | if (fbsl.getName().toLowerCase().endsWith(".bsl")) { | 
 
 
 
 
 | 485 | File targetFile = new File(targetPath, fbsl.getName()); | 
 
 
 
 
 | 486 | if (addon || !targetFile.exists()) { | 
 
 
 
 
 | 487 | try { | 
 
 
 
 
 | 488 | FileUtils.copyFile(fbsl, targetFile); | 
 
 
 
 
 | 489 | } catch (IOException e) { | 
 
 
 
 
 | 490 | e.printStackTrace(); | 
 
 
 
 
 | 491 | } | 
 
 
 
 
 | 492 | } | 
 
 
 
 
 | 493 | } | 
 
 
 
 
 | 494 | } | 
 
 
 
 
 | 495 | } | 
 
 
 
 
 | 496 | } | 
 
 
 
 
 | 497 | } | 
 
 
 
 
 | 498 | */ | 
 
 
 
 
 | 499 |  | 
 
 
 
 
 | 500 | private static void applyPatches( | 
 
 
 
 
 | 501 | TreeMap<String, Vector<File>> oniLevelFolders, | 
 
 
 
 
 | 502 | List<File> patchFolders, InstallProgressListener listener, | 
 
 
 
 
 | 503 | Logger log) { | 
 
 
 
 
 | 504 | log.println(); | 
 
 
 
 
 | 505 | log.println("Applying XML patches"); | 
 
 
 
 
 | 506 | listener.installProgressUpdate(0, 1, AEInstaller2.globalBundle.getString("modInstaller.applyXmlPatches")); | 
 
 
 
 
 | 507 |  | 
 
 
 
 
 | 508 | long startMS = new Date().getTime(); | 
 
 
 
 
 | 509 |  | 
 
 
 
 
 | 510 | String tmpFolderName = "installrun_temp-" | 
 
 
 
 
 | 511 | + new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss") | 
 
 
 
 
 | 512 | .format(new Date()); | 
 
 
 
 
 | 513 | File tmpFolder = new File(Paths.getTempPath(), tmpFolderName); | 
 
 
 
 
 | 514 | tmpFolder.mkdir(); | 
 
 
 
 
 | 515 |  | 
 
 
 
 
 | 516 | TreeMap<String, Vector<File>> patches = new TreeMap<String, Vector<File>>( | 
 
 
 
 
 | 517 | new NaturalOrderComparator()); | 
 
 
 
 
 | 518 | for (File patchFolder : patchFolders) { | 
 
 
 
 
 | 519 | for (File levelFolder : patchFolder.listFiles(dirFileFilter)) { | 
 
 
 
 
 | 520 | String lvlName = levelFolder.getName().toLowerCase(); | 
 
 
 
 
 | 521 | for (File f : FileUtils.listFiles(levelFolder, | 
 
 
 
 
 | 522 | new String[] { "oni-patch" }, true)) { | 
 
 
 
 
 | 523 | if (!patches.containsKey(lvlName)) | 
 
 
 
 
 | 524 | patches.put(lvlName, new Vector<File>()); | 
 
 
 
 
 | 525 | patches.get(lvlName).add(f); | 
 
 
 
 
 | 526 | } | 
 
 
 
 
 | 527 | } | 
 
 
 
 
 | 528 | } | 
 
 
 
 
 | 529 |  | 
 
 
 
 
 | 530 | for (String level : patches.keySet()) { | 
 
 
 
 
 | 531 | File levelFolder = new File(tmpFolder, level); | 
 
 
 
 
 | 532 | levelFolder.mkdir(); | 
 
 
 
 
 | 533 |  | 
 
 
 
 
 | 534 | log.println("\t\tPatches for " + level); | 
 
 
 
 
 | 535 |  | 
 
 
 
 
 | 536 | log.println("\t\t\tSource files/folders:"); | 
 
 
 
 
 | 537 | for (File srcFolder : oniLevelFolders.get(level)) { | 
 
 
 
 
 | 538 | log.println("\t\t\t\t" + srcFolder.getPath()); | 
 
 
 
 
 | 539 | } | 
 
 
 
 
 | 540 |  | 
 
 
 
 
 | 541 | // Get files to be patched from vanilla.dat | 
 
 
 
 
 | 542 | Vector<String> exportPatterns = new Vector<String>(); | 
 
 
 
 
 | 543 | for (File patch : patches.get(level)) { | 
 
 
 
 
 | 544 | String patternWildcard = patch.getName(); | 
 
 
 
 
 | 545 | patternWildcard = patternWildcard.substring(0, | 
 
 
 
 
 | 546 | patternWildcard.indexOf(".oni-patch")); | 
 
 
 
 
 | 547 | patternWildcard = patternWildcard.replace('-', '*'); | 
 
 
 
 
 | 548 | exportPatterns.add(patternWildcard); | 
 
 
 
 
 | 549 | } | 
 
 
 
 
 | 550 | for (File srcFolder : oniLevelFolders.get(level)) { | 
 
 
 
 
 | 551 | if (srcFolder.isFile()) { | 
 
 
 
 
 | 552 | if (srcFolder.getPath().toLowerCase().contains("vanilla")) { | 
 
 
 
 
 | 553 | // Extract from .dat | 
 
 
 
 
 | 554 | ApplicationInvocationResult res = OniSplit.export( | 
 
 
 
 
 | 555 | levelFolder, srcFolder, exportPatterns); | 
 
 
 
 
 | 556 | log.logAppOutput(res, true); | 
 
 
 
 
 | 557 | } | 
 
 
 
 
 | 558 | } | 
 
 
 
 
 | 559 | } | 
 
 
 
 
 | 560 |  | 
 
 
 
 
 | 561 | // Get files to be patched from packages | 
 
 
 
 
 | 562 | for (File patch : patches.get(level)) { | 
 
 
 
 
 | 563 | String patternWildcard = patch.getName(); | 
 
 
 
 
 | 564 | patternWildcard = patternWildcard.substring(0, | 
 
 
 
 
 | 565 | patternWildcard.indexOf(".oni-patch")); | 
 
 
 
 
 | 566 | patternWildcard = patternWildcard.replace('-', '*'); | 
 
 
 
 
 | 567 | Vector<String> patterns = new Vector<String>(); | 
 
 
 
 
 | 568 | patterns.add(patternWildcard); | 
 
 
 
 
 | 569 | patternWildcard = patternWildcard + ".oni"; | 
 
 
 
 
 | 570 | final Pattern patternRegex = Pattern.compile( | 
 
 
 
 
 | 571 | patternWildcard.replaceAll("\\*", ".\\*"), | 
 
 
 
 
 | 572 | Pattern.CASE_INSENSITIVE); | 
 
 
 
 
 | 573 |  | 
 
 
 
 
 | 574 | for (File srcFolder : oniLevelFolders.get(level)) { | 
 
 
 
 
 | 575 | if (srcFolder.isFile()) { | 
 
 
 
 
 | 576 | if (!srcFolder.getPath().toLowerCase() | 
 
 
 
 
 | 577 | .contains("vanilla")) { | 
 
 
 
 
 | 578 | // Extract from .dat | 
 
 
 
 
 | 579 | ApplicationInvocationResult res = OniSplit.export( | 
 
 
 
 
 | 580 | levelFolder, srcFolder, patterns); | 
 
 
 
 
 | 581 | log.logAppOutput(res, true); | 
 
 
 
 
 | 582 | } | 
 
 
 
 
 | 583 | } else { | 
 
 
 
 
 | 584 | // Copy from folder with overwrite | 
 
 
 
 
 | 585 | for (File f : FileUtils.listFiles(srcFolder, | 
 
 
 
 
 | 586 | new RegexFileFilter(patternRegex), | 
 
 
 
 
 | 587 | TrueFileFilter.TRUE)) { | 
 
 
 
 
 | 588 | try { | 
 
 
 
 
 | 589 | FileUtils.copyFileToDirectory(f, levelFolder); | 
 
 
 
 
 | 590 | } catch (IOException e) { | 
 
 
 
 
 | 591 | e.printStackTrace(); | 
 
 
 
 
 | 592 | } | 
 
 
 
 
 | 593 | } | 
 
 
 
 
 | 594 | } | 
 
 
 
 
 | 595 | } | 
 
 
 
 
 | 596 | } | 
 
 
 
 
 | 597 |  | 
 
 
 
 
 | 598 | // Extract files to XML | 
 
 
 
 
 | 599 | File levelFolderXML = new File(levelFolder, "xml"); | 
 
 
 
 
 | 600 | Vector<File> files = new Vector<File>(); | 
 
 
 
 
 | 601 | files.add(new File(levelFolder, "*.oni")); | 
 
 
 
 
 | 602 | ApplicationInvocationResult res = OniSplit.convertOniToXML( | 
 
 
 
 
 | 603 | levelFolderXML, files); | 
 
 
 
 
 | 604 | log.logAppOutput(res, true); | 
 
 
 
 
 | 605 |  | 
 
 
 
 
 | 606 | // Create masterpatch file (containing calls to all individual | 
 
 
 
 
 | 607 | // patches) | 
 
 
 
 
 | 608 | File masterpatch = new File(levelFolderXML, "masterpatch.txt"); | 
 
 
 
 
 | 609 | PrintWriter masterpatchWriter = null; | 
 
 
 
 
 | 610 | try { | 
 
 
 
 
 | 611 | masterpatchWriter = new PrintWriter(new OutputStreamWriter( | 
 
 
 
 
 | 612 | new FileOutputStream(masterpatch), "UTF-8")); | 
 
 
 
 
 | 613 | } catch (FileNotFoundException e) { | 
 
 
 
 
 | 614 | e.printStackTrace(); | 
 
 
 
 
 | 615 | } catch (UnsupportedEncodingException e) { | 
 
 
 
 
 | 616 | e.printStackTrace(); | 
 
 
 
 
 | 617 | } | 
 
 
 
 
 | 618 | for (File patch : patches.get(level)) { | 
 
 
 
 
 | 619 | String patternWildcard = patch.getName(); | 
 
 
 
 
 | 620 | patternWildcard = patternWildcard.substring(0, | 
 
 
 
 
 | 621 | patternWildcard.indexOf(".oni-patch")); | 
 
 
 
 
 | 622 | patternWildcard = patternWildcard + ".xml"; | 
 
 
 
 
 | 623 | patternWildcard = patternWildcard.replace('-', '*'); | 
 
 
 
 
 | 624 | File xmlFilePath = new File(levelFolderXML, patternWildcard); | 
 
 
 
 
 | 625 | masterpatchWriter.println(String.format("\"%s\" \"%s\"", | 
 
 
 
 
 | 626 | patch.getPath(), xmlFilePath.getPath())); | 
 
 
 
 
 | 627 | } | 
 
 
 
 
 | 628 | masterpatchWriter.close(); | 
 
 
 
 
 | 629 | // Apply patches through masterpatch in levelFolderXML | 
 
 
 
 
 | 630 | res = XMLTools.patch(masterpatch); | 
 
 
 
 
 | 631 | log.logAppOutput(res, true); | 
 
 
 
 
 | 632 |  | 
 
 
 
 
 | 633 | // Create .oni files from XML | 
 
 
 
 
 | 634 | files.clear(); | 
 
 
 
 
 | 635 | files.add(new File(levelFolderXML, "*.xml")); | 
 
 
 
 
 | 636 | res = OniSplit.convertXMLtoOni(levelFolder, files); | 
 
 
 
 
 | 637 | log.logAppOutput(res, true); | 
 
 
 
 
 | 638 |  | 
 
 
 
 
 | 639 | if (!RuntimeOptions.isDebug()) { | 
 
 
 
 
 | 640 | // Remove XML folder as import will only require .oni's | 
 
 
 
 
 | 641 | try { | 
 
 
 
 
 | 642 | FileUtils.deleteDirectory(levelFolderXML); | 
 
 
 
 
 | 643 | } catch (IOException e) { | 
 
 
 
 
 | 644 | e.printStackTrace(); | 
 
 
 
 
 | 645 | } | 
 
 
 
 
 | 646 | } | 
 
 
 
 
 | 647 |  | 
 
 
 
 
 | 648 | oniLevelFolders.get(level).add(levelFolder); | 
 
 
 
 
 | 649 | } | 
 
 
 
 
 | 650 |  | 
 
 
 
 
 | 651 | log.println("Applying XML patches took " | 
 
 
 
 
 | 652 | + (new Date().getTime() - startMS) + " ms"); | 
 
 
 
 
 | 653 | } | 
 
 
 
 
 | 654 |  | 
 
 
 
 
 | 655 | private static void combineBinaryFiles( | 
 
 
 
 
 | 656 | TreeMap<String, Vector<File>> oniLevelFolders, | 
 
 
 
 
 | 657 | TreeSet<String> levelsUpdated, InstallProgressListener listener, | 
 
 
 
 
 | 658 | Logger log) { | 
 
 
 
 
 | 659 | long startMS = new Date().getTime(); | 
 
 
 
 
 | 660 |  | 
 
 
 
 
 | 661 | int totalSteps = oniLevelFolders.size() + 1; | 
 
 
 
 
 | 662 | int stepsDone = 0; | 
 
 
 
 
 | 663 |  | 
 
 
 
 
 | 664 | log.println(); | 
 
 
 
 
 | 665 | log.println("Importing levels"); | 
 
 
 
 
 | 666 | for (String l : oniLevelFolders.keySet()) { | 
 
 
 
 
 | 667 | log.println("\tLevel " + l); | 
 
 
 
 
 | 668 | listener.installProgressUpdate(stepsDone, totalSteps, | 
 
 
 
 
 | 669 | AEInstaller2.globalBundle.getString("modInstaller.buildingLevelN").replaceAll("%1", l.toString())); | 
 
 
 
 
 | 670 |  | 
 
 
 
 
 | 671 | if ((levelsUpdated == null) | 
 
 
 
 
 | 672 | || levelsUpdated.contains(l.toLowerCase())) { | 
 
 
 
 
 | 673 | ApplicationInvocationResult res = OniSplit.packLevel( | 
 
 
 
 
 | 674 | oniLevelFolders.get(l), new File(Paths.getEditionGDF(), | 
 
 
 
 
 | 675 | sanitizeLevelName(l) + ".dat")); | 
 
 
 
 
 | 676 | log.logAppOutput(res, true); | 
 
 
 
 
 | 677 | } else { | 
 
 
 
 
 | 678 | log.println("\t\tLevel not affected by new mod selection"); | 
 
 
 
 
 | 679 | log.println(); | 
 
 
 
 
 | 680 | } | 
 
 
 
 
 | 681 |  | 
 
 
 
 
 | 682 | stepsDone++; | 
 
 
 
 
 | 683 | } | 
 
 
 
 
 | 684 |  | 
 
 
 
 
 | 685 | log.println("Importing levels took " + (new Date().getTime() - startMS) | 
 
 
 
 
 | 686 | + " ms"); | 
 
 
 
 
 | 687 | log.println(); | 
 
 
 
 
 | 688 | } | 
 
 
 
 
 | 689 |  | 
 
 
 
 
 | 690 | private static void copyVideos(Logger log) { | 
 
 
 
 
 | 691 | log.println(); | 
 
 
 
 
 | 692 | if (SettingsManager.getInstance().get("copyintro", false)) { | 
 
 
 
 
 | 693 | File src = new File(Paths.getVanillaGDF(), "intro.bik"); | 
 
 
 
 
 | 694 | File target = new File(Paths.getEditionGDF(), "intro.bik"); | 
 
 
 
 
 | 695 | log.println("Copying intro"); | 
 
 
 
 
 | 696 | if (src.exists() && !target.exists()) { | 
 
 
 
 
 | 697 | try { | 
 
 
 
 
 | 698 | FileUtils.copyFileToDirectory(src, Paths.getEditionGDF()); | 
 
 
 
 
 | 699 | } catch (IOException e) { | 
 
 
 
 
 | 700 | e.printStackTrace(); | 
 
 
 
 
 | 701 | } | 
 
 
 
 
 | 702 | } | 
 
 
 
 
 | 703 | } else { | 
 
 
 
 
 | 704 | log.println("NOT copying intro"); | 
 
 
 
 
 | 705 | } | 
 
 
 
 
 | 706 | if (SettingsManager.getInstance().get("copyoutro", true)) { | 
 
 
 
 
 | 707 | File src = new File(Paths.getVanillaGDF(), "outro.bik"); | 
 
 
 
 
 | 708 | File target = new File(Paths.getEditionGDF(), "outro.bik"); | 
 
 
 
 
 | 709 | log.println("Copying outro"); | 
 
 
 
 
 | 710 | if (src.exists() && !target.exists()) { | 
 
 
 
 
 | 711 | try { | 
 
 
 
 
 | 712 | FileUtils.copyFileToDirectory(src, Paths.getEditionGDF()); | 
 
 
 
 
 | 713 | } catch (IOException e) { | 
 
 
 
 
 | 714 | e.printStackTrace(); | 
 
 
 
 
 | 715 | } | 
 
 
 
 
 | 716 | } | 
 
 
 
 
 | 717 | } else { | 
 
 
 
 
 | 718 | log.println("NOT copying outro"); | 
 
 
 
 
 | 719 | } | 
 
 
 
 
 | 720 | } | 
 
 
 
 
 | 721 |  | 
 
 
 
 
 | 722 | private static void copyPlainFiles(final Logger log, TreeSet<Package> mods, InstallProgressListener listener) { | 
 
 
 
 
 | 723 | listener.installProgressUpdate(97, 100, AEInstaller2.globalBundle.getString("modInstaller.copyPlainFiles")); | 
 
 
 
 
 | 724 | log.println(); | 
 
 
 
 
 | 725 | log.println("Copying plain files from mods"); | 
 
 
 
 
 | 726 |  | 
 
 
 
 
 | 727 | for (Package p : mods) { | 
 
 
 
 
 | 728 | ToolFileIterator.iteratePlatformToolFiles(p, | 
 
 
 
 
 | 729 | new ToolFileIteratorEntry() { | 
 
 
 
 
 | 730 | @Override | 
 
 
 
 
 | 731 | public void toolFile(File source, File target, boolean isDir) { | 
 
 
 
 
 | 732 | copyPlainFile(source, target, log); | 
 
 
 
 
 | 733 | } | 
 
 
 
 
 | 734 | }); | 
 
 
 
 
 | 735 | } | 
 
 
 
 
 | 736 | } | 
 
 
 
 
 | 737 |  | 
 
 
 
 
 | 738 | private static void copyPlainFile(File src, File target, Logger log) { | 
 
 
 
 
 | 739 | try { | 
 
 
 
 
 | 740 | if (src.getAbsolutePath().toLowerCase().contains("gamedatafolder")) { | 
 
 
 
 
 | 741 | File targetFile = CaseInsensitiveFile.getCaseInsensitiveFile( | 
 
 
 
 
 | 742 | target.getParentFile(), target.getName()); | 
 
 
 
 
 | 743 |  | 
 
 
 
 
 | 744 | // Case mismatch? | 
 
 
 
 
 | 745 | if (!targetFile.getName().equals(src.getName())) | 
 
 
 
 
 | 746 | targetFile.delete(); | 
 
 
 
 
 | 747 |  | 
 
 
 
 
 | 748 | FileUtils.copyFile(src, target); | 
 
 
 
 
 | 749 | } else { | 
 
 
 
 
 | 750 | log.printlnFmt("Not copying \"%s\": Not within GameDataFolder", src.getPath()); | 
 
 
 
 
 | 751 | } | 
 
 
 
 
 | 752 | } catch (IOException e) { | 
 
 
 
 
 | 753 | e.printStackTrace(); | 
 
 
 
 
 | 754 | } | 
 
 
 
 
 | 755 | } | 
 
 
 
 
 | 756 |  | 
 
 
 
 
 | 757 |  | 
 
 
 
 
 | 758 | private static void unlockLevels(TreeSet<Integer> unlockLevels, Logger log) { | 
 
 
 
 
 | 759 | File dat = new File(Paths.getEditionBasePath(), "persist.dat"); | 
 
 
 
 
 | 760 | log.println(); | 
 
 
 
 
 | 761 | log.println("Unlocking levels: " + unlockLevels.toString()); | 
 
 
 
 
 | 762 | if (!dat.exists()) { | 
 
 
 
 
 | 763 | InputStream is = AEInstaller2.class | 
 
 
 
 
 | 764 | .getResourceAsStream("/net/oni2/aeinstaller/resources/persist.dat"); | 
 
 
 
 
 | 765 | try { | 
 
 
 
 
 | 766 | FileUtils.copyInputStreamToFile(is, dat); | 
 
 
 
 
 | 767 | } catch (IOException e) { | 
 
 
 
 
 | 768 | e.printStackTrace(); | 
 
 
 
 
 | 769 | } | 
 
 
 
 
 | 770 | } | 
 
 
 
 
 | 771 | PersistDat save = new PersistDat(dat); | 
 
 
 
 
 | 772 | HashSet<Integer> currentlyUnlocked = save.getUnlockedLevels(); | 
 
 
 
 
 | 773 | currentlyUnlocked.addAll(unlockLevels); | 
 
 
 
 
 | 774 | save.setUnlockedLevels(currentlyUnlocked); | 
 
 
 
 
 | 775 | save.close(); | 
 
 
 
 
 | 776 | } | 
 
 
 
 
 | 777 |  | 
 
 
 
 
 | 778 | private static String sanitizeLevelName(String ln) { | 
 
 
 
 
 | 779 | int ind = ln.indexOf("_"); | 
 
 
 
 
 | 780 | String res = ln.substring(0, ind + 1); | 
 
 
 
 
 | 781 | res += ln.substring(ind + 1, ind + 2).toUpperCase(); | 
 
 
 
 
 | 782 | res += ln.substring(ind + 2); | 
 
 
 
 
 | 783 | return res; | 
 
 
 
 
 | 784 | } | 
 
 
 
 
 | 785 |  | 
 
 
 
 
 | 786 | } |