source: AE/installer2/src/net/oni2/aeinstaller/backend/mods/Mod.java@ 627

Last change on this file since 627 was 623, checked in by alloc, 12 years ago

AEI2 0.83:

  • Dependencies from Mods to Tools supported
  • Installed tools can get a menu entry to launch them
  • Mods can unlock levels in persist.dat through UnlockLevel-tag
File size: 10.2 KB
Line 
1package net.oni2.aeinstaller.backend.mods;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileNotFoundException;
7import java.io.FilenameFilter;
8import java.io.IOException;
9import java.io.InputStreamReader;
10import java.util.HashSet;
11
12import net.oni2.aeinstaller.backend.Paths;
13import net.oni2.aeinstaller.backend.Settings;
14import net.oni2.aeinstaller.backend.Settings.Platform;
15import net.oni2.aeinstaller.backend.depot.DepotConfig;
16import net.oni2.aeinstaller.backend.depot.DepotManager;
17import net.oni2.aeinstaller.backend.depot.model.NodeMod;
18import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
19
20/**
21 * @author Christian Illy
22 */
23public class Mod implements Comparable<Mod> {
24 private String name = "";
25 private int packageNumber = 0;
26
27 private HashSet<Type> types = new HashSet<Type>();
28 private boolean tool = false;
29 private ECompatiblePlatform platform = null;
30 private String version = "";
31 private String creator = "";
32 private EBSLInstallType bslInstallType = EBSLInstallType.NORMAL;
33 private String description = "";
34 private double aeVersion = 0;
35 private int zipSize = 0;
36 private NodeMod node = null;
37 private net.oni2.aeinstaller.backend.depot.model.File file = null;
38
39 private File exeFile = null;
40 private File iconFile = null;
41 private String workingDir = "Base";
42
43 private HashSet<Integer> incompatibilities = new HashSet<Integer>();
44 private HashSet<Integer> dependencies = new HashSet<Integer>();
45 private HashSet<Integer> unlockLevel = new HashSet<Integer>();
46
47 private long localTimestamp = 0;
48
49 /**
50 * Create a new Mod entry from a given Mod-Node
51 *
52 * @param nm
53 * Mod-Node
54 */
55 public Mod(NodeMod nm) {
56 node = nm;
57 name = nm.getTitle();
58 packageNumber = nm.getPackageNumber();
59 platform = nm.getPlatform();
60 tool = nm.isTool();
61 for (TaxonomyTerm tt : nm.getTypes()) {
62 Type t = ModManager.getInstance().getTypeByName(tt.getName());
63 types.add(t);
64 if (!tool && !isMandatoryMod() && isValidOnPlatform())
65 t.addEntry(this);
66 }
67 version = nm.getVersion();
68 creator = nm.getCreator();
69 if (nm.getBody() != null)
70 description = nm.getBody().getSafe_value();
71 file = DepotManager.getInstance().getFile(
72 nm.getUploads().firstElement().getFid());
73 zipSize = file.getFilesize();
74
75 if (isLocalAvailable())
76 updateLocalData();
77 }
78
79 /**
80 * Update information for local package existence
81 */
82 public void updateLocalData() {
83 File config = new File(getLocalPath(), "Mod_Info.cfg");
84 File aeicfg = new File(getLocalPath(), "aei.cfg");
85 File plain = new File(getLocalPath(), "plain");
86 if (config.exists()) {
87 try {
88 FileInputStream fstream = new FileInputStream(config);
89 InputStreamReader isr = new InputStreamReader(fstream);
90 BufferedReader br = new BufferedReader(isr);
91 String strLine;
92 while ((strLine = br.readLine()) != null) {
93 if (strLine.indexOf("->") < 1)
94 continue;
95 if (strLine.indexOf("//") >= 0)
96 strLine = strLine.substring(0, strLine.indexOf("//"));
97 String[] split = strLine.split("->", 2);
98 String sName = split[0].trim();
99 String sVal = split[1].trim();
100 if (sName.equalsIgnoreCase("AEInstallVersion")) {
101 aeVersion = Double.parseDouble(sVal);
102 } else if (sName.equalsIgnoreCase("NameOfMod")) {
103 if (node == null)
104 name = sVal;
105 } else if (sName.equalsIgnoreCase("Creator")) {
106 if (node == null)
107 creator = sVal;
108 } else if (sName.equalsIgnoreCase("HasBsl")) {
109 if (sVal.equalsIgnoreCase("addon"))
110 bslInstallType = EBSLInstallType.ADDON;
111 } else if (sName.equalsIgnoreCase("ModVersion")) {
112 if (node == null)
113 version = sVal;
114 } else if (sName.equalsIgnoreCase("Readme")) {
115 if (node == null)
116 description = sVal.replaceAll("\\\\n", "<br>");
117 } else if (sName.equalsIgnoreCase("DependsOn")) {
118 String[] depsS = sVal.split(",");
119 for (String s : depsS) {
120 try {
121 int dep = Integer.parseInt(s);
122 dependencies.add(dep);
123 } catch (NumberFormatException e) {
124 System.err
125 .format("Mod %05d does contain a non-number dependency: '%s'\n",
126 packageNumber, s);
127 }
128 }
129 } else if (sName.equalsIgnoreCase("IncompatibleWith")) {
130 String[] confS = sVal.split(",");
131 for (String s : confS) {
132 try {
133 int conf = Integer.parseInt(s);
134 incompatibilities.add(conf);
135 } catch (NumberFormatException e) {
136 System.err
137 .format("Mod %05d does contain a non-number incompatibility: '%s'\n",
138 packageNumber, s);
139 }
140 }
141 } else if (sName.equalsIgnoreCase("UnlockLevel")) {
142 String[] levelsS = sVal.split(",");
143 for (String s : levelsS) {
144 try {
145 int level = Integer.parseInt(s);
146 unlockLevel.add(level);
147 } catch (NumberFormatException e) {
148 System.err
149 .format("Mod %05d does contain a non-number UnlockLevel value: '%s'\n",
150 packageNumber, s);
151 }
152 }
153 } else if (sName.equalsIgnoreCase("ExeName")) {
154 exeFile = new File(Paths.getEditionBasePath(), sVal);
155 } else if (sName.equalsIgnoreCase("WorkingDir")) {
156 workingDir = sVal;
157 } else if (sName.equalsIgnoreCase("IconName")) {
158 iconFile = new File(Paths.getEditionBasePath(), sVal);
159 }
160 }
161 isr.close();
162 } catch (FileNotFoundException e) {
163 } catch (IOException e) {
164 e.printStackTrace();
165 }
166 } else {
167 System.err.println("No config found for mod folder: "
168 + getLocalPath().getPath());
169 }
170 if (aeicfg.exists()) {
171 try {
172 FileInputStream fstream = new FileInputStream(aeicfg);
173 InputStreamReader isr = new InputStreamReader(fstream);
174 BufferedReader br = new BufferedReader(isr);
175 String strLine;
176 while ((strLine = br.readLine()) != null) {
177 if (strLine.indexOf("->") < 1)
178 continue;
179 if (strLine.indexOf("//") >= 0)
180 strLine = strLine.substring(0, strLine.indexOf("//"));
181 String[] split = strLine.split("->", 2);
182 String sName = split[0].trim();
183 String sVal = split[1].trim();
184 if (sName.equalsIgnoreCase("Timestamp")) {
185 localTimestamp = Long.parseLong(sVal);
186 }
187 }
188 isr.close();
189 } catch (FileNotFoundException e) {
190 } catch (IOException e) {
191 e.printStackTrace();
192 }
193 }
194 if (node == null)
195 tool = plain.exists();
196 }
197
198 /**
199 * Create a new Mod entry from the given local mod folder
200 *
201 * @param folder
202 * Mod folder with Mod_Info.cfg
203 */
204 public Mod(File folder) {
205 packageNumber = Integer.parseInt(folder.getName().substring(0, 5));
206 updateLocalData();
207
208 platform = ECompatiblePlatform.BOTH;
209 }
210
211 /**
212 * @return has separate paths for win/mac/common or not
213 */
214 public boolean hasSeparatePlatformDirs() {
215 return aeVersion >= 2;
216 }
217
218 /**
219 * @return Path to local mod folder
220 */
221 public File getLocalPath() {
222 final String folderStart = String.format("%05d", packageNumber);
223
224 if (Paths.getModsPath().exists()) {
225 for (File f : Paths.getModsPath().listFiles(new FilenameFilter() {
226 @Override
227 public boolean accept(File d, String fn) {
228 return fn.startsWith(folderStart);
229 }
230 })) {
231 return f;
232 }
233 }
234
235 return new File(Paths.getModsPath(), folderStart);
236 }
237
238 /**
239 * @return Is there a newer version on the depot?
240 */
241 public boolean isNewerAvailable() {
242 if (file != null)
243 return file.getTimestamp() > localTimestamp;
244 else
245 return false;
246 }
247
248 /**
249 * @return Mod exists within mods folder
250 */
251 public boolean isLocalAvailable() {
252 return getLocalPath().exists();
253 }
254
255 /**
256 * @return Name of mod
257 */
258 public String getName() {
259 return name;
260 }
261
262 /**
263 * @return the package number
264 */
265 public int getPackageNumber() {
266 return packageNumber;
267 }
268
269 /**
270 * @return the package number as 5 digit string
271 */
272 public String getPackageNumberString() {
273 return String.format("%05d", packageNumber);
274 }
275
276 /**
277 * @return Types of mod
278 */
279 public HashSet<Type> getTypes() {
280 return types;
281 }
282
283 /**
284 * @return Is this mod actually a tool?
285 */
286 public boolean isTool() {
287 return tool;
288 }
289
290 /**
291 * @return Compatible platforms
292 */
293 public ECompatiblePlatform getPlatform() {
294 return platform;
295 }
296
297 /**
298 * @return Version of mod
299 */
300 public String getVersion() {
301 return version;
302 }
303
304 /**
305 * @return Creator of mod
306 */
307 public String getCreator() {
308 return creator;
309 }
310
311 /**
312 * @return Installation type of BSL files
313 */
314 public EBSLInstallType getBSLInstallType() {
315 return bslInstallType;
316 }
317
318 /**
319 * @return Description of mod
320 */
321 public String getDescription() {
322 return description;
323 }
324
325 /**
326 * @return Size of Zip file on Depot
327 */
328 public int getZipSize() {
329 return zipSize;
330 }
331
332 /**
333 * @return Is a mod that is always installed?
334 */
335 public boolean isMandatoryMod() {
336 return packageNumber < DepotConfig.getMandatoryLimit();
337 }
338
339 /**
340 * @return Get the depot file entry
341 */
342 public net.oni2.aeinstaller.backend.depot.model.File getFile() {
343 return file;
344 }
345
346 @Override
347 public String toString() {
348 return name;
349 }
350
351 /**
352 * @return the incompabitilities
353 */
354 public HashSet<Integer> getIncompabitilities() {
355 return incompatibilities;
356 }
357
358 /**
359 * @return the dependencies
360 */
361 public HashSet<Integer> getDependencies() {
362 return dependencies;
363 }
364
365 /**
366 * @return the levels this mod will unlock
367 */
368 public HashSet<Integer> getUnlockLevels() {
369 return unlockLevel;
370 }
371
372 /**
373 * @return Executable name of this tool
374 */
375 public File getExeFile() {
376 return exeFile;
377 }
378 /**
379 * @return Icon file of this tool
380 */
381 public File getIconFile() {
382 return iconFile;
383 }
384
385 /**
386 * @return Working directory of this tool
387 */
388 public File getWorkingDir() {
389 if (workingDir.equalsIgnoreCase("Exe")) {
390 if (exeFile != null)
391 return exeFile.getParentFile();
392 else
393 return Paths.getEditionGDF();
394 } else if (workingDir.equalsIgnoreCase("GDF"))
395 return Paths.getEditionGDF();
396 else
397 return Paths.getEditionBasePath();
398 }
399
400 /**
401 * @return Is this mod valid on the running platform?
402 */
403 public boolean isValidOnPlatform() {
404 switch (platform) {
405 case BOTH:
406 return true;
407 case MACOS:
408 return (Settings.getPlatform() == Platform.MACOS);
409 case WIN:
410 return (Settings.getPlatform() == Platform.WIN)
411 || (Settings.getPlatform() == Platform.LINUX);
412 }
413 return false;
414 }
415
416 @Override
417 public int compareTo(Mod o) {
418 return getPackageNumber() - o.getPackageNumber();
419 }
420}
Note: See TracBrowser for help on using the repository browser.