package net.oni2.aeinstaller.backend.packages; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; import net.oni2.aeinstaller.backend.CaseInsensitiveFile; import net.oni2.aeinstaller.backend.Paths; import net.oni2.aeinstaller.backend.oni.management.tools.ToolInstallationList; import net.oni2.moddepot.DepotConfig; import net.oni2.moddepot.ECompatiblePlatform; import net.oni2.moddepot.model.NodeMod; import net.oni2.platformtools.PlatformInformation; import net.oni2.platformtools.PlatformInformation.Platform; import net.oni2.platformtools.applicationinvoker.EExeType; import org.apache.commons.io.FileUtils; /** * @author Christian Illy */ public class Package implements Comparable { private String name = ""; private int packageNumber = 0; private HashSet types = new HashSet(); private boolean tool = false; private ECompatiblePlatform platform = null; private String version = ""; private String submitter = ""; private String creator = ""; private transient EBSLInstallType bslInstallType = EBSLInstallType.NORMAL; private String description = ""; private transient double aeVersion = 0; private int zipSize = 0; private URI nodeUrl = null; private String fileUrl = null; private long createdMillis = -1; private long updatedMillis = -1; private transient File exeFile = null; private transient EExeType exeType = EExeType.OSBINARY; private transient File iconFile = null; private transient String workingDir = "Base"; private transient HashSet incompatibilities = new HashSet(); private transient HashSet dependencies = new HashSet(); private transient HashSet unlockLevel = new HashSet(); private transient long localTimestamp = 0; /** * Create a new Package entry from a given Mod-Node * * @param nm * Mod-Node */ public Package(NodeMod nm) { name = nm.getTitle(); packageNumber = nm.getPackageNumber(); platform = nm.getPlatform(); tool = nm.isTool(); for (String nType : nm.getTypes()) { Type t = PackageManager.getInstance().getTypeByName(nType); types.add(t); if (!tool && !isCorePackage() && isValidOnPlatform()) t.addEntry(this); } createdMillis = nm.getCreated(); updatedMillis = nm.getUploads().firstElement().getTimestamp(); try { nodeUrl = new URI(nm.getPath()); } catch (URISyntaxException e) { e.printStackTrace(); } fileUrl = nm.getUploads().firstElement().getUri_full(); zipSize = nm.getUploads().firstElement().getFilesize(); version = nm.getVersion(); submitter = nm.getName(); creator = nm.getCreator(); if (nm.getBody() != null) { description = nm.getBody().getSafe_value(); if (!description.toLowerCase().startsWith("

")) description = "

" + description + "

"; } if (isLocalAvailable()) updateLocalData(); } private void clearLocalOnlyInfo() { aeVersion = 0; bslInstallType = EBSLInstallType.NORMAL; dependencies = new HashSet(); incompatibilities = new HashSet(); unlockLevel = new HashSet(); exeFile = null; workingDir = null; iconFile = null; } /** * Update information for local package existence */ public void updateLocalData() { File config = CaseInsensitiveFile.getCaseInsensitiveFile( getLocalPath(), "Mod_Info.cfg"); File aeicfg = new File(getLocalPath(), "aei.cfg"); // File plain = CaseInsensitiveFile.getCaseInsensitiveFile(getLocalPath(), // "plain"); if (config.exists()) { Mod_Info mi = new Mod_Info(config, packageNumber); aeVersion = mi.getAeVersion(); bslInstallType = mi.getBslInstallType(); if (isLocalOnly()) { name = mi.getName(); creator = mi.getCreator(); version = mi.getVersion(); description = mi.getDescription(); } dependencies = mi.getDependencies(); incompatibilities = mi.getIncompatibilities(); unlockLevel = mi.getUnlockLevel(); exeFile = mi.getExeFile(); exeType = mi.getExeType(); workingDir = mi.getWorkingDir(); iconFile = mi.getIconFile(); } else { clearLocalOnlyInfo(); // System.err.println("No config found for mod folder: " // + getLocalPath().getPath()); } if (aeicfg.exists()) { try { FileInputStream fstream = new FileInputStream(aeicfg); InputStreamReader isr = new InputStreamReader(fstream); BufferedReader br = new BufferedReader(isr); String strLine; while ((strLine = br.readLine()) != null) { if (strLine.indexOf("->") < 1) continue; if (strLine.indexOf("//") >= 0) strLine = strLine.substring(0, strLine.indexOf("//")); String[] split = strLine.split("->", 2); String sName = split[0].trim(); String sVal = split[1].trim(); if (sName.equalsIgnoreCase("Timestamp")) { localTimestamp = Long.parseLong(sVal); } } isr.close(); } catch (FileNotFoundException e) { } catch (IOException e) { e.printStackTrace(); } } if (isLocalOnly()) { tool = packageNumber < 10000; } } /** * Create a new Mod entry from the given local mod folder * * @param folder * Mod folder with Mod_Info.cfg */ public Package(File folder) { packageNumber = Integer.parseInt(folder.getName().substring(0, 5)); updateLocalData(); platform = ECompatiblePlatform.BOTH; } /** * @return has separate paths for win/mac/common or not */ public boolean hasSeparatePlatformDirs() { return aeVersion >= 2; } private String getSanitizedPathName() { return name.replaceAll("[^a-zA-Z0-9_.-]", "_"); } /** * @return Path to local mod folder */ public File getLocalPath() { final String folderStart = String.format("%05d", packageNumber); if (Paths.getModsPath().exists()) { for (File f : Paths.getModsPath().listFiles(new FilenameFilter() { @Override public boolean accept(File d, String fn) { return fn.startsWith(folderStart); } })) { return f; } } return new File(Paths.getModsPath(), folderStart + getSanitizedPathName()); } /** * @return Is there a newer version on the depot? */ public boolean isNewerAvailable() { if (!isLocalOnly()) return updatedMillis > localTimestamp; else return false; } /** * @return Mod exists within mods folder */ public boolean isLocalAvailable() { return getLocalPath().exists(); } /** * @return If this mod is only locally available (not on Depot) */ public boolean isLocalOnly() { return nodeUrl == null; } /** * @return Is mod installed? */ public boolean isInstalled() { if (tool) return ToolInstallationList.getInstance() .isInstalled(packageNumber); else return PackageManager.getInstance().isModInstalled(this); } /** * @return Name of mod */ public String getName() { return name; } /** * @return the package number */ public int getPackageNumber() { return packageNumber; } /** * @return the package number as 5 digit string */ public String getPackageNumberString() { return String.format("%05d", packageNumber); } /** * @return Types of mod */ public HashSet getTypes() { return types; } /** * @return Is this mod actually a tool? */ public boolean isTool() { return tool; } /** * @return Compatible platforms */ public ECompatiblePlatform getPlatform() { return platform; } /** * @return Version of mod */ public String getVersion() { return version; } /** * @return Submitter of mod */ public String getSubmitter() { return submitter; } /** * @return Creator of mod */ public String getCreator() { return creator; } /** * @return Installation type of BSL files */ public EBSLInstallType getBSLInstallType() { return bslInstallType; } /** * @return Description of mod */ public String getDescription() { return description; } /** * @return Size of Zip file on Depot */ public int getZipSize() { return zipSize; } /** * @return the createdMillis */ public long getCreatedMillis() { return createdMillis; } /** * @return the updatedMillis */ public long getUpdatedMillis() { return updatedMillis; } /** * @return the fileUrl */ public String getFileUrl() { return fileUrl; } /** * @return Is a package that is always installed? */ public boolean isCorePackage() { return packageNumber < DepotConfig.corePackageNumberLimit; } /** * @return Depot page URI */ public URI getUrl() { return nodeUrl; } @Override public String toString() { return name; } /** * @return the incompabitilities */ public HashSet getIncompabitilities() { return incompatibilities; } /** * @return the dependencies */ public HashSet getDependencies() { return dependencies; } /** * @return the levels this mod will unlock */ public HashSet getUnlockLevels() { return unlockLevel; } /** * @return Executable name of this tool */ public File getExeFile() { return exeFile; } /** * @return Executable type of this tool */ public EExeType getExeType() { return exeType; } /** * @return Icon file of this tool */ public File getIconFile() { return iconFile; } /** * @return Working directory of this tool */ public File getWorkingDir() { if (workingDir.equalsIgnoreCase("Exe")) { if (exeFile != null) return exeFile.getParentFile(); else return Paths.getEditionGDF(); } else if (workingDir.equalsIgnoreCase("GDF")) return Paths.getEditionGDF(); else return Paths.getEditionBasePath(); } /** * @return Is this mod valid on the running platform? */ public boolean isValidOnPlatform() { switch (platform) { case BOTH: return true; case MACOS: return (PlatformInformation.getPlatform() == Platform.MACOS); case WIN: return (PlatformInformation.getPlatform() == Platform.WIN) || (PlatformInformation.getPlatform() == Platform.LINUX); } return false; } /** * Delete the local package folder */ public void deleteLocalPackage() { if (getLocalPath().exists()) { try { FileUtils.deleteDirectory(getLocalPath()); updateLocalData(); } catch (IOException e) { e.printStackTrace(); } } } @Override public int compareTo(Package o) { return getPackageNumber() - o.getPackageNumber(); } }