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

Last change on this file since 1064 was 1032, checked in by alloc, 9 years ago

v.25: Added some debug information to mod installation, auto flush log, print detected platform

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