package gtPlusPlus; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; import gtPlusPlus.api.objects.random.XSTR; public class GenerateDictionaries { public static void main(String[] args) { File aMainDictionary = new File("proguard/DictionaryMain.txt"); File aMethodDict = new File("proguard/method-dict.txt"); File aClassDict = new File("proguard/class-dict.txt"); if (Utils.doesFileExist(aMainDictionary)) { Utils.log("Found Main Dictionary"); List aLines = Utils.readLines(aMainDictionary); ArrayList aLinesToWriteMethods = new ArrayList(); ArrayList aLinesToWriteClasses = new ArrayList(); if (aLines != null && aLines.size() > 0) { Utils.log("Main Dictionary has > 0 keywords (" + aLines.size() + ")"); HashSet aUsedIndicies = new HashSet(); int aCount = aLines.size() / 5; Utils.log("Mapping " + aCount + " to each dict."); // Map New Method Names for (int i = 0; aLinesToWriteMethods.size() < aCount; i++) { Integer aIndex = Utils.randInt(0, aLines.size() - 1); if (!aUsedIndicies.contains(aIndex)) { String aLineAtIndex = aLines.get(aIndex); if (aLineAtIndex != null && aLineAtIndex.length() > 0) { aLinesToWriteMethods.add(aLineAtIndex); aUsedIndicies.add(aIndex); } } if (i >= aCount * 5) { break; } } // Map New Class Names for (int i = 0; aLinesToWriteClasses.size() < aCount; i++) { Integer aIndex = Utils.randInt(0, aLines.size() - 1); if (!aUsedIndicies.contains(aIndex)) { String aLineAtIndex = aLines.get(aIndex); if (aLineAtIndex != null && aLineAtIndex.length() > 0) { aLinesToWriteClasses.add(aLineAtIndex); aUsedIndicies.add(aIndex); } } if (i >= aCount * 5) { break; } } } // Remove old generated Dicts if (Utils.doesFileExist(aMethodDict)) { aMethodDict.delete(); Utils.log("Removed old Method-Dict"); } if (Utils.doesFileExist(aClassDict)) { aClassDict.delete(); Utils.log("Removed old Class-Dict"); } // Create new empty dict files if (!Utils.doesFileExist(aMethodDict)) { Utils.createFile(aMethodDict); } if (!Utils.doesFileExist(aClassDict)) { Utils.createFile(aClassDict); } Utils.log("Writing new Dictionaries."); // Write Utils.appendListToFile(aMethodDict, aLinesToWriteMethods); Utils.appendListToFile(aClassDict, aLinesToWriteClasses); Utils.log("Finished all generation of new Dictionaries."); } } private static final class Utils { private static final Charset utf8 = StandardCharsets.UTF_8; private static final Random rand = new XSTR(); private static final void log(String s) { System.out.println("[GTPP-Proguard] " + s); } public static int randInt(final int min, final int max) { return rand.nextInt((max - min) + 1) + min; } public static boolean doesFileExist(File f) { if (f != null && f.exists() && !f.isDirectory()) { return true; } return false; } public static File createFile(File aFile) { boolean blnCreated = false; log("Trying to use relative path " + aFile.getPath()); try { // log("Trying to use path "+aFile.getCanonicalPath()); // log("Trying to use absolute path "+aFile.getAbsolutePath()); blnCreated = aFile.createNewFile(); } catch (IOException ioe) { log("Error while creating a new empty file :" + ioe); return null; } return blnCreated ? aFile : null; } public static boolean appendListToFile(File file, List content) { try { long oldSize; long newSize; if (doesFileExist(file)) { Path p = Paths.get(file.getPath()); if (p != null && Files.isWritable(p)) { oldSize = Files.size(p); try { Files.write(p, content, utf8, StandardOpenOption.APPEND); } catch (IOException e) { e.printStackTrace(); } newSize = Files.size(p); return newSize > oldSize; } } } catch (IOException e) {} return false; } /** * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM. The * file is always closed. * * @param file the file to read, must not be {@code null} * @return the list of Strings representing each line in the file, never {@code null} * @throws IOException in case of an I/O error * @since 1.3 */ public static List readLines(File file) { try { return org.apache.commons.io.FileUtils.readLines(file, utf8); } catch (IOException e) { return new ArrayList(); } } } }