PageRenderTime 61ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/yifanlu/PSXperiaTool/Interface/CommandLine.java

https://github.com/BoTToEsP/PSXperia
Java | 262 lines | 222 code | 23 blank | 17 comment | 45 complexity | 60cbe696c438e3c413ca62f380fe248b MD5 | raw file
  1. /*
  2. * PSXperia Converter Tool - Logging
  3. * Copyright (C) 2011 Yifan Lu (http://yifan.lu/)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. package com.yifanlu.PSXperiaTool.Interface;
  19. import com.android.sdklib.internal.build.SignedJarBuilder;
  20. import com.yifanlu.PSXperiaTool.Extractor.CrashBandicootExtractor;
  21. import com.yifanlu.PSXperiaTool.Logger;
  22. import com.yifanlu.PSXperiaTool.PSImageExtract;
  23. import com.yifanlu.PSXperiaTool.PSXperiaTool;
  24. import java.io.File;
  25. import java.io.FileInputStream;
  26. import java.io.FileOutputStream;
  27. import java.io.IOException;
  28. import java.security.GeneralSecurityException;
  29. import java.util.Arrays;
  30. import java.util.InputMismatchException;
  31. import java.util.Properties;
  32. import java.util.Stack;
  33. import java.util.regex.Matcher;
  34. import java.util.regex.Pattern;
  35. import java.util.zip.DataFormatException;
  36. public class CommandLine {
  37. private static class InvalidArgumentException extends Exception {
  38. private String mMessage;
  39. public InvalidArgumentException(String message) {
  40. this.mMessage = message;
  41. }
  42. public String getMessage() {
  43. return this.mMessage;
  44. }
  45. }
  46. public static void verifyTitleID(String toVerify) throws InputMismatchException {
  47. Pattern pattern = Pattern.compile("^[A-Za-z0-9_]+$");
  48. Matcher matcher = pattern.matcher(toVerify);
  49. if (!matcher.find())
  50. throw new InputMismatchException("Title ID can only contain alphanumberic characters and underscores.");
  51. }
  52. public static void main(String[] args) {
  53. Logger.setLevel(Logger.DEBUG);
  54. if (args.length < 1)
  55. printHelp();
  56. String toDo = args[0];
  57. try {
  58. if (toDo.equals("extract") || toDo.equals("x"))
  59. doExtractData(args);
  60. if (toDo.equals("convert") || toDo.equals("c"))
  61. doConvertImage(args);
  62. if (toDo.equals("decompress") || toDo.equals("d"))
  63. doDecompressImage(args);
  64. } catch (InputMismatchException ex) {
  65. Logger.error("Input error: %s", ex.getMessage());
  66. ex.printStackTrace();
  67. } catch (InvalidArgumentException ex) {
  68. Logger.error("Invalid argument: %s", ex.getMessage());
  69. printHelp();
  70. } catch (IOException ex) {
  71. Logger.error("IO error, Java says: %s", ex.getMessage());
  72. ex.printStackTrace();
  73. } catch (InterruptedException ex) {
  74. Logger.error("Process exec Error, Java says: %s", ex.getMessage());
  75. ex.printStackTrace();
  76. } catch (DataFormatException ex) {
  77. Logger.error("Data format error, Java says: %s", ex.getMessage());
  78. ex.printStackTrace();
  79. } catch (GeneralSecurityException ex) {
  80. Logger.error("Error signing JAR, Java says: %s", ex.getMessage());
  81. ex.printStackTrace();
  82. } catch (SignedJarBuilder.IZipEntryFilter.ZipAbortException ex) {
  83. Logger.error("Error signing JAR, Java says: %s", ex.getMessage());
  84. ex.printStackTrace();
  85. } catch (UnsupportedOperationException ex) {
  86. Logger.error("Unsupported exception: %s", ex.getMessage());
  87. ex.printStackTrace();
  88. }
  89. }
  90. public static void doExtractData(String[] args) throws InvalidArgumentException, IOException {
  91. if (args.length < 4)
  92. throw new InvalidArgumentException("Not enough input.");
  93. Stack<String> stack = new Stack<String>();
  94. stack.addAll(Arrays.asList(args));
  95. File outputDir = new File(stack.pop());
  96. File inputZpak = new File(stack.pop());
  97. File inputApk = new File(stack.pop());
  98. while (!stack.empty()) {
  99. String argument = stack.pop();
  100. if (argument.startsWith("-")) {
  101. if (argument.equals("-v") || argument.equalsIgnoreCase("--verbose")) {
  102. Logger.setLevel(Logger.ALL);
  103. continue;
  104. }
  105. Logger.warning("Unknown option %s", argument);
  106. }
  107. }
  108. (new CrashBandicootExtractor(inputApk, inputZpak, outputDir)).extractApk();
  109. System.exit(0);
  110. }
  111. public static void doConvertImage(String[] args) throws InvalidArgumentException, IOException, InterruptedException, GeneralSecurityException, SignedJarBuilder.IZipEntryFilter.ZipAbortException {
  112. if (args.length < 3)
  113. throw new InvalidArgumentException("Not enough input.");
  114. Stack<String> stack = new Stack<String>();
  115. stack.addAll(Arrays.asList(args));
  116. File outputDir = new File(stack.pop());
  117. File inputFile = new File(stack.pop());
  118. String titleId = stack.pop();
  119. Properties settings = new Properties();
  120. settings.loadFromXML(PSXperiaTool.class.getResourceAsStream("/resources/defaults.xml"));
  121. settings.put("KEY_TITLE_ID", titleId);
  122. File currentDir = new File(".");
  123. File dataDir = new File(currentDir, "/data");
  124. Stack<String> stringList = new Stack<String>();
  125. while (!stack.empty()) {
  126. String argument = stack.pop();
  127. if (argument.startsWith("-")) {
  128. if (argument.equals("-v") || argument.equalsIgnoreCase("--verbose")) {
  129. Logger.setLevel(Logger.ALL);
  130. continue;
  131. } else if (argument.equals("-D")) {
  132. dataDir = new File(stringList.pop());
  133. stringList.empty();
  134. } else if (argument.equals("--load-xml")) {
  135. File xml = new File(stringList.pop());
  136. settings.loadFromXML(new FileInputStream(xml));
  137. stringList.empty();
  138. } else if (argument.equals("--game-name")) {
  139. String name = stackToString(stringList);
  140. settings.put("KEY_DISPLAY_NAME", name);
  141. settings.put("KEY_TITLE", name);
  142. } else if (argument.equals("--description")) {
  143. settings.put("KEY_DESCRIPTION", stackToString(stringList));
  144. } else if (argument.equals("--publisher")) {
  145. settings.put("KEY_PUBLISHER", stackToString(stringList));
  146. } else if (argument.equals("--developer")) {
  147. settings.put("KEY_DEVELOPER", stackToString(stringList));
  148. } else if (argument.equals("--icon-file")) {
  149. settings.put("IconFile", new File(stringList.pop()));
  150. stringList.empty();
  151. } else if (argument.equals("--store-type")) {
  152. settings.put("KEY_STORE_TYPE", stackToString(stringList));
  153. } else if (argument.equals("--analog-mode")) {
  154. String str = stringList.pop();
  155. if (str.equals("true"))
  156. settings.put("KEY_ANALOG_MODE", "YES");
  157. stringList.empty();
  158. } else {
  159. stringList.push(argument);
  160. }
  161. } else {
  162. stringList.push(argument);
  163. }
  164. }
  165. verifyTitleID(titleId);
  166. PSXperiaTool tool = new PSXperiaTool(settings, inputFile, dataDir, outputDir);
  167. tool.startBuild();
  168. System.exit(0);
  169. }
  170. private static String stackToString(Stack<String> stack) {
  171. String str = "";
  172. while (!stack.isEmpty()) {
  173. str += stack.pop() + " ";
  174. }
  175. str = str.replaceAll("^\"", "");
  176. str = str.replaceAll("\"$", "");
  177. return str;
  178. }
  179. public static void doDecompressImage(String[] args) throws InvalidArgumentException, IOException, DataFormatException {
  180. if (args.length < 3)
  181. throw new InvalidArgumentException("Not enough input.");
  182. Stack<String> stack = new Stack<String>();
  183. stack.addAll(Arrays.asList(args));
  184. File outputFile = new File(stack.pop());
  185. File inputFile = new File(stack.pop());
  186. while (!stack.empty()) {
  187. String argument = stack.pop();
  188. if (argument.startsWith("-")) {
  189. if (argument.equals("-v") || argument.equalsIgnoreCase("--verbose")) {
  190. Logger.setLevel(Logger.ALL);
  191. continue;
  192. }
  193. Logger.warning("Unknown option %s", argument);
  194. }
  195. }
  196. FileInputStream in = new FileInputStream(inputFile);
  197. FileOutputStream out = new FileOutputStream(outputFile);
  198. PSImageExtract extract = new PSImageExtract(in);
  199. extract.uncompress(out);
  200. out.close();
  201. in.close();
  202. System.exit(0);
  203. }
  204. public static void printHelp() {
  205. System.out.println("PSXPeria Converter Tool");
  206. System.out.println("");
  207. System.out.println("Usage:");
  208. System.out.println(" Extract and patch data files");
  209. System.out.println(" psxperia e[x]tract [-v|--verbose] input.apk input-data.zpak output");
  210. System.out.println(" [-v|--verbose] Verbose output");
  211. System.out.println(" input.apk Either com.sony.playstation.ncua94900_1.apk or com.sony.playstation.ncea00344_1.apk");
  212. System.out.println(" input-data.zpak Either NCUA94900_1_1.zpak or NCEA00344_1_1.zpak (must match region of APK)");
  213. System.out.println(" output Directory to extract the files");
  214. System.out.println("");
  215. System.out.println(" Convert ISO to Xperia Play APK and ZPAK");
  216. System.out.println(" psxperia [c]onvert [OPTIONS] titleId image.iso output");
  217. System.out.println(" titleId An unique ID, usually from the game in the format NCXAXXXXX_1");
  218. System.out.println(" image.iso Input PSX image. You must rip it on your own!");
  219. System.out.println(" output Directory to output files");
  220. System.out.println(" Options (unset options will be set to defaults):");
  221. System.out.println(" -v|--verbose Verbose output, including image creation progress");
  222. System.out.println(" -D directory Custom location for extracted data files, default is \"./data\"");
  223. System.out.println(" --load-xml Load options from Java properties XML");
  224. System.out.println(" --game-name Name of the game");
  225. System.out.println(" --description Description of the game");
  226. System.out.println(" --publisher Publisher of the game");
  227. System.out.println(" --developer Developer of the game");
  228. System.out.println(" --icon-file Path to image for icon");
  229. System.out.println(" --store-type Where to find this title (any string will do)");
  230. System.out.println(" --analog-mode true|false, Turn on/off analog controls (game must support it).");
  231. System.out.println("");
  232. System.out.println(" Convert image.ps to ISO");
  233. System.out.println(" psxperia [d]ecompress [-v|--verbose] input.ps output.iso");
  234. System.out.println(" [-v|--verbose] Verbose output");
  235. System.out.println(" input.ps image.ps from ZPAK");
  236. System.out.println(" output.iso ISO file to generate");
  237. System.exit(0);
  238. }
  239. }