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

Last change on this file since 1020 was 1020, checked in by alloc, 10 years ago

AEI 2.22: Consider all local packages with number < 10000 as Tool, others as Mod. Repository packages are not affected by this

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