source: java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java@ 1081

Last change on this file since 1081 was 1076, checked in by alloc, 7 years ago

Fixed #112

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