diff --git a/src/com/jpexs/decompiler/flash/SWFInputStream.java b/src/com/jpexs/decompiler/flash/SWFInputStream.java index 1cc9ab493..5a1826177 100644 --- a/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -321,7 +321,7 @@ public class SWFInputStream implements AutoCloseable { } } } - + public void setPercentMax(long percentMax) { this.percentMax = percentMax; } @@ -403,7 +403,7 @@ public class SWFInputStream implements AutoCloseable { dumpInfo = dumpInfo.parent; } } - + private void endDumpLevelUntil(DumpInfo di) { if (di != null) { while (dumpInfo != null && dumpInfo != di) { @@ -706,7 +706,7 @@ public class SWFInputStream implements AutoCloseable { if (count <= 0) { return new byte[0]; } - + informListeners(); bitPos = 0; byte[] ret = new byte[(int) count]; @@ -980,7 +980,7 @@ public class SWFInputStream implements AutoCloseable { DumpInfo di = dumpInfo; try { Tag t = resolveTag(tag, level, parallel, skipUnusualTags, gfx); - if (dumpInfo!= null && t != null) { + if (dumpInfo != null && t != null) { dumpInfo.name = t.getName(); } return t; @@ -1436,7 +1436,7 @@ public class SWFInputStream implements AutoCloseable { if (tagLength > available) { tagLength = available; } - + ByteArrayRange dataRange = new ByteArrayRange(swf.uncompressedData, (int) pos, (int) (tagLength + headerLength)); TagStub tagStub = new TagStub(swf, tagID, "Unresolved", dataRange, tagDataStream); tagStub.forceWriteAsLong = readLong; diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java b/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java index d031b936f..98b23e67c 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java @@ -257,8 +257,8 @@ public class ConstantPool { } } return m; - } } + } return 0; } diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java b/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java index 27756f7a9..101f3dc38 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopIns.java @@ -44,11 +44,11 @@ public class PopIns extends InstructionDefinition { @Override public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, Stack stack, Stack scopeStack, ConstantPool constants, AVM2Instruction ins, List method_info, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code) { if (stack.size() > 0) { - GraphTargetItem top = stack.pop(); + GraphTargetItem top = stack.pop(); //Note: Commands like "5;" - numbers are unsupported as it collide with try..finally block decompilation. TODO: allow this somehow - if(!(top instanceof IntegerValueAVM2Item)){ + if (!(top instanceof IntegerValueAVM2Item)) { output.add(top); - } + } } } diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java index 4fbda5e13..5496fadd8 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java @@ -66,7 +66,7 @@ public class NewFunctionAVM2Item extends AVM2Item { methodInfo.get(methodIndex).getParamStr(writer, constants, body, abc, fullyQualifiedNames); writer.appendNoHilight("):"); methodInfo.get(methodIndex).getReturnTypeStr(writer, constants, fullyQualifiedNames); - writer.endMethod(); + writer.endMethod(); writer.startBlock(); if (body != null) { if (writer instanceof NulWriter) { diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/model/NewObjectAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/model/NewObjectAVM2Item.java index 2eac81abd..6846b1a3e 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/model/NewObjectAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/model/NewObjectAVM2Item.java @@ -1,86 +1,86 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.abc.avm2.model; - -import com.jpexs.decompiler.flash.SourceGeneratorLocalData; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.GraphSourceItem; -import com.jpexs.decompiler.graph.GraphTargetItem; -import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.LocalData; -import java.util.ArrayList; -import java.util.List; - -public class NewObjectAVM2Item extends AVM2Item { - - public List pairs; - - public NewObjectAVM2Item(AVM2Instruction instruction, List pairs) { - super(instruction, PRECEDENCE_PRIMARY); - this.pairs = pairs; - } - - @Override - public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - boolean singleLine = pairs.size() < 2; - //no new line before as it may break return clause (#593) - writer.append("{"); - if (!singleLine) { - writer.newLine(); - writer.indent(); - } - for (int n = 0; n < pairs.size(); n++) { - if (n > 0) { - writer.append(",").newLine(); - } - pairs.get(n).toString(writer, localData); - } - if (!singleLine) { - writer.newLine(); - writer.unindent(); - } - writer.append("}"); - return writer; - } - - @Override - public GraphTargetItem returnType() { - return new TypeItem("Object"); - } - - @Override - public boolean hasReturnValue() { - return true; - } - - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - List args = new ArrayList<>(); - for (NameValuePair p : pairs) { - args.add(p.name); - args.add(p.value); - } - return toSourceMerge(localData, generator, args, - new AVM2Instruction(0, new NewObjectIns(), new int[]{pairs.size()}, new byte[0]) - ); - } - -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.abc.avm2.model; + +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.decompiler.graph.model.LocalData; +import java.util.ArrayList; +import java.util.List; + +public class NewObjectAVM2Item extends AVM2Item { + + public List pairs; + + public NewObjectAVM2Item(AVM2Instruction instruction, List pairs) { + super(instruction, PRECEDENCE_PRIMARY); + this.pairs = pairs; + } + + @Override + public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + boolean singleLine = pairs.size() < 2; + //no new line before as it may break return clause (#593) + writer.append("{"); + if (!singleLine) { + writer.newLine(); + writer.indent(); + } + for (int n = 0; n < pairs.size(); n++) { + if (n > 0) { + writer.append(",").newLine(); + } + pairs.get(n).toString(writer, localData); + } + if (!singleLine) { + writer.newLine(); + writer.unindent(); + } + writer.append("}"); + return writer; + } + + @Override + public GraphTargetItem returnType() { + return new TypeItem("Object"); + } + + @Override + public boolean hasReturnValue() { + return true; + } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + List args = new ArrayList<>(); + for (NameValuePair p : pairs) { + args.add(p.name); + args.add(p.value); + } + return toSourceMerge(localData, generator, args, + new AVM2Instruction(0, new NewObjectIns(), new int[]{pairs.size()}, new byte[0]) + ); + } + +} diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/model/WithAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/model/WithAVM2Item.java index 6c92fabcb..70a8e0202 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/model/WithAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/model/WithAVM2Item.java @@ -58,7 +58,7 @@ public class WithAVM2Item extends AVM2Item { scope.toString(writer, localData); writer.append(")").startBlock(); //NOTE: endBlock is added with WithEndAVM2Item - return writer; + return writer; } @Override diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/TryAVM2Item.java b/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/TryAVM2Item.java index 6354ba810..132db2853 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/TryAVM2Item.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/TryAVM2Item.java @@ -66,12 +66,12 @@ public class TryAVM2Item extends AVM2Item implements Block { @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { - writer.append("try").startBlock(); + writer.append("try").startBlock(); for (GraphTargetItem ti : tryCommands) { if (!ti.isEmpty()) { ti.toStringSemicoloned(writer, localData).newLine(); } - } + } writer.endBlock(); for (int e = 0; e < catchExceptions.size(); e++) { writer.newLine(); diff --git a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 2db032f06..d93577fdc 100644 --- a/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -2032,7 +2032,7 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } TraitMethodGetterSetter tmgs = new TraitMethodGetterSetter(); - tmgs.kindType = (item instanceof GetterAVM2Item)?Trait.TRAIT_GETTER:((item instanceof SetterAVM2Item) ? Trait.TRAIT_SETTER : Trait.TRAIT_METHOD); + tmgs.kindType = (item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : ((item instanceof SetterAVM2Item) ? Trait.TRAIT_SETTER : Trait.TRAIT_METHOD); //tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); tmgs.disp_id = mai.isStatic() ? disp_id++ : 0; //For a reason, there is disp_id only for static methods (or not?) if (mai.isFinal() || mai.isStatic()) { diff --git a/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java b/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java index b08c28ac1..f9ff43a88 100644 --- a/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java +++ b/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java @@ -99,7 +99,7 @@ public class TraitMethodGetterSetter extends Trait { writer.startBlock(); if (bodyIndex != -1) { abc.bodies.get(bodyIndex).toString(path, exportMode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new Stack(), false, writer, fullyQualifiedNames, null); - } + } writer.endBlock(); } writer.newLine(); diff --git a/src/com/jpexs/decompiler/flash/action/Action.java b/src/com/jpexs/decompiler/flash/action/Action.java index da60374d1..4762d92a6 100644 --- a/src/com/jpexs/decompiler/flash/action/Action.java +++ b/src/com/jpexs/decompiler/flash/action/Action.java @@ -128,7 +128,6 @@ public class Action implements GraphSourceItem { return false; } - /** * Names of ActionScript properties */ diff --git a/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/src/com/jpexs/decompiler/flash/configuration/Configuration.java index ce6e9a49c..57aa2a581 100644 --- a/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -1,702 +1,702 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.configuration; - -import com.jpexs.decompiler.flash.ApplicationInfo; -import com.jpexs.decompiler.flash.helpers.CodeFormatting; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.utf8.Utf8InputStreamReader; -import com.jpexs.helpers.utf8.Utf8OutputStreamWriter; -import com.jpexs.proxy.Replacement; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.PrintWriter; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.swing.JOptionPane; - -public class Configuration { - - private static final String CONFIG_NAME = "config.bin"; - private static final String REPLACEMENTS_NAME = "replacements.cfg"; - private static final File unspecifiedFile = new File("unspecified"); - private static File directory = unspecifiedFile; - - /** - * List of replacements - */ - private static List replacements = new ArrayList<>(); - - public static final Level logLevel; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("ui") - public static final ConfigurationItem openMultipleFiles = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("script") - public static final ConfigurationItem decompile = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("decompilation") - public static final ConfigurationItem parallelSpeedUp = null; - - @ConfigurationDefaultInt(20) - @ConfigurationCategory("decompilation") - public static final ConfigurationItem parallelThreadCount = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("script") - public static final ConfigurationItem autoDeobfuscate = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("decompilation") - public static final ConfigurationItem cacheOnDisk = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("display") - public static final ConfigurationItem internalFlashViewer = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("display") - public static final ConfigurationItem dumpView = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("display") - public static final ConfigurationItem dumpInfoCollecting = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("ui") - public static final ConfigurationItem gotoMainClassOnStartup = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("script") - public static final ConfigurationItem autoRenameIdentifiers = null; - - @ConfigurationDefaultBoolean(false) - public static final ConfigurationItem offeredAssociation = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("script") - public static final ConfigurationItem decimalAddress = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("script") - public static final ConfigurationItem showAllAddresses = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("display") - public static final ConfigurationItem useFrameCache = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("ui") - public static final ConfigurationItem useRibbonInterface = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("export") - public static final ConfigurationItem openFolderAfterFlaExport = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("debug") - public static final ConfigurationItem useDetailedLogging = null; - - /** - * Debug mode = throwing an error when comparing original file and - * recompiled - */ - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("debug") - public static final ConfigurationItem debugMode = null; - /** - * Turn off resolving constants in ActionScript 2 - */ - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("script") - public static final ConfigurationItem resolveConstants = null; - /** - * Limit of code subs (for obfuscated code) - */ - @ConfigurationDefaultInt(500) - @ConfigurationCategory("limit") - public static final ConfigurationItem sublimiter = null; - /** - * Total export timeout in seconds - */ - @ConfigurationDefaultInt(30 * 60) - @ConfigurationCategory("limit") - public static final ConfigurationItem exportTimeout = null; - /** - * Decompilation timeout in seconds for a single file - */ - @ConfigurationDefaultInt(5 * 60) - @ConfigurationCategory("limit") - public static final ConfigurationItem decompilationTimeoutFile = null; - /** - * Using parameter names in decompiling may cause problems because official - * programs like Flash CS 5.5 inserts wrong parameter names indices - */ - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("script") - public static final ConfigurationItem paramNamesEnable = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("ui") - public static final ConfigurationItem displayFileName = null; - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("debug") - public static final ConfigurationItem debugCopy = null; - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("debug") - public static final ConfigurationItem dumpTags = null; - - @ConfigurationDefaultInt(60) - @ConfigurationCategory("limit") - public static final ConfigurationItem decompilationTimeoutSingleMethod = null; - @ConfigurationDefaultInt(1) - public static final ConfigurationItem lastRenameType = null; - - @ConfigurationDefaultString(".") - public static final ConfigurationItem lastSaveDir = null; - - @ConfigurationDefaultString(".") - public static final ConfigurationItem lastOpenDir = null; - - @ConfigurationDefaultString(".") - public static final ConfigurationItem lastExportDir = null; - - @ConfigurationDefaultString("en") - @ConfigurationCategory("ui") - public static final ConfigurationItem locale = null; - - @ConfigurationDefaultString("_loc%d_") - @ConfigurationCategory("script") - public static final ConfigurationItem registerNameFormat = null; - - @ConfigurationDefaultInt(10) - public static final ConfigurationItem maxRecentFileCount = null; - - public static final ConfigurationItem recentFiles = null; - - public static final ConfigurationItem fontPairing = null; - - public static final ConfigurationItem lastUpdatesCheckDate = null; - - @ConfigurationDefaultInt(1000) - @ConfigurationName("gui.window.width") - public static final ConfigurationItem guiWindowWidth = null; - @ConfigurationDefaultInt(700) - @ConfigurationName("gui.window.height") - public static final ConfigurationItem guiWindowHeight = null; - @ConfigurationDefaultBoolean(false) - @ConfigurationName("gui.window.maximized.horizontal") - public static final ConfigurationItem guiWindowMaximizedHorizontal = null; - @ConfigurationDefaultBoolean(false) - @ConfigurationName("gui.window.maximized.vertical") - public static final ConfigurationItem guiWindowMaximizedVertical = null; - @ConfigurationName("gui.avm2.splitPane.dividerLocation") - public static final ConfigurationItem guiAvm2SplitPaneDividerLocation = null; - @ConfigurationName("guiActionSplitPaneDividerLocation") - public static final ConfigurationItem guiActionSplitPaneDividerLocation = null; - @ConfigurationName("guiPreviewSplitPaneDividerLocation") - public static final ConfigurationItem guiPreviewSplitPaneDividerLocation = null; - @ConfigurationName("gui.splitPane1.dividerLocation") - public static final ConfigurationItem guiSplitPane1DividerLocation = null; - @ConfigurationName("gui.splitPane2.dividerLocation") - public static final ConfigurationItem guiSplitPane2DividerLocation = null; - @ConfigurationDefaultInt(3) - @ConfigurationCategory("export") - public static final ConfigurationItem saveAsExeScaleMode = null; - - @ConfigurationDefaultInt(1024 * 100/*100KB*/) - @ConfigurationCategory("limit") - public static final ConfigurationItem syntaxHighlightLimit = null; - public static final ConfigurationItem guiFontPreviewSampleText = null; - @ConfigurationName("gui.fontPreviewWindow.width") - public static final ConfigurationItem guiFontPreviewWidth = null; - @ConfigurationName("gui.fontPreviewWindow.height") - public static final ConfigurationItem guiFontPreviewHeight = null; - @ConfigurationName("gui.fontPreviewWindow.posX") - public static final ConfigurationItem guiFontPreviewPosX = null; - @ConfigurationName("gui.fontPreviewWindow.posY") - public static final ConfigurationItem guiFontPreviewPosY = null; - - @ConfigurationDefaultInt(3) - @ConfigurationName("formatting.indent.size") - @ConfigurationCategory("format") - public static final ConfigurationItem indentSize = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationName("formatting.indent.useTabs") - @ConfigurationCategory("format") - public static final ConfigurationItem indentUseTabs = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("format") - public static final ConfigurationItem beginBlockOnNewLine = null; - - @ConfigurationDefaultInt(1000 * 60 * 60 * 24) - @ConfigurationCategory("update") - @ConfigurationName("check.updates.delay") - public static final ConfigurationItem checkForUpdatesDelay = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("update") - @ConfigurationName("check.updates.stable") - public static final ConfigurationItem checkForUpdatesStable = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("update") - @ConfigurationName("check.updates.nightly") - public static final ConfigurationItem checkForUpdatesNightly = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("update") - @ConfigurationName("check.updates.enabled") - public static final ConfigurationItem checkForUpdatesAuto = null; - - @ConfigurationDefaultString("") - @ConfigurationName("export.formats") - public static final ConfigurationItem lastSelectedExportFormats = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("export") - public static final ConfigurationItem textExportSingleFile = null; - - @ConfigurationDefaultString("--- SEPARATOR ---") - @ConfigurationCategory("export") - public static final ConfigurationItem textExportSingleFileSeparator = null; - - @ConfigurationDefaultString("--- RECORDSEPARATOR ---") - @ConfigurationCategory("export") - public static final ConfigurationItem textExportSingleFileRecordSeparator = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationName("warning.experimental.as12edit") - @ConfigurationCategory("script") - public static final ConfigurationItem warningExperimentalAS12Edit = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationName("warning.experimental.as3edit") - @ConfigurationCategory("script") - public static final ConfigurationItem warningExperimentalAS3Edit = null; - - @ConfigurationDefaultBoolean(true) - @ConfigurationCategory("export") - public static final ConfigurationItem packJavaScripts = null; - - @ConfigurationDefaultBoolean(false) - @ConfigurationCategory("export") - public static final ConfigurationItem textExportExportFontFace = null; - - private enum OSId { - - WINDOWS, OSX, UNIX - } - - private static OSId getOSId() { - PrivilegedAction doGetOSName = new PrivilegedAction() { - @Override - public String run() { - return System.getProperty("os.name"); - } - }; - OSId id = OSId.UNIX; - String osName = AccessController.doPrivileged(doGetOSName); - if (osName != null) { - if (osName.toLowerCase().startsWith("mac os x")) { - id = OSId.OSX; - } else if (osName.contains("Windows")) { - id = OSId.WINDOWS; - } - } - return id; - } - - public static String getFFDecHome() { - if (directory == unspecifiedFile) { - directory = null; - String userHome = null; - try { - userHome = System.getProperty("user.home"); - } catch (SecurityException ignore) { - } - if (userHome != null) { - String applicationId = ApplicationInfo.SHORT_APPLICATION_NAME; - OSId osId = getOSId(); - if (osId == OSId.WINDOWS) { - File appDataDir = null; - try { - String appDataEV = System.getenv("APPDATA"); - if ((appDataEV != null) && (appDataEV.length() > 0)) { - appDataDir = new File(appDataEV); - } - } catch (SecurityException ignore) { - } - String vendorId = ApplicationInfo.VENDOR; - if ((appDataDir != null) && appDataDir.isDirectory()) { - // ${APPDATA}\{vendorId}\${applicationId} - String path = vendorId + "\\" + applicationId + "\\"; - directory = new File(appDataDir, path); - } else { - // ${userHome}\Application Data\${vendorId}\${applicationId} - String path = "Application Data\\" + vendorId + "\\" + applicationId + "\\"; - directory = new File(userHome, path); - } - } else if (osId == OSId.OSX) { - // ${userHome}/Library/Application Support/${applicationId} - String path = "Library/Application Support/" + applicationId + "/"; - directory = new File(userHome, path); - } else { - // ${userHome}/.${applicationId}/ - String path = "." + applicationId + "/"; - directory = new File(userHome, path); - } - } else { - //no home, then use application directory - directory = new File("."); - } - } - if (!directory.exists()) { - if (!directory.mkdirs()) { - if (!directory.exists()) { - directory = new File("."); //fallback to current directory - } - } - } - String ret = directory.getAbsolutePath(); - if (!ret.endsWith(File.separator)) { - ret += File.separator; - } - return ret; - } - - public static List getRecentFiles() { - String files = recentFiles.get(); - if (files == null || files.isEmpty()) { - return new ArrayList<>(); - } - return Arrays.asList(files.split("::")); - } - - public static void addRecentFile(String path) { - List recentFilesArray = new ArrayList<>(getRecentFiles()); - int idx = recentFilesArray.indexOf(path); - if (idx != -1) { - recentFilesArray.remove(idx); - } - recentFilesArray.add(path); - while (recentFilesArray.size() > maxRecentFileCount.get()) { - recentFilesArray.remove(0); - } - recentFiles.set(Helper.joinStrings(recentFilesArray, "::")); - } - - public static void removeRecentFile(String path) { - List recentFilesArray = new ArrayList<>(getRecentFiles()); - int idx = recentFilesArray.indexOf(path); - if (idx != -1) { - recentFilesArray.remove(idx); - } - recentFiles.set(Helper.joinStrings(recentFilesArray, "::")); - } - - public static Map getFontPairs() { - String fonts = fontPairing.get(); - if (fonts == null) { - return new HashMap<>(); - } - - Map result = new HashMap<>(); - for (String pair : fonts.split("::")) { - String[] splittedPair = pair.split("="); - result.put(splittedPair[0], splittedPair[1]); - } - return result; - } - - public static void addFontPair(String fileName, int fontId, String fontName, String systemFontName) { - String key = fileName + "_" + fontId + "_" + fontName; - Map fontPairs = getFontPairs(); - fontPairs.put(key, systemFontName); - fontPairs.put(fontName, systemFontName); - StringBuilder sb = new StringBuilder(); - int i = 0; - for (Entry pair : fontPairs.entrySet()) { - if (i != 0) { - sb.append("::"); - } - sb.append(pair.getKey()).append("=").append(pair.getValue()); - i++; - } - fontPairing.set(sb.toString()); - } - - /** - * Saves replacements to file for future use - */ - private static void saveReplacements(String replacementsFile) { - if (replacements.isEmpty()) { - File rf = new File(replacementsFile); - if (rf.exists()) { - if (!rf.delete()) { - Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Cannot delete replacements file"); - } - } - } else { - try (PrintWriter pw = new PrintWriter(new Utf8OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(replacementsFile))))) { - for (Replacement r : replacements) { - pw.println(r.urlPattern); - pw.println(r.targetFile); - } - } catch (IOException ex) { - Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Exception during saving replacements", ex); - } - } - } - - /** - * Load replacements from file - */ - private static void loadReplacements(String replacementsFile) { - if (!(new File(replacementsFile)).exists()) { - return; - } - replacements = new ArrayList<>(); - try (BufferedReader br = new BufferedReader(new Utf8InputStreamReader(new FileInputStream(replacementsFile)))) { - String s; - while ((s = br.readLine()) != null) { - Replacement r = new Replacement(s, br.readLine()); - replacements.add(r); - } - } catch (IOException e) { - //ignore - } - } - - private static String getReplacementsFile() throws IOException { - return getFFDecHome() + REPLACEMENTS_NAME; - } - - private static String getConfigFile() throws IOException { - return getFFDecHome() + CONFIG_NAME; - } - - private static HashMap loadFromFile(String file, String replacementsFile) { - HashMap config = new HashMap<>(); - try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) { - - @SuppressWarnings("unchecked") - HashMap cfg = (HashMap) ois.readObject(); - config = cfg; - } catch (ClassNotFoundException | IOException ex) { - //ignore - } - if (replacementsFile != null) { - loadReplacements(replacementsFile); - } - if (config.containsKey("paralelSpeedUp")) { - config.put("parallelSpeedUp", config.get("paralelSpeedUp")); - config.remove("paralelSpeedUp"); - } - return config; - } - - private static void saveToFile(String file, String replacementsFile) { - HashMap config = new HashMap<>(); - for (Entry entry : getConfigurationFields().entrySet()) { - try { - String name = entry.getKey(); - Field field = entry.getValue(); - ConfigurationItem item = (ConfigurationItem) field.get(null); - if (item.hasValue) { - config.put(name, item.get()); - } - } catch (IllegalArgumentException | IllegalAccessException ex) { - Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); - } - } - try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { - oos.writeObject(config); - } catch (IOException ex) { - //TODO: move this to GUI - JOptionPane.showMessageDialog(null, "Cannot save configuration.", "Error", JOptionPane.ERROR_MESSAGE); - Logger.getLogger(Configuration.class.getName()).severe("Configuration directory is read only."); - } - if (replacementsFile != null) { - saveReplacements(replacementsFile); - } - } - - public static List getReplacements() { - return replacements; - } - - public static void saveConfig() { - try { - saveToFile(getConfigFile(), getReplacementsFile()); - } catch (IOException ex) { - //ignore - } - } - - static { - setConfigurationFields(); - if (useDetailedLogging.get() || debugMode.get()) { - logLevel = Level.CONFIG; - } else { - logLevel = Level.WARNING; - } - int processorCount = Runtime.getRuntime().availableProcessors(); - if (parallelThreadCount.get() > processorCount) { - parallelThreadCount.set(processorCount); - } - - if (lastUpdatesCheckDate.get() == null) { - GregorianCalendar mingc = new GregorianCalendar(); - mingc.setTime(new Date(Long.MIN_VALUE)); - lastUpdatesCheckDate.set(mingc); - } - } - - @SuppressWarnings("unchecked") - public static void setConfigurationFields() { - try { - HashMap config = loadFromFile(getConfigFile(), getReplacementsFile()); - for (Entry entry : getConfigurationFields().entrySet()) { - String name = entry.getKey(); - Field field = entry.getValue(); - // remove final modifier from field - Field modifiersField = field.getClass().getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - - Object defaultValue = getDefaultValue(field); - Object value = null; - if (config.containsKey(name)) { - value = config.get(name); - } - - if (value != null) { - field.set(null, new ConfigurationItem(name, defaultValue, value)); - } else { - field.set(null, new ConfigurationItem(name, defaultValue)); - } - } - } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ex) { - // Reflection exceptions. This should never happen - throw new Error(ex.getMessage()); - } catch (IOException ex) { - Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); - } - } - - public static Object getDefaultValue(Field field) { - Object defaultValue = null; - ConfigurationDefaultBoolean aBool = field.getAnnotation(ConfigurationDefaultBoolean.class); - if (aBool != null) { - defaultValue = aBool.value(); - } - ConfigurationDefaultInt aInt = field.getAnnotation(ConfigurationDefaultInt.class); - if (aInt != null) { - defaultValue = aInt.value(); - } - ConfigurationDefaultString aString = field.getAnnotation(ConfigurationDefaultString.class); - if (aString != null) { - defaultValue = aString.value(); - } - return defaultValue; - } - - public static Map getConfigurationFields() { - Field[] fields = Configuration.class.getFields(); - Map result = new HashMap<>(); - for (Field field : fields) { - if (ConfigurationItem.class.isAssignableFrom(field.getType())) { - ConfigurationName annotation = field.getAnnotation(ConfigurationName.class); - String name = annotation == null ? field.getName() : annotation.value(); - result.put(name, field); - } - } - return result; - } - - public static CodeFormatting getCodeFormatting() { - CodeFormatting ret = new CodeFormatting(); - String indentString = ""; - for (int i = 0; i < indentSize.get(); i++) { - indentString += indentUseTabs.get() ? "\t" : " "; - } - ret.indentString = indentString; - ret.beginBlockOnNewLine = beginBlockOnNewLine.get(); - return ret; - } - - public static File getFlashLibPath() { - String home = getFFDecHome(); - File libsdir = new File(home + "flashlib"); - if (!libsdir.exists()) { - libsdir.mkdirs(); - } - return libsdir; - } - - public static File getPlayerSWC() { - File libsdir = getFlashLibPath(); - if (libsdir != null && libsdir.exists()) { - File libs[] = libsdir.listFiles(new FilenameFilter() { - - @Override - public boolean accept(File dir, String name) { - return name.toLowerCase().startsWith("playerglobal"); - } - }); - List libnames = new ArrayList<>(); - for (File f : libs) { - libnames.add(f.getName()); - } - Collections.sort(libnames); - if (!libnames.isEmpty()) { - return new File(libsdir.getAbsolutePath() + File.separator + libnames.get(libnames.size() - 1)); - } else { - return null; - } - } - - return null; - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.configuration; + +import com.jpexs.decompiler.flash.ApplicationInfo; +import com.jpexs.decompiler.flash.helpers.CodeFormatting; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.utf8.Utf8InputStreamReader; +import com.jpexs.helpers.utf8.Utf8OutputStreamWriter; +import com.jpexs.proxy.Replacement; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.PrintWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; + +public class Configuration { + + private static final String CONFIG_NAME = "config.bin"; + private static final String REPLACEMENTS_NAME = "replacements.cfg"; + private static final File unspecifiedFile = new File("unspecified"); + private static File directory = unspecifiedFile; + + /** + * List of replacements + */ + private static List replacements = new ArrayList<>(); + + public static final Level logLevel; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("ui") + public static final ConfigurationItem openMultipleFiles = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("script") + public static final ConfigurationItem decompile = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("decompilation") + public static final ConfigurationItem parallelSpeedUp = null; + + @ConfigurationDefaultInt(20) + @ConfigurationCategory("decompilation") + public static final ConfigurationItem parallelThreadCount = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem autoDeobfuscate = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("decompilation") + public static final ConfigurationItem cacheOnDisk = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("display") + public static final ConfigurationItem internalFlashViewer = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("display") + public static final ConfigurationItem dumpView = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("display") + public static final ConfigurationItem dumpInfoCollecting = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("ui") + public static final ConfigurationItem gotoMainClassOnStartup = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem autoRenameIdentifiers = null; + + @ConfigurationDefaultBoolean(false) + public static final ConfigurationItem offeredAssociation = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem decimalAddress = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem showAllAddresses = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("display") + public static final ConfigurationItem useFrameCache = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("ui") + public static final ConfigurationItem useRibbonInterface = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("export") + public static final ConfigurationItem openFolderAfterFlaExport = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("debug") + public static final ConfigurationItem useDetailedLogging = null; + + /** + * Debug mode = throwing an error when comparing original file and + * recompiled + */ + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("debug") + public static final ConfigurationItem debugMode = null; + /** + * Turn off resolving constants in ActionScript 2 + */ + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("script") + public static final ConfigurationItem resolveConstants = null; + /** + * Limit of code subs (for obfuscated code) + */ + @ConfigurationDefaultInt(500) + @ConfigurationCategory("limit") + public static final ConfigurationItem sublimiter = null; + /** + * Total export timeout in seconds + */ + @ConfigurationDefaultInt(30 * 60) + @ConfigurationCategory("limit") + public static final ConfigurationItem exportTimeout = null; + /** + * Decompilation timeout in seconds for a single file + */ + @ConfigurationDefaultInt(5 * 60) + @ConfigurationCategory("limit") + public static final ConfigurationItem decompilationTimeoutFile = null; + /** + * Using parameter names in decompiling may cause problems because official + * programs like Flash CS 5.5 inserts wrong parameter names indices + */ + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem paramNamesEnable = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("ui") + public static final ConfigurationItem displayFileName = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("debug") + public static final ConfigurationItem debugCopy = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("debug") + public static final ConfigurationItem dumpTags = null; + + @ConfigurationDefaultInt(60) + @ConfigurationCategory("limit") + public static final ConfigurationItem decompilationTimeoutSingleMethod = null; + @ConfigurationDefaultInt(1) + public static final ConfigurationItem lastRenameType = null; + + @ConfigurationDefaultString(".") + public static final ConfigurationItem lastSaveDir = null; + + @ConfigurationDefaultString(".") + public static final ConfigurationItem lastOpenDir = null; + + @ConfigurationDefaultString(".") + public static final ConfigurationItem lastExportDir = null; + + @ConfigurationDefaultString("en") + @ConfigurationCategory("ui") + public static final ConfigurationItem locale = null; + + @ConfigurationDefaultString("_loc%d_") + @ConfigurationCategory("script") + public static final ConfigurationItem registerNameFormat = null; + + @ConfigurationDefaultInt(10) + public static final ConfigurationItem maxRecentFileCount = null; + + public static final ConfigurationItem recentFiles = null; + + public static final ConfigurationItem fontPairing = null; + + public static final ConfigurationItem lastUpdatesCheckDate = null; + + @ConfigurationDefaultInt(1000) + @ConfigurationName("gui.window.width") + public static final ConfigurationItem guiWindowWidth = null; + @ConfigurationDefaultInt(700) + @ConfigurationName("gui.window.height") + public static final ConfigurationItem guiWindowHeight = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationName("gui.window.maximized.horizontal") + public static final ConfigurationItem guiWindowMaximizedHorizontal = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationName("gui.window.maximized.vertical") + public static final ConfigurationItem guiWindowMaximizedVertical = null; + @ConfigurationName("gui.avm2.splitPane.dividerLocation") + public static final ConfigurationItem guiAvm2SplitPaneDividerLocation = null; + @ConfigurationName("guiActionSplitPaneDividerLocation") + public static final ConfigurationItem guiActionSplitPaneDividerLocation = null; + @ConfigurationName("guiPreviewSplitPaneDividerLocation") + public static final ConfigurationItem guiPreviewSplitPaneDividerLocation = null; + @ConfigurationName("gui.splitPane1.dividerLocation") + public static final ConfigurationItem guiSplitPane1DividerLocation = null; + @ConfigurationName("gui.splitPane2.dividerLocation") + public static final ConfigurationItem guiSplitPane2DividerLocation = null; + @ConfigurationDefaultInt(3) + @ConfigurationCategory("export") + public static final ConfigurationItem saveAsExeScaleMode = null; + + @ConfigurationDefaultInt(1024 * 100/*100KB*/) + @ConfigurationCategory("limit") + public static final ConfigurationItem syntaxHighlightLimit = null; + public static final ConfigurationItem guiFontPreviewSampleText = null; + @ConfigurationName("gui.fontPreviewWindow.width") + public static final ConfigurationItem guiFontPreviewWidth = null; + @ConfigurationName("gui.fontPreviewWindow.height") + public static final ConfigurationItem guiFontPreviewHeight = null; + @ConfigurationName("gui.fontPreviewWindow.posX") + public static final ConfigurationItem guiFontPreviewPosX = null; + @ConfigurationName("gui.fontPreviewWindow.posY") + public static final ConfigurationItem guiFontPreviewPosY = null; + + @ConfigurationDefaultInt(3) + @ConfigurationName("formatting.indent.size") + @ConfigurationCategory("format") + public static final ConfigurationItem indentSize = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationName("formatting.indent.useTabs") + @ConfigurationCategory("format") + public static final ConfigurationItem indentUseTabs = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("format") + public static final ConfigurationItem beginBlockOnNewLine = null; + + @ConfigurationDefaultInt(1000 * 60 * 60 * 24) + @ConfigurationCategory("update") + @ConfigurationName("check.updates.delay") + public static final ConfigurationItem checkForUpdatesDelay = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("update") + @ConfigurationName("check.updates.stable") + public static final ConfigurationItem checkForUpdatesStable = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("update") + @ConfigurationName("check.updates.nightly") + public static final ConfigurationItem checkForUpdatesNightly = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("update") + @ConfigurationName("check.updates.enabled") + public static final ConfigurationItem checkForUpdatesAuto = null; + + @ConfigurationDefaultString("") + @ConfigurationName("export.formats") + public static final ConfigurationItem lastSelectedExportFormats = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("export") + public static final ConfigurationItem textExportSingleFile = null; + + @ConfigurationDefaultString("--- SEPARATOR ---") + @ConfigurationCategory("export") + public static final ConfigurationItem textExportSingleFileSeparator = null; + + @ConfigurationDefaultString("--- RECORDSEPARATOR ---") + @ConfigurationCategory("export") + public static final ConfigurationItem textExportSingleFileRecordSeparator = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationName("warning.experimental.as12edit") + @ConfigurationCategory("script") + public static final ConfigurationItem warningExperimentalAS12Edit = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationName("warning.experimental.as3edit") + @ConfigurationCategory("script") + public static final ConfigurationItem warningExperimentalAS3Edit = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("export") + public static final ConfigurationItem packJavaScripts = null; + + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("export") + public static final ConfigurationItem textExportExportFontFace = null; + + private enum OSId { + + WINDOWS, OSX, UNIX + } + + private static OSId getOSId() { + PrivilegedAction doGetOSName = new PrivilegedAction() { + @Override + public String run() { + return System.getProperty("os.name"); + } + }; + OSId id = OSId.UNIX; + String osName = AccessController.doPrivileged(doGetOSName); + if (osName != null) { + if (osName.toLowerCase().startsWith("mac os x")) { + id = OSId.OSX; + } else if (osName.contains("Windows")) { + id = OSId.WINDOWS; + } + } + return id; + } + + public static String getFFDecHome() { + if (directory == unspecifiedFile) { + directory = null; + String userHome = null; + try { + userHome = System.getProperty("user.home"); + } catch (SecurityException ignore) { + } + if (userHome != null) { + String applicationId = ApplicationInfo.SHORT_APPLICATION_NAME; + OSId osId = getOSId(); + if (osId == OSId.WINDOWS) { + File appDataDir = null; + try { + String appDataEV = System.getenv("APPDATA"); + if ((appDataEV != null) && (appDataEV.length() > 0)) { + appDataDir = new File(appDataEV); + } + } catch (SecurityException ignore) { + } + String vendorId = ApplicationInfo.VENDOR; + if ((appDataDir != null) && appDataDir.isDirectory()) { + // ${APPDATA}\{vendorId}\${applicationId} + String path = vendorId + "\\" + applicationId + "\\"; + directory = new File(appDataDir, path); + } else { + // ${userHome}\Application Data\${vendorId}\${applicationId} + String path = "Application Data\\" + vendorId + "\\" + applicationId + "\\"; + directory = new File(userHome, path); + } + } else if (osId == OSId.OSX) { + // ${userHome}/Library/Application Support/${applicationId} + String path = "Library/Application Support/" + applicationId + "/"; + directory = new File(userHome, path); + } else { + // ${userHome}/.${applicationId}/ + String path = "." + applicationId + "/"; + directory = new File(userHome, path); + } + } else { + //no home, then use application directory + directory = new File("."); + } + } + if (!directory.exists()) { + if (!directory.mkdirs()) { + if (!directory.exists()) { + directory = new File("."); //fallback to current directory + } + } + } + String ret = directory.getAbsolutePath(); + if (!ret.endsWith(File.separator)) { + ret += File.separator; + } + return ret; + } + + public static List getRecentFiles() { + String files = recentFiles.get(); + if (files == null || files.isEmpty()) { + return new ArrayList<>(); + } + return Arrays.asList(files.split("::")); + } + + public static void addRecentFile(String path) { + List recentFilesArray = new ArrayList<>(getRecentFiles()); + int idx = recentFilesArray.indexOf(path); + if (idx != -1) { + recentFilesArray.remove(idx); + } + recentFilesArray.add(path); + while (recentFilesArray.size() > maxRecentFileCount.get()) { + recentFilesArray.remove(0); + } + recentFiles.set(Helper.joinStrings(recentFilesArray, "::")); + } + + public static void removeRecentFile(String path) { + List recentFilesArray = new ArrayList<>(getRecentFiles()); + int idx = recentFilesArray.indexOf(path); + if (idx != -1) { + recentFilesArray.remove(idx); + } + recentFiles.set(Helper.joinStrings(recentFilesArray, "::")); + } + + public static Map getFontPairs() { + String fonts = fontPairing.get(); + if (fonts == null) { + return new HashMap<>(); + } + + Map result = new HashMap<>(); + for (String pair : fonts.split("::")) { + String[] splittedPair = pair.split("="); + result.put(splittedPair[0], splittedPair[1]); + } + return result; + } + + public static void addFontPair(String fileName, int fontId, String fontName, String systemFontName) { + String key = fileName + "_" + fontId + "_" + fontName; + Map fontPairs = getFontPairs(); + fontPairs.put(key, systemFontName); + fontPairs.put(fontName, systemFontName); + StringBuilder sb = new StringBuilder(); + int i = 0; + for (Entry pair : fontPairs.entrySet()) { + if (i != 0) { + sb.append("::"); + } + sb.append(pair.getKey()).append("=").append(pair.getValue()); + i++; + } + fontPairing.set(sb.toString()); + } + + /** + * Saves replacements to file for future use + */ + private static void saveReplacements(String replacementsFile) { + if (replacements.isEmpty()) { + File rf = new File(replacementsFile); + if (rf.exists()) { + if (!rf.delete()) { + Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Cannot delete replacements file"); + } + } + } else { + try (PrintWriter pw = new PrintWriter(new Utf8OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(replacementsFile))))) { + for (Replacement r : replacements) { + pw.println(r.urlPattern); + pw.println(r.targetFile); + } + } catch (IOException ex) { + Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Exception during saving replacements", ex); + } + } + } + + /** + * Load replacements from file + */ + private static void loadReplacements(String replacementsFile) { + if (!(new File(replacementsFile)).exists()) { + return; + } + replacements = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new Utf8InputStreamReader(new FileInputStream(replacementsFile)))) { + String s; + while ((s = br.readLine()) != null) { + Replacement r = new Replacement(s, br.readLine()); + replacements.add(r); + } + } catch (IOException e) { + //ignore + } + } + + private static String getReplacementsFile() throws IOException { + return getFFDecHome() + REPLACEMENTS_NAME; + } + + private static String getConfigFile() throws IOException { + return getFFDecHome() + CONFIG_NAME; + } + + private static HashMap loadFromFile(String file, String replacementsFile) { + HashMap config = new HashMap<>(); + try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) { + + @SuppressWarnings("unchecked") + HashMap cfg = (HashMap) ois.readObject(); + config = cfg; + } catch (ClassNotFoundException | IOException ex) { + //ignore + } + if (replacementsFile != null) { + loadReplacements(replacementsFile); + } + if (config.containsKey("paralelSpeedUp")) { + config.put("parallelSpeedUp", config.get("paralelSpeedUp")); + config.remove("paralelSpeedUp"); + } + return config; + } + + private static void saveToFile(String file, String replacementsFile) { + HashMap config = new HashMap<>(); + for (Entry entry : getConfigurationFields().entrySet()) { + try { + String name = entry.getKey(); + Field field = entry.getValue(); + ConfigurationItem item = (ConfigurationItem) field.get(null); + if (item.hasValue) { + config.put(name, item.get()); + } + } catch (IllegalArgumentException | IllegalAccessException ex) { + Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); + } + } + try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { + oos.writeObject(config); + } catch (IOException ex) { + //TODO: move this to GUI + JOptionPane.showMessageDialog(null, "Cannot save configuration.", "Error", JOptionPane.ERROR_MESSAGE); + Logger.getLogger(Configuration.class.getName()).severe("Configuration directory is read only."); + } + if (replacementsFile != null) { + saveReplacements(replacementsFile); + } + } + + public static List getReplacements() { + return replacements; + } + + public static void saveConfig() { + try { + saveToFile(getConfigFile(), getReplacementsFile()); + } catch (IOException ex) { + //ignore + } + } + + static { + setConfigurationFields(); + if (useDetailedLogging.get() || debugMode.get()) { + logLevel = Level.CONFIG; + } else { + logLevel = Level.WARNING; + } + int processorCount = Runtime.getRuntime().availableProcessors(); + if (parallelThreadCount.get() > processorCount) { + parallelThreadCount.set(processorCount); + } + + if (lastUpdatesCheckDate.get() == null) { + GregorianCalendar mingc = new GregorianCalendar(); + mingc.setTime(new Date(Long.MIN_VALUE)); + lastUpdatesCheckDate.set(mingc); + } + } + + @SuppressWarnings("unchecked") + public static void setConfigurationFields() { + try { + HashMap config = loadFromFile(getConfigFile(), getReplacementsFile()); + for (Entry entry : getConfigurationFields().entrySet()) { + String name = entry.getKey(); + Field field = entry.getValue(); + // remove final modifier from field + Field modifiersField = field.getClass().getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + Object defaultValue = getDefaultValue(field); + Object value = null; + if (config.containsKey(name)) { + value = config.get(name); + } + + if (value != null) { + field.set(null, new ConfigurationItem(name, defaultValue, value)); + } else { + field.set(null, new ConfigurationItem(name, defaultValue)); + } + } + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ex) { + // Reflection exceptions. This should never happen + throw new Error(ex.getMessage()); + } catch (IOException ex) { + Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public static Object getDefaultValue(Field field) { + Object defaultValue = null; + ConfigurationDefaultBoolean aBool = field.getAnnotation(ConfigurationDefaultBoolean.class); + if (aBool != null) { + defaultValue = aBool.value(); + } + ConfigurationDefaultInt aInt = field.getAnnotation(ConfigurationDefaultInt.class); + if (aInt != null) { + defaultValue = aInt.value(); + } + ConfigurationDefaultString aString = field.getAnnotation(ConfigurationDefaultString.class); + if (aString != null) { + defaultValue = aString.value(); + } + return defaultValue; + } + + public static Map getConfigurationFields() { + Field[] fields = Configuration.class.getFields(); + Map result = new HashMap<>(); + for (Field field : fields) { + if (ConfigurationItem.class.isAssignableFrom(field.getType())) { + ConfigurationName annotation = field.getAnnotation(ConfigurationName.class); + String name = annotation == null ? field.getName() : annotation.value(); + result.put(name, field); + } + } + return result; + } + + public static CodeFormatting getCodeFormatting() { + CodeFormatting ret = new CodeFormatting(); + String indentString = ""; + for (int i = 0; i < indentSize.get(); i++) { + indentString += indentUseTabs.get() ? "\t" : " "; + } + ret.indentString = indentString; + ret.beginBlockOnNewLine = beginBlockOnNewLine.get(); + return ret; + } + + public static File getFlashLibPath() { + String home = getFFDecHome(); + File libsdir = new File(home + "flashlib"); + if (!libsdir.exists()) { + libsdir.mkdirs(); + } + return libsdir; + } + + public static File getPlayerSWC() { + File libsdir = getFlashLibPath(); + if (libsdir != null && libsdir.exists()) { + File libs[] = libsdir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().startsWith("playerglobal"); + } + }); + List libnames = new ArrayList<>(); + for (File f : libs) { + libnames.add(f.getName()); + } + Collections.sort(libnames); + if (!libnames.isEmpty()) { + return new File(libsdir.getAbsolutePath() + File.separator + libnames.get(libnames.size() - 1)); + } else { + return null; + } + } + + return null; + } +} diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java index eaff77026..b9a2b173d 100644 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java +++ b/src/com/jpexs/decompiler/flash/dumpview/DumpInfo.java @@ -65,14 +65,14 @@ public class DumpInfo { public int getChildCount() { return childInfos == null ? 0 : childInfos.size(); } - + public List getChildInfos() { if (childInfos == null) { childInfos = new ArrayList<>(); } return childInfos; } - + @Override public String toString() { String value = previewValue == null ? "" : previewValue.toString(); diff --git a/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java b/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java index 58b3e8ee4..722695533 100644 --- a/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java +++ b/src/com/jpexs/decompiler/flash/dumpview/DumpInfoSwfNode.java @@ -25,16 +25,16 @@ import com.jpexs.decompiler.flash.SWF; public class DumpInfoSwfNode extends DumpInfo { private final SWF swf; - + public DumpInfoSwfNode(SWF swf, String name, String type, Object value, long startByte, long lengthBytes) { super(name, type, value, startByte, lengthBytes); this.swf = swf; } - + public SWF getSwf() { return swf; } - + public static DumpInfoSwfNode getSwfNode(DumpInfo dumpInfo) { while (!(dumpInfo instanceof DumpInfoSwfNode)) { dumpInfo = dumpInfo.parent; diff --git a/src/com/jpexs/decompiler/flash/gui/HeaderInfoPanel.java b/src/com/jpexs/decompiler/flash/gui/HeaderInfoPanel.java index a63ee1038..069d25f81 100644 --- a/src/com/jpexs/decompiler/flash/gui/HeaderInfoPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/HeaderInfoPanel.java @@ -60,8 +60,7 @@ public class HeaderInfoPanel extends JPanel { add(displayRectTwipsLabel); add(new JLabel("")); add(displayRectPixelsLabel); - - + SpringUtilities.makeCompactGrid(this, 9, 2, //rows, cols 6, 6, //initX, initY @@ -87,22 +86,23 @@ public class HeaderInfoPanel extends JPanel { frameRateLabel.setText("" + swf.frameRate); frameCountLabel.setText("" + swf.frameCount); displayRectTwipsLabel.setText(AppStrings.translate("header.displayrect.value.twips") - .replace("%xmin%", ""+swf.displayRect.Xmin) - .replace("%ymin%", ""+swf.displayRect.Ymin) - .replace("%xmax%", ""+swf.displayRect.Xmax) - .replace("%ymax%", ""+swf.displayRect.Ymax)); + .replace("%xmin%", "" + swf.displayRect.Xmin) + .replace("%ymin%", "" + swf.displayRect.Ymin) + .replace("%xmax%", "" + swf.displayRect.Xmax) + .replace("%ymax%", "" + swf.displayRect.Ymax)); displayRectPixelsLabel.setText(AppStrings.translate("header.displayrect.value.pixels") - .replace("%xmin%", ""+fmtDouble(swf.displayRect.Xmin/SWF.unitDivisor)) - .replace("%ymin%", ""+fmtDouble(swf.displayRect.Ymin/SWF.unitDivisor)) - .replace("%xmax%", ""+fmtDouble(swf.displayRect.Xmax/SWF.unitDivisor)) - .replace("%ymax%", ""+fmtDouble(swf.displayRect.Ymax/SWF.unitDivisor))); + .replace("%xmin%", "" + fmtDouble(swf.displayRect.Xmin / SWF.unitDivisor)) + .replace("%ymin%", "" + fmtDouble(swf.displayRect.Ymin / SWF.unitDivisor)) + .replace("%xmax%", "" + fmtDouble(swf.displayRect.Xmax / SWF.unitDivisor)) + .replace("%ymax%", "" + fmtDouble(swf.displayRect.Ymax / SWF.unitDivisor))); } - private String fmtDouble(double d){ - String r = ""+d; - if(r.endsWith(".0")){ - r = r.substring(0,r.length()-2); + + private String fmtDouble(double d) { + String r = "" + d; + if (r.endsWith(".0")) { + r = r.substring(0, r.length() - 2); } return r; } - + } diff --git a/src/com/jpexs/decompiler/flash/gui/HexView.java b/src/com/jpexs/decompiler/flash/gui/HexView.java index 633f670e5..3a322c428 100644 --- a/src/com/jpexs/decompiler/flash/gui/HexView.java +++ b/src/com/jpexs/decompiler/flash/gui/HexView.java @@ -33,7 +33,7 @@ import javax.swing.table.TableColumn; * @author JPEXS */ public class HexView extends JTable { - + private final int bytesInRow = 16; private long[] highlightStarts; private long[] highlightEnds; @@ -51,7 +51,7 @@ public class HexView extends JTable { JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); int level = -1; if (col > 0 && highlightStarts != null) { - if(col!=bytesInRow+1){ + if (col != bytesInRow + 1) { int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1)); for (int i = 0; i < highlightStarts.length; i++) { if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) { @@ -73,14 +73,14 @@ public class HexView extends JTable { return l; } - } + } public HexView() { highlightColors = new Color[highlightColorsStr.length]; for (int i = 0; i < highlightColors.length; i++) { highlightColors[i] = Color.decode("#" + highlightColorsStr[i]); } - + setModel(new AbstractTableModel() { @Override @@ -137,7 +137,7 @@ public class HexView extends JTable { setFont(new Font("Monospaced", Font.PLAIN, 12)); setTableHeader(new JTableHeader()); setMaximumSize(new Dimension(200, 200)); - + setShowHorizontalLines(false); setShowVerticalLines(false); setRowSelectionAllowed(false); @@ -152,10 +152,10 @@ public class HexView extends JTable { column.setMaxWidth(25); column.setCellRenderer(cellRenderer); } - + column = columnModel.getColumn(bytesInRow + 1); column.setMaxWidth(10); - + for (int i = 0; i < bytesInRow; i++) { column = columnModel.getColumn(i + bytesInRow + 1 + 1); column.setMaxWidth(10); @@ -164,28 +164,28 @@ public class HexView extends JTable { } public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) { - + if ((highlightStarts == null) ^ (highlightEnds == null)) { throw new Error("highlightStarts and highlightEnds should be both null or not null."); } - + if (highlightStarts != null && highlightStarts.length != highlightEnds.length) { throw new Error("highlightStarts and highlightEnds should have the same number of elements."); } - + this.data = data; this.highlightStarts = highlightStarts; this.highlightEnds = highlightEnds; } - + public void scrollToByte(long byteNum) { int row = (int) (byteNum / bytesInRow); //final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight()); getSelectionModel().setSelectionInterval(row, row); - scrollRectToVisible(new Rectangle(getCellRect(row, 0, true))); + scrollRectToVisible(new Rectangle(getCellRect(row, 0, true))); } - + public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) { for (int i = 0; i < byteNumStarts.length; i++) { scrollToByte(byteNumStarts[i]); diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java index ab2d111ad..6f072e559 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameRibbonMenu.java @@ -329,29 +329,27 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { assignListener(importTextCommandButton, ACTION_IMPORT_TEXT); importBand.addCommandButton(importTextCommandButton, RibbonElementPriority.TOP); - - + JRibbonBand viewBand = new JRibbonBand(translate("menu.view"), null); viewBand.setResizePolicies(getResizePolicies(viewBand)); - - CommandToggleButtonGroup grp=new CommandToggleButtonGroup(); - + + CommandToggleButtonGroup grp = new CommandToggleButtonGroup(); + viewModeResourcesToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.resources")), View.getResizableIcon("viewresources16")); - assignListener(viewModeResourcesToggleButton, ACTION_VIEWMODE_RESOURCES); - + assignListener(viewModeResourcesToggleButton, ACTION_VIEWMODE_RESOURCES); + viewModeHexToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.file.view.hex")), View.getResizableIcon("viewhex16")); assignListener(viewModeHexToggleButton, ACTION_VIEWMODE_HEX); - + grp.add(viewModeResourcesToggleButton); grp.add(viewModeHexToggleButton); - - if(Configuration.dumpView.get()){ + + if (Configuration.dumpView.get()) { grp.setSelected(viewModeHexToggleButton, true); - }else{ + } else { grp.setSelected(viewModeResourcesToggleButton, true); } - - + viewBand.addCommandButton(viewModeResourcesToggleButton, RibbonElementPriority.MEDIUM); viewBand.addCommandButton(viewModeHexToggleButton, RibbonElementPriority.MEDIUM); @@ -460,10 +458,9 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { miAutoRenameIdentifiers.addActionListener(this); /*miDumpView = new JCheckBox(translate("menu.settings.dumpView")); - miDumpView.setSelected(Configuration.dumpView.get()); - miDumpView.setActionCommand(ACTION_DUMP_VIEW_SWITCH); - miDumpView.addActionListener(this);*/ - + miDumpView.setSelected(Configuration.dumpView.get()); + miDumpView.setActionCommand(ACTION_DUMP_VIEW_SWITCH); + miDumpView.addActionListener(this);*/ settingsBand.addRibbonComponent(new JRibbonComponent(miAutoDeobfuscation)); settingsBand.addRibbonComponent(new JRibbonComponent(miInternalViewer)); settingsBand.addRibbonComponent(new JRibbonComponent(miParallelSpeedUp)); @@ -652,7 +649,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener { Configuration.internalFlashViewer.set(miInternalViewer.isSelected()); mainFrame.panel.reload(true); break; - + case ACTION_VIEWMODE_RESOURCES: Configuration.dumpView.set(false); mainFrame.panel.showDumpView(false); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 10b485dd4..1daa51850 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -485,10 +485,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec displayPanel.add(previewPanel, CARDPREVIEWPANEL); displayPanel.add(createFolderPreviewCard(), CARDFOLDERPREVIEWPANEL); displayPanel.add(createDumpPreviewCard(), CARDDUMPVIEW); - - headerPanel = new HeaderInfoPanel(); - displayPanel.add(headerPanel,CARDHEADER); - + + headerPanel = new HeaderInfoPanel(); + displayPanel.add(headerPanel, CARDHEADER); + displayPanel.add(new JPanel(), CARDEMPTYPANEL); showCard(CARDEMPTYPANEL); @@ -1133,7 +1133,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf(); } - + return null; } @@ -1859,7 +1859,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec setDumpTreeSelectedNode(dumpInfo); } } - + public void refreshDecompiled() { clearCache(); if (abcPanel != null) { @@ -2153,18 +2153,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec showCard(CARDEMPTYPANEL); return; } - + dumpViewPanel.setData(DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().uncompressedData, dumpInfo); dumpViewPanel.revalidate(); showCard(CARDDUMPVIEW); } - + public void reload(boolean forceReload) { if (Configuration.dumpView.get()) { dumpViewReload(forceReload); return; } - + TreeNode treeNode = (TreeNode) tagTree.getLastSelectedPathComponent(); if (treeNode == null) { return; @@ -2249,9 +2249,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.setImageReplaceButtonVisible(false); - if(treeNode instanceof HeaderNode) { + if (treeNode instanceof HeaderNode) { showCard(CARDHEADER); - headerPanel.load(((HeaderNode)treeNode).getItem().getSwf()); + headerPanel.load(((HeaderNode) treeNode).getItem().getSwf()); } else if (treeNode instanceof StringNode) { showCard(CARDFOLDERPREVIEWPANEL); showFolderPreview(treeNode); @@ -2543,7 +2543,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec ds.matrix = new MATRIX(); f.layers.put(1, ds); tim.frames.add(f); - } + } tim.displayRect = getRect(new HashSet()); return tim; } diff --git a/src/com/jpexs/decompiler/flash/gui/TagTree.java b/src/com/jpexs/decompiler/flash/gui/TagTree.java index 39de34d27..277c24424 100644 --- a/src/com/jpexs/decompiler/flash/gui/TagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/TagTree.java @@ -187,11 +187,11 @@ public class TagTree extends JTree implements ActionListener { } public static TreeNodeType getTreeNodeType(TreeItem t) { - - if(t instanceof HeaderItem){ + + if (t instanceof HeaderItem) { return TreeNodeType.HEADER; } - + if ((t instanceof DefineFontTag) || (t instanceof DefineFont2Tag) || (t instanceof DefineFont3Tag) @@ -498,7 +498,7 @@ public class TagTree extends JTree implements ActionListener { } } } - + public boolean hasExportableNodes() { return !getSelection(mainPanel.getCurrentSwf()).isEmpty(); } diff --git a/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java index bb741543f..19738f166 100644 --- a/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/TagTreeModel.java @@ -244,9 +244,8 @@ public class TagTreeModel implements TreeModel { } swfNode.scriptsNode = actionScriptNode; - ret.add(new HeaderNode(new HeaderItem(swf))); - + if (!shapesNode.subNodes.isEmpty()) { ret.add(shapesNode); } @@ -341,7 +340,7 @@ public class TagTreeModel implements TreeModel { return newPath; } } - + if (obj instanceof StringItem && n.getItem() instanceof StringItem) { // StringItems are always recreated, so compare them by name StringItem nds = (StringItem) n.getItem(); diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java index a29218cef..d68e2da32 100644 --- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpTree.java @@ -156,7 +156,7 @@ public class DumpTree extends JTree implements ActionListener { } } } - + @Override public void setModel(TreeModel tm) { super.setModel(tm); diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java index 2e68c2190..4b5d32c92 100644 --- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java @@ -59,7 +59,7 @@ public class DumpViewPanel extends JPanel { } return end - 1; } - + public void setData(byte[] data, DumpInfo dumpInfo) { List dumpInfos = new ArrayList<>(); DumpInfo di = dumpInfo; @@ -81,7 +81,7 @@ public class DumpViewPanel extends JPanel { int selectionEnd = getEndIndex(dumpInfo); dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds); - + setLabelText("startByte: " + dumpInfo.startByte + " startBit: " + dumpInfo.startBit + " lengthBytes: " + dumpInfo.lengthBytes @@ -89,7 +89,7 @@ public class DumpViewPanel extends JPanel { + " selectionStart: " + selectionStart + " selectionEnd: " + selectionEnd); } - + repaint(); } diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index 6d298d6a1..5fad4e5ba 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -243,7 +243,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { CharacterTag ch = swf.characters.get(r.characterId); if (ch instanceof BoundedTag) { BoundedTag bt = (BoundedTag) ch; - if (!added.contains(bt)){ + if (!added.contains(bt)) { added.add(bt); RECT r2 = bt.getRect(added); MATRIX mat = r.placeMatrix; diff --git a/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index 3030d6efa..0baa2c531 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -125,7 +125,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, Drawable } return ret; } - + private static final Cache rectCache = Cache.getInstance(true); @Override diff --git a/src/com/jpexs/decompiler/flash/tags/EndTag.java b/src/com/jpexs/decompiler/flash/tags/EndTag.java index c025fb0e4..9475ee3e2 100644 --- a/src/com/jpexs/decompiler/flash/tags/EndTag.java +++ b/src/com/jpexs/decompiler/flash/tags/EndTag.java @@ -36,7 +36,7 @@ public class EndTag extends Tag { public byte[] getData() { return new byte[0]; } - + public static final int ID = 0; /** diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java index 95e06cd46..3632be366 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject2Tag.java @@ -228,7 +228,7 @@ public class PlaceObject2Tag extends CharacterIdTag implements Container, PlaceO placeFlagHasMatrix = sis.readUB(1, "placeFlagHasMatrix") == 1; placeFlagHasCharacter = sis.readUB(1, "placeFlagHasCharacter") == 1; placeFlagMove = sis.readUB(1, "placeFlagMove") == 1; - + depth = sis.readUI16("depth"); if (placeFlagHasCharacter) { characterId = sis.readUI16("characterId"); diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java index 451907f52..3b6341e3f 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject3Tag.java @@ -397,7 +397,7 @@ public class PlaceObject3Tag extends CharacterIdTag implements Container, PlaceO } return clipActions.clipActionRecords.size(); } - + @Override public void getNeededCharacters(Set needed) { if (placeFlagHasCharacter) { diff --git a/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java b/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java index 23e1a1167..f1f1d5e8d 100644 --- a/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/PlaceObject4Tag.java @@ -249,7 +249,7 @@ public class PlaceObject4Tag extends CharacterIdTag implements Container, PlaceO sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0); sos.writeUB(1, placeFlagHasFilterList ? 1 : 0); sos.writeUI16(depth); - + if (placeFlagHasClassName) { sos.writeString(className); } diff --git a/src/com/jpexs/decompiler/flash/tags/Tag.java b/src/com/jpexs/decompiler/flash/tags/Tag.java index 9873179af..546d640c1 100644 --- a/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -350,7 +350,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, ContainerItem, * @return Bytes of data */ public abstract byte[] getData(); - + public final ByteArrayRange getOriginalRange() { return originalRange; } @@ -369,7 +369,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, ContainerItem, if (originalRange == null) { return 0; } - + return originalRange.length - (isLongOriginal() ? 6 : 2); } diff --git a/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index eaefc15fc..0b0c24418 100644 --- a/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -146,7 +146,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { shape.shapeRecords.add(new EndShapeRecord()); return shape; } - + @Override public RECT getRect(Set added) { SerializableImage image = getImage(); diff --git a/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java b/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java index fb82f70da..e2788f4e1 100644 --- a/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java +++ b/src/com/jpexs/decompiler/flash/treeitems/HeaderItem.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.treeitems; import com.jpexs.decompiler.flash.AppStrings; @@ -31,9 +30,7 @@ public class HeaderItem implements TreeItem { public HeaderItem(SWF swf) { this.swf = swf; } - - - + @Override public SWF getSwf() { return swf; @@ -43,7 +40,5 @@ public class HeaderItem implements TreeItem { public String toString() { return AppStrings.translate("node.header"); } - - - + } diff --git a/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java b/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java index ba079d9f2..7aa895340 100644 --- a/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java +++ b/src/com/jpexs/decompiler/flash/treenodes/HeaderNode.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package com.jpexs.decompiler.flash.treenodes; import com.jpexs.decompiler.flash.treeitems.HeaderItem; @@ -28,10 +27,10 @@ public class HeaderNode extends TreeNode { public HeaderNode(HeaderItem item) { super(item); } - + @Override public HeaderItem getItem() { return (HeaderItem) item; } - + } diff --git a/src/com/jpexs/helpers/ByteArrayRange.java b/src/com/jpexs/helpers/ByteArrayRange.java index e8d327eb3..4ca4d2870 100644 --- a/src/com/jpexs/helpers/ByteArrayRange.java +++ b/src/com/jpexs/helpers/ByteArrayRange.java @@ -23,13 +23,13 @@ package com.jpexs.helpers; public class ByteArrayRange { public final byte[] array; - public final int pos; - public final int length; - + public final int pos; + public final int length; + public ByteArrayRange() { this(new byte[0]); } - + public ByteArrayRange(byte[] array) { this.array = array; this.pos = 0; diff --git a/src/com/jpexs/helpers/MemoryInputStream.java b/src/com/jpexs/helpers/MemoryInputStream.java index c30d2ca26..bcef7826b 100644 --- a/src/com/jpexs/helpers/MemoryInputStream.java +++ b/src/com/jpexs/helpers/MemoryInputStream.java @@ -87,10 +87,10 @@ public class MemoryInputStream extends SeekableInputStream { pos += toRead; return toRead; } - + return -1; } - + @Override public int available() throws IOException { return maxLength - (int) pos; diff --git a/test/com/jpexs/decompiler/flash/ABCStreamTest.java b/test/com/jpexs/decompiler/flash/ABCStreamTest.java index 1011c3843..9815a78b3 100644 --- a/test/com/jpexs/decompiler/flash/ABCStreamTest.java +++ b/test/com/jpexs/decompiler/flash/ABCStreamTest.java @@ -1,56 +1,57 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.abc.ABCInputStream; -import com.jpexs.decompiler.flash.abc.ABCOutputStream; -import com.jpexs.decompiler.flash.gui.Main; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * - * @author JPEXS - */ -public class ABCStreamTest { - @BeforeClass - public void init(){ - Main.initLogging(false); - } - - @Test - public void testU30() { - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ABCOutputStream aos = new ABCOutputStream(baos);) { - long number = 1531; - aos.writeU30(number); - aos.close(); - try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ABCInputStream ais = new ABCInputStream(bais);) { - assertEquals(number, ais.readU30()); - assertEquals(0, bais.available()); - } - } catch (IOException ex) { - fail(); - } - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.abc.ABCInputStream; +import com.jpexs.decompiler.flash.abc.ABCOutputStream; +import com.jpexs.decompiler.flash.gui.Main; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * + * @author JPEXS + */ +public class ABCStreamTest { + + @BeforeClass + public void init() { + Main.initLogging(false); + } + + @Test + public void testU30() { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ABCOutputStream aos = new ABCOutputStream(baos);) { + long number = 1531; + aos.writeU30(number); + aos.close(); + try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ABCInputStream ais = new ABCInputStream(bais);) { + assertEquals(number, ais.readU30()); + assertEquals(0, bais.available()); + } + } catch (IOException ex) { + fail(); + } + } +} diff --git a/test/com/jpexs/decompiler/flash/ExportTest.java b/test/com/jpexs/decompiler/flash/ExportTest.java index 7c9bd83b3..2267dab34 100644 --- a/test/com/jpexs/decompiler/flash/ExportTest.java +++ b/test/com/jpexs/decompiler/flash/ExportTest.java @@ -1,122 +1,122 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.gui.Main; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; -import static org.testng.Assert.fail; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -/** - * - * @author JPEXS - */ -public class ExportTest { - - @BeforeClass - public void init(){ - Main.initLogging(false); - } - - public static final String TESTDATADIR = "testdata/decompile"; - - @BeforeClass - public void addLogger() { - Configuration.autoDeobfuscate.set(true); - Logger logger = Logger.getLogger(""); - logger.addHandler(new Handler() { - @Override - public void publish(LogRecord record) { - if (record.getLevel() == Level.SEVERE) { - fail("Error during decompilation", record.getThrown()); - } - } - - @Override - public void flush() { - } - - @Override - public void close() throws SecurityException { - } - }); - } - - @DataProvider(name = "swfFiles") - public Object[][] createData() { - File dir = new File(TESTDATADIR); - if (!dir.exists()) { - return new Object[0][0]; - } - File[] files = dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.toLowerCase().endsWith(".swf"); - } - }); - Object[][] ret = new Object[files.length][1]; - for (int i = 0; i < files.length; i++) { - ret[i][0] = files[i]; - } - return ret; - } - - @Test(dataProvider = "swfFiles") - public void testDecompileAS(File f) { - testDecompile(f, ScriptExportMode.AS); - } - - @Test(dataProvider = "swfFiles") - public void testDecompilePcode(File f) { - testDecompile(f, ScriptExportMode.PCODE); - } - - public void testDecompile(File f, ScriptExportMode exportMode) { - try { - SWF swf = new SWF(new FileInputStream(f), false); - Configuration.debugCopy.set(true); - String folderName = exportMode == ScriptExportMode.AS ? "output" : "outputp"; - File fdir = new File(TESTDATADIR + File.separator + folderName + File.separator + f.getName()); - fdir.mkdirs(); - - swf.exportActionScript(new AbortRetryIgnoreHandler() { - @Override - public int handle(Throwable thrown) { - return AbortRetryIgnoreHandler.ABORT; - } - - @Override - public AbortRetryIgnoreHandler getNewInstance() { - return this; - } - - }, fdir.getAbsolutePath(), exportMode, false); - } catch (Exception ex) { - fail(); - } - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.gui.Main; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import static org.testng.Assert.fail; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * + * @author JPEXS + */ +public class ExportTest { + + @BeforeClass + public void init() { + Main.initLogging(false); + } + + public static final String TESTDATADIR = "testdata/decompile"; + + @BeforeClass + public void addLogger() { + Configuration.autoDeobfuscate.set(true); + Logger logger = Logger.getLogger(""); + logger.addHandler(new Handler() { + @Override + public void publish(LogRecord record) { + if (record.getLevel() == Level.SEVERE) { + fail("Error during decompilation", record.getThrown()); + } + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }); + } + + @DataProvider(name = "swfFiles") + public Object[][] createData() { + File dir = new File(TESTDATADIR); + if (!dir.exists()) { + return new Object[0][0]; + } + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".swf"); + } + }); + Object[][] ret = new Object[files.length][1]; + for (int i = 0; i < files.length; i++) { + ret[i][0] = files[i]; + } + return ret; + } + + @Test(dataProvider = "swfFiles") + public void testDecompileAS(File f) { + testDecompile(f, ScriptExportMode.AS); + } + + @Test(dataProvider = "swfFiles") + public void testDecompilePcode(File f) { + testDecompile(f, ScriptExportMode.PCODE); + } + + public void testDecompile(File f, ScriptExportMode exportMode) { + try { + SWF swf = new SWF(new FileInputStream(f), false); + Configuration.debugCopy.set(true); + String folderName = exportMode == ScriptExportMode.AS ? "output" : "outputp"; + File fdir = new File(TESTDATADIR + File.separator + folderName + File.separator + f.getName()); + fdir.mkdirs(); + + swf.exportActionScript(new AbortRetryIgnoreHandler() { + @Override + public int handle(Throwable thrown) { + return AbortRetryIgnoreHandler.ABORT; + } + + @Override + public AbortRetryIgnoreHandler getNewInstance() { + return this; + } + + }, fdir.getAbsolutePath(), exportMode, false); + } catch (Exception ex) { + fail(); + } + } +} diff --git a/test/com/jpexs/decompiler/flash/RecompileTest.java b/test/com/jpexs/decompiler/flash/RecompileTest.java index a44520790..f9d34188a 100644 --- a/test/com/jpexs/decompiler/flash/RecompileTest.java +++ b/test/com/jpexs/decompiler/flash/RecompileTest.java @@ -1,184 +1,185 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash; - -import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ClassPath; -import com.jpexs.decompiler.flash.abc.NotSameException; -import com.jpexs.decompiler.flash.abc.ScriptPack; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.action.parser.ParseException; -import com.jpexs.decompiler.flash.action.parser.script.ActionScriptParser; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.gui.Main; -import com.jpexs.decompiler.flash.helpers.CodeFormatting; -import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; -import com.jpexs.decompiler.flash.helpers.collections.MyEntry; -import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.ContainerItem; -import com.jpexs.decompiler.flash.treeitems.TreeItem; -import com.jpexs.decompiler.flash.treenodes.TagNode; -import com.jpexs.decompiler.flash.treenodes.TreeNode; -import com.jpexs.decompiler.graph.CompilationException; -import com.jpexs.decompiler.graph.TranslateException; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import static org.testng.Assert.fail; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -/** - * - * @author JPEXS - */ -public class RecompileTest { - - @BeforeClass - public void init() { - Main.initLogging(false); - } - - public static final String TESTDATADIR = "testdata/recompile"; - - @Test(dataProvider = "provideFiles") - public void testRecompile(String filename) { - try { - SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); - Configuration.debugCopy.set(true); - swf.saveTo(new ByteArrayOutputStream()); - } catch (IOException | InterruptedException ex) { - fail(); - } catch (NotSameException ex) { - fail("File is different after recompiling: " + filename); - } - } - - private void testAS2DirectEditingOneRecursive(int swfVersion,List nodeList) { - for (TreeNode node : nodeList) { - if (node.subNodes.isEmpty()) { - TreeItem item = node.getItem(); - if ((item instanceof ASMSource) && (node.export)) { - try { - ASMSource asm = ((ASMSource) item); - HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as = writer.toString(); - as = asm.removePrefixAndSuffix(as); - ActionScriptParser par = new ActionScriptParser(swfVersion); - try { - asm.setActions(par.actionsFromString(as)); - } catch (ParseException | CompilationException ex) { - fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as2 = writer.toString(); - as2 = asm.removePrefixAndSuffix(as2); - try { - asm.setActions(par.actionsFromString(as2)); - } catch (ParseException | CompilationException ex) { - fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - writer = new HilightedTextWriter(new CodeFormatting(), false); - Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); - String as3 = writer.toString(); - as3 = asm.removePrefixAndSuffix(as3); - if (!as3.equals(as2)) { - fail("ActionScript is different: " + item.getSwf().getShortFileName() + "/" + item.toString()); - } - } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { - } - } - } else { - testAS2DirectEditingOneRecursive(swfVersion,node.subNodes); - } - } - } - - @Test(dataProvider = "provideFiles") - public void testDirectEditing(String filename) throws IOException, InterruptedException, com.jpexs.decompiler.flash.abc.avm2.parser.ParseException, CompilationException { - Configuration.autoDeobfuscate.set(false); - try{SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); - if (swf.fileAttributes.actionScript3) { - boolean dotest=false; - List allAbcs = new ArrayList<>(); - for (ABCContainerTag ct : swf.abcList) { - allAbcs.add(ct.getABC()); - } - for (ABC abc : allAbcs) { - for (int s = 0; s < abc.script_info.size(); s++) { - - String startAfter=null; - HilightedTextWriter htw = new HilightedTextWriter(new CodeFormatting(), false); - MyEntry en = abc.script_info.get(s).getPacks(abc, s).get(0); - if(startAfter==null || en.key.toString().equals(startAfter)){ - dotest = true; - } - if(!dotest){ - System.out.println("Skipped:"+en.key.toString()); - continue; - } - - System.out.println("Recompiling:"+en.key.toString()+"..."); - en.value.toSource(htw, swf.abcList, abc.script_info.get(s).traits.traits, ScriptExportMode.AS, false); - String original = htw.toString(); - ABC nabc = new ABC(swf); - com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(original, nabc,allAbcs, false, en.key.className + ".as"); - } - } - } else { - List list2 = new ArrayList<>(); - list2.addAll(swf.tags); - List list = SWF.createASTagList(list2, null); - - TagNode.setExport(list, true); - testAS2DirectEditingOneRecursive(swf.version,list); - } - }catch(Exception ex){ - System.out.println("FAIL"); - throw ex; - } - } - - @DataProvider(name = "provideFiles") - public Object[][] provideFiles() { - File dir = new File(TESTDATADIR); - if (!dir.exists()) { - return new Object[0][]; - } - File[] files = dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.toLowerCase().endsWith(".swf"); - } - }); - Object[][] ret = new Object[files.length][1]; - for (int f = 0; f < files.length; f++) { - ret[f][0] = files[f].getName(); - } - return ret; - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ClassPath; +import com.jpexs.decompiler.flash.abc.NotSameException; +import com.jpexs.decompiler.flash.abc.ScriptPack; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.ParseException; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptParser; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.gui.Main; +import com.jpexs.decompiler.flash.helpers.CodeFormatting; +import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.ContainerItem; +import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.decompiler.flash.treenodes.TagNode; +import com.jpexs.decompiler.flash.treenodes.TreeNode; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.TranslateException; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import static org.testng.Assert.fail; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * + * @author JPEXS + */ +public class RecompileTest { + + @BeforeClass + public void init() { + Main.initLogging(false); + } + + public static final String TESTDATADIR = "testdata/recompile"; + + @Test(dataProvider = "provideFiles") + public void testRecompile(String filename) { + try { + SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); + Configuration.debugCopy.set(true); + swf.saveTo(new ByteArrayOutputStream()); + } catch (IOException | InterruptedException ex) { + fail(); + } catch (NotSameException ex) { + fail("File is different after recompiling: " + filename); + } + } + + private void testAS2DirectEditingOneRecursive(int swfVersion, List nodeList) { + for (TreeNode node : nodeList) { + if (node.subNodes.isEmpty()) { + TreeItem item = node.getItem(); + if ((item instanceof ASMSource) && (node.export)) { + try { + ASMSource asm = ((ASMSource) item); + HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as = writer.toString(); + as = asm.removePrefixAndSuffix(as); + ActionScriptParser par = new ActionScriptParser(swfVersion); + try { + asm.setActions(par.actionsFromString(as)); + } catch (ParseException | CompilationException ex) { + fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); + } + writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as2 = writer.toString(); + as2 = asm.removePrefixAndSuffix(as2); + try { + asm.setActions(par.actionsFromString(as2)); + } catch (ParseException | CompilationException ex) { + fail("Unable to parse: " + item.getSwf().getShortFileName() + "/" + item.toString()); + } + writer = new HilightedTextWriter(new CodeFormatting(), false); + Action.actionsToSource(asm, asm.getActions(), asm.toString()/*FIXME?*/, writer); + String as3 = writer.toString(); + as3 = asm.removePrefixAndSuffix(as3); + if (!as3.equals(as2)) { + fail("ActionScript is different: " + item.getSwf().getShortFileName() + "/" + item.toString()); + } + } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { + } + } + } else { + testAS2DirectEditingOneRecursive(swfVersion, node.subNodes); + } + } + } + + @Test(dataProvider = "provideFiles") + public void testDirectEditing(String filename) throws IOException, InterruptedException, com.jpexs.decompiler.flash.abc.avm2.parser.ParseException, CompilationException { + Configuration.autoDeobfuscate.set(false); + try { + SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); + if (swf.fileAttributes.actionScript3) { + boolean dotest = false; + List allAbcs = new ArrayList<>(); + for (ABCContainerTag ct : swf.abcList) { + allAbcs.add(ct.getABC()); + } + for (ABC abc : allAbcs) { + for (int s = 0; s < abc.script_info.size(); s++) { + + String startAfter = null; + HilightedTextWriter htw = new HilightedTextWriter(new CodeFormatting(), false); + MyEntry en = abc.script_info.get(s).getPacks(abc, s).get(0); + if (startAfter == null || en.key.toString().equals(startAfter)) { + dotest = true; + } + if (!dotest) { + System.out.println("Skipped:" + en.key.toString()); + continue; + } + + System.out.println("Recompiling:" + en.key.toString() + "..."); + en.value.toSource(htw, swf.abcList, abc.script_info.get(s).traits.traits, ScriptExportMode.AS, false); + String original = htw.toString(); + ABC nabc = new ABC(swf); + com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(original, nabc, allAbcs, false, en.key.className + ".as"); + } + } + } else { + List list2 = new ArrayList<>(); + list2.addAll(swf.tags); + List list = SWF.createASTagList(list2, null); + + TagNode.setExport(list, true); + testAS2DirectEditingOneRecursive(swf.version, list); + } + } catch (Exception ex) { + System.out.println("FAIL"); + throw ex; + } + } + + @DataProvider(name = "provideFiles") + public Object[][] provideFiles() { + File dir = new File(TESTDATADIR); + if (!dir.exists()) { + return new Object[0][]; + } + File[] files = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".swf"); + } + }); + Object[][] ret = new Object[files.length][1]; + for (int f = 0; f < files.length; f++) { + ret[f][0] = files[f].getName(); + } + return ret; + } +} diff --git a/test/com/jpexs/decompiler/flash/SWFStreamTest.java b/test/com/jpexs/decompiler/flash/SWFStreamTest.java index 97e9e8497..33e4e5a16 100644 --- a/test/com/jpexs/decompiler/flash/SWFStreamTest.java +++ b/test/com/jpexs/decompiler/flash/SWFStreamTest.java @@ -32,10 +32,10 @@ import org.testng.annotations.Test; public class SWFStreamTest { @BeforeClass - public void init(){ + public void init() { Main.initLogging(false); } - + @Test public void testNeededBits() { assertEquals(SWFOutputStream.getNeededBitsU(3), 2);