diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java
index f17f66ae3..d1a5d2e08 100644
--- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java
+++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java
@@ -2513,6 +2513,10 @@ public final class SWF implements SWFContainerItem, Timelined {
}
}
+ public void clearSoundCache() {
+ soundCache.clear();
+ }
+
public void clearScriptCache() {
as2PcodeCache.clear();
as2Cache.clear();
@@ -2890,7 +2894,8 @@ public final class SWF implements SWFContainerItem, Timelined {
timelined.setModified(true);
timelined.resetTimeline();
} else // timeline should be always the swf here
- if (removeDependencies) {
+ {
+ if (removeDependencies) {
removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline());
timelined.setModified(true);
} else {
@@ -2899,6 +2904,7 @@ public final class SWF implements SWFContainerItem, Timelined {
timelined.setModified(true);
}
}
+ }
}
@Override
diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java
index 09ba3a0f9..938cf6b29 100644
--- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java
+++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java
@@ -1807,8 +1807,8 @@ public class XFLConverter {
}
format += 4; //quality best
try {
- MP3SOUNDDATA s = new MP3SOUNDDATA(new SWFInputStream(swf, soundData), false);
- //sis.readSI16();
+ SWFInputStream sis = new SWFInputStream(swf, soundData);
+ MP3SOUNDDATA s = new MP3SOUNDDATA(sis, false);
//MP3FRAME frame = new MP3FRAME(sis);
MP3FRAME frame = s.frames.get(0);
int bitRate = frame.getBitRate();
diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java
index 94bd445cb..9694928c6 100644
--- a/src/com/jpexs/decompiler/flash/gui/Main.java
+++ b/src/com/jpexs/decompiler/flash/gui/Main.java
@@ -1,2347 +1,2335 @@
-/*
- * Copyright (C) 2010-2016 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.gui;
-
-import com.jpexs.debugger.flash.Debugger;
-import com.jpexs.debugger.flash.DebuggerCommands;
-import com.jpexs.debugger.flash.Variable;
-import com.jpexs.decompiler.flash.ApplicationInfo;
-import com.jpexs.decompiler.flash.EventListener;
-import com.jpexs.decompiler.flash.SWF;
-import com.jpexs.decompiler.flash.SWFBundle;
-import com.jpexs.decompiler.flash.SWFSourceInfo;
-import com.jpexs.decompiler.flash.SearchMode;
-import com.jpexs.decompiler.flash.SwfOpenException;
-import com.jpexs.decompiler.flash.UrlResolver;
-import com.jpexs.decompiler.flash.Version;
-import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
-import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
-import com.jpexs.decompiler.flash.configuration.Configuration;
-import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
-import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
-import com.jpexs.decompiler.flash.console.ContextMenuTools;
-import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
-import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
-import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
-import com.jpexs.decompiler.flash.gui.pipes.FirstInstance;
-import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
-import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
-import com.jpexs.decompiler.flash.tags.Tag;
-import com.jpexs.decompiler.flash.tags.base.FontTag;
-import com.jpexs.decompiler.flash.tags.base.ImportTag;
-import com.jpexs.decompiler.flash.treeitems.SWFList;
-import com.jpexs.helpers.Cache;
-import com.jpexs.helpers.CancellableWorker;
-import com.jpexs.helpers.Helper;
-import com.jpexs.helpers.Path;
-import com.jpexs.helpers.ProgressListener;
-import com.jpexs.helpers.Stopwatch;
-import com.jpexs.helpers.streams.SeekableInputStream;
-import com.sun.jna.Platform;
-import com.sun.jna.platform.win32.Advapi32Util;
-import com.sun.jna.platform.win32.Kernel32;
-import com.sun.jna.platform.win32.WinReg;
-import java.awt.AWTException;
-import java.awt.Frame;
-import java.awt.GraphicsEnvironment;
-import java.awt.MenuItem;
-import java.awt.PopupMenu;
-import java.awt.SystemTray;
-import java.awt.TrayIcon;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.BufferedInputStream;
-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.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.URL;
-import java.net.URLConnection;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.FileHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.logging.SimpleFormatter;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.SwingWorker;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.filechooser.FileFilter;
-import org.pushingpixels.substance.api.SubstanceLookAndFeel;
-
-/**
- * Main executable class
- *
- * @author JPEXS
- */
-public class Main {
-
- protected static ProxyFrame proxyFrame;
-
- private static List sourceInfos = new ArrayList<>();
-
- public static LoadingDialog loadingDialog;
-
- private static boolean working = false;
-
- private static TrayIcon trayIcon;
-
- private static MenuItem stopMenuItem;
-
- private static volatile MainFrame mainFrame;
-
- public static final int UPDATE_SYSTEM_MAJOR = 1;
-
- public static final int UPDATE_SYSTEM_MINOR = 3;
-
- private static LoadFromMemoryFrame loadFromMemoryFrame;
-
- private static LoadFromCacheFrame loadFromCacheFrame;
-
- private static final Logger logger = Logger.getLogger(Main.class.getName());
-
- public static DebugLogDialog debugDialog;
-
- public static boolean shouldCloseWhenClosingLoadingDialog;
-
- private static Debugger flashDebugger;
-
- private static DebuggerHandler debugHandler = null;
-
- //private static int ip = 0;
- //private static String ipClass = null;
- private static Process runProcess;
-
- private static boolean runProcessDebug;
-
- private static boolean runProcessDebugPCode;
-
- private static boolean inited = false;
-
- private static File runTempFile;
-
- private static List runTempFiles = new ArrayList<>();
-
- public static void freeRun() {
- synchronized (Main.class) {
- if (runTempFile != null) {
- runTempFile.delete();
- runTempFile = null;
- }
- for (File f : runTempFiles) {
- f.delete();
- }
- runTempFiles.clear();
-
- runProcess = null;
- }
- if (mainFrame != null && mainFrame.getPanel() != null) {
- mainFrame.getPanel().clearDebuggerColors();
- }
- if (runProcessDebug) {
- Main.getDebugHandler().disconnect();
- }
- }
-
- public static synchronized boolean isDebugPaused() {
- return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
- }
-
- public static synchronized boolean isDebugRunning() {
- return runProcess != null && runProcessDebug;
- }
-
- public static synchronized boolean isDebugPCode() {
- return runProcessDebugPCode;
- }
-
- public static synchronized boolean isDebugConnected() {
- return getDebugHandler().isConnected();
- }
-
- public static synchronized boolean isRunning() {
- return runProcess != null && !runProcessDebug;
- }
-
- public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
- DebuggerCommands.Watch w = getDebugHandler().addWatch(v, v_id, watchRead, watchWrite);
- return w != null;
- }
-
- public static void runPlayer(String title, final String exePath, String file, String flashVars) {
- if (!new File(file).exists()) {
- return;
- }
- if (flashVars != null && !flashVars.isEmpty()) {
- file += "?" + flashVars;
- }
- final String ffile = file;
-
- CancellableWorker runWorker = new CancellableWorker() {
-
- @Override
- protected Object doInBackground() throws Exception {
- Process proc;
- try {
- proc = Runtime.getRuntime().exec(new String[]{exePath, ffile});
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- return null;
- }
- boolean isDebug;
-
- synchronized (Main.class) {
- runProcess = proc;
- isDebug = runProcessDebug;
- }
- if (isDebug) {
- mainFrame.getMenu().hilightPath("/debugging");
- }
- mainFrame.getMenu().updateComponents();
- try {
- if (proc != null) {
- proc.waitFor();
- }
- } catch (InterruptedException ex) {
- if (proc != null) {
- try {
- proc.destroy();
- } catch (Exception ex2) {
- //ignore
- }
- }
- }
- freeRun();
- stopDebugger();
- mainFrame.getMenu().updateComponents();
- return null;
- }
-
- @Override
- protected void done() {
- Main.stopWork();
- }
-
- @Override
- public void workerCancelled() {
- Main.stopWork();
- synchronized (Main.class) {
- if (runProcess != null) {
- try {
- runProcess.destroy();
- } catch (Exception ex) {
-
- }
- }
- }
- freeRun();
- mainFrame.getMenu().updateComponents();
- }
-
- };
-
- mainFrame.getMenu().updateComponents();
- Main.startWork(title + "...", runWorker);
- runWorker.execute();
- }
-
- public static void stopRun() {
-
- synchronized (Main.class) {
- if (runProcess != null) {
- runProcess.destroy();
- }
- }
- freeRun();
- stopDebugger();
- mainFrame.getMenu().updateComponents();
- }
-
- private static interface SwfPreparation {
-
- public SWF prepare(SWF swf);
- }
-
- private static class SwfRunPrepare implements SwfPreparation {
-
- @Override
- public SWF prepare(SWF swf) {
- if (Configuration.autoOpenLoadedSWFs.get()) {
- if (!DebuggerTools.hasDebugger(swf)) {
- DebuggerTools.switchDebugger(swf);
- }
- DebuggerTools.injectDebugLoader(swf);
- }
- return swf;
- }
- }
-
- private static class SwfDebugPrepare extends SwfRunPrepare {
-
- private boolean doPCode;
-
- public SwfDebugPrepare(boolean doPCode) {
- this.doPCode = doPCode;
- }
-
- @Override
- public SWF prepare(SWF instrSWF) {
- instrSWF = super.prepare(instrSWF);
- try {
- File fTempFile = new File(instrSWF.getFile());
- instrSWF.enableDebugging(true, new File("."), true, doPCode);
- FileOutputStream fos = new FileOutputStream(fTempFile);
- instrSWF.saveTo(fos);
- fos.close();
- if (!instrSWF.isAS3()) {
- //Read again, because line file offsets changed with adding debug tags
- //TODO: handle somehow without rereading?
- instrSWF = null;
- try (FileInputStream fis = new FileInputStream(fTempFile)) {
- instrSWF = new SWF(fis, false, false);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- if (instrSWF != null) {
- String swfFileName = fTempFile.getAbsolutePath();
- if (swfFileName.toLowerCase().endsWith(".swf")) {
- swfFileName = swfFileName.substring(0, swfFileName.length() - 4) + ".swd";
- } else {
- swfFileName = swfFileName + ".swd";
- }
- File swdFile = new File(swfFileName);
- if (doPCode) {
- instrSWF.generatePCodeSwdFile(swdFile, getPackBreakPoints(true));
- } else {
- instrSWF.generateSwdFile(swdFile, getPackBreakPoints(true));
- }
- }
- }
- } catch (IOException ex) {
- //ignore, return instrSWF
- }
- return instrSWF;
- }
- }
-
- private static void prepareSwf(SwfPreparation prep, File toPrepareFile, File origFile, List tempFiles) throws IOException {
- SWF instrSWF = null;
- try (FileInputStream fis = new FileInputStream(toPrepareFile)) {
- instrSWF = new SWF(fis, toPrepareFile.getAbsolutePath(), origFile.getName(), false);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- if (instrSWF != null) {
- for (Tag t : instrSWF.getLocalTags()) {
- if (t instanceof ImportTag) {
- ImportTag it = (ImportTag) t;
- String url = it.getUrl();
- File importedFile = new File(origFile.getParentFile(), url);
- if (importedFile.exists()) {
- File newTempFile = File.createTempFile("ffdec_run_import_", ".swf");
- it.setUrl("./" + newTempFile.getName());
- byte[] impData = Helper.readFile(importedFile.getAbsolutePath());
- Helper.writeFile(newTempFile.getAbsolutePath(), impData);
- tempFiles.add(newTempFile);
- prepareSwf(prep, newTempFile, importedFile, tempFiles);
- }
- }
- }
- if (prep != null) {
- instrSWF = prep.prepare(instrSWF);
- }
- try (FileOutputStream fos = new FileOutputStream(toPrepareFile)) {
- instrSWF.saveTo(fos);
- }
- }
- }
-
- public static void run(SWF swf) {
- String flashVars = "";//key=val&key2=val2
- String playerLocation = Configuration.playerLocation.get();
- if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
- View.showMessageDialog(null, AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- advancedSettings("paths");
- return;
- }
- if (swf == null) {
- return;
- }
- File tempFile;
- List tempFiles = new ArrayList<>();
- try {
- tempFile = File.createTempFile("ffdec_run_", ".swf");
-
- try (FileOutputStream fos = new FileOutputStream(tempFile)) {
- swf.saveTo(fos);
- }
-
- prepareSwf(new SwfRunPrepare(), tempFile, new File(swf.getFile()), tempFiles);
-
- } catch (IOException ex) {
- return;
-
- }
- if (tempFile != null) {
- synchronized (Main.class) {
- runTempFile = tempFile;
- runTempFiles = tempFiles;
- runProcessDebug = false;
- }
- runPlayer(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
- }
- }
-
- public static void runDebug(SWF swf, final boolean doPCode) {
- String flashVars = "";//key=val&key2=val2
- String playerLocation = Configuration.playerDebugLocation.get();
- if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
- View.showMessageDialog(null, AppStrings.translate("message.playerpath.debug.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
- Main.advancedSettings("paths");
- return;
- }
- if (swf == null) {
- return;
- }
- File tempFile = null;
-
- try {
- tempFile = File.createTempFile("ffdec_debug_", ".swf");
- } catch (Exception ex) {
-
- }
-
- if (tempFile != null) {
- final File fTempFile = tempFile;
- final List tempFiles = new ArrayList<>();
- CancellableWorker instrumentWorker = new CancellableWorker() {
-
- @Override
- protected Object doInBackground() throws Exception {
-
- try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
- swf.saveTo(fos);
- }
- prepareSwf(new SwfDebugPrepare(doPCode), fTempFile, new File(swf.getFile()), tempFiles);
- return null;
- }
-
- @Override
- public void workerCancelled() {
- Main.stopWork();
- }
-
- @Override
- protected void done() {
- synchronized (Main.class) {
- runTempFile = fTempFile;
- runProcessDebug = true;
- runProcessDebugPCode = doPCode;
- runTempFiles = tempFiles;
- }
- Main.stopWork();
- Main.startDebugger();
- runPlayer(AppStrings.translate("work.debugging.wait"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
- }
-
- };
-
- Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
- instrumentWorker.execute();
- }
- }
-
- /* public static void debuggerNotSuspended() {
-
- }*/
- public static boolean isDebugging() {
- return isDebugRunning();
- }
-
- public synchronized static int getIp(Object pack) {
- return getDebugHandler().getBreakIp();
- }
-
- public synchronized static String getIpClass() {
- return getDebugHandler().getBreakScriptName();
- }
-
- public static synchronized boolean isBreakPointValid(String scriptName, int line) {
- return !getDebugHandler().isBreakpointInvalid(scriptName, line);
- }
-
- public synchronized static void addBreakPoint(String scriptName, int line) {
- getDebugHandler().addBreakPoint(scriptName, line);
- }
-
- public synchronized static void removeBreakPoint(String scriptName, int line) {
- getDebugHandler().removeBreakPoint(scriptName, line);
- }
-
- public synchronized static boolean toggleBreakPoint(String scriptName, int line) {
- if (getDebugHandler().isBreakpointToAdd(scriptName, line) || getDebugHandler().isBreakpointConfirmed(scriptName, line) || getDebugHandler().isBreakpointInvalid(scriptName, line)) {
- getDebugHandler().removeBreakPoint(scriptName, line);
- return false;
- } else {
- getDebugHandler().addBreakPoint(scriptName, line);
- return true;
- }
- }
-
- public synchronized static Map> getPackBreakPoints(boolean validOnly) {
- return getDebugHandler().getAllBreakPoints(validOnly);
- }
-
- public synchronized static Set getScriptBreakPoints(String pack, boolean onlyValid) {
- return getDebugHandler().getBreakPoints(pack, onlyValid);
- }
-
- public static DebuggerHandler getDebugHandler() {
- return debugHandler;
- }
-
- public static void ensureMainFrame() {
- if (mainFrame == null) {
- synchronized (Main.class) {
- if (mainFrame == null) {
- MainFrame frame;
- if (Configuration.useRibbonInterface.get()) {
- frame = new MainFrameRibbon();
- } else {
- frame = new MainFrameClassic();
- }
- frame.getPanel().setErrorState(ErrorLogFrame.getInstance().getErrorState());
- mainFrame = frame;
- }
- }
- }
- }
-
- public static MainFrame getMainFrame() {
- return mainFrame;
- }
-
- public static void loadFromCache() {
- if (loadFromCacheFrame == null) {
- loadFromCacheFrame = new LoadFromCacheFrame();
- }
- loadFromCacheFrame.setVisible(true);
- }
-
- public static void loadFromMemory() {
- if (loadFromMemoryFrame == null) {
- loadFromMemoryFrame = new LoadFromMemoryFrame(mainFrame);
- }
- loadFromMemoryFrame.setVisible(true);
- }
-
- public static void setVariable(long parentId, String varName, int valueType, Object value) {
- getDebugHandler().setVariable(parentId, varName, valueType, value);
- }
-
- public static void setSubLimiter(boolean value) {
- if (value) {
- AVM2Code.toSourceLimit = Configuration.sublimiter.get();
- } else {
- AVM2Code.toSourceLimit = -1;
- }
- }
-
- public synchronized static boolean isInited() {
- return inited;
- }
-
- public synchronized static void setSessionLoaded(boolean v) {
- inited = v;
- }
-
- public static boolean isWorking() {
- return working;
- }
-
- public static void startProxy(int port) {
- if (proxyFrame == null) {
- proxyFrame = new ProxyFrame(mainFrame);
- }
-
- proxyFrame.setPort(port);
- addTrayIcon();
- switchProxy();
- }
-
- public static void showProxy() {
- if (proxyFrame == null) {
- proxyFrame = new ProxyFrame(mainFrame);
- }
- proxyFrame.setVisible(true);
- proxyFrame.setState(Frame.NORMAL);
- }
-
- public static void startWork(String name, CancellableWorker worker) {
- startWork(name, -1, worker);
- }
-
- public static void startWork(final String name, final int percent, final CancellableWorker worker) {
- working = true;
- View.execInEventDispatchLater(() -> {
- if (mainFrame != null) {
- mainFrame.getPanel().setWorkStatus(name, worker);
- if (percent == -1) {
- mainFrame.getPanel().hidePercent();
- } else {
- mainFrame.getPanel().setPercent(percent);
- }
- }
- if (loadingDialog != null) {
- loadingDialog.setDetail(name);
- loadingDialog.setPercent(percent);
- }
- if (CommandLineArgumentParser.isCommandLineMode()) {
- System.out.println(name);
- }
- });
- }
-
- public static void stopWork() {
- working = false;
- View.execInEventDispatchLater(() -> {
- if (mainFrame != null) {
- mainFrame.getPanel().setWorkStatus("", null);
- }
- if (loadingDialog != null) {
- loadingDialog.setDetail("");
- }
- });
- }
-
- public static SWFList parseSWF(SWFSourceInfo sourceInfo) throws Exception {
- SWFList result = new SWFList();
-
- InputStream inputStream = sourceInfo.getInputStream();
- SWFBundle bundle = null;
- FileInputStream fis = null;
- if (inputStream == null) {
- inputStream = new BufferedInputStream(fis = new FileInputStream(sourceInfo.getFile()));
- bundle = sourceInfo.getBundle(false, SearchMode.ALL);
- logger.log(Level.INFO, "Load file: {0}", sourceInfo.getFile());
- } else if (inputStream instanceof SeekableInputStream
- || inputStream instanceof BufferedInputStream) {
- try {
- inputStream.reset();
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- logger.log(Level.INFO, "Load stream: {0}", sourceInfo.getFileTitle());
- }
-
- Stopwatch sw = Stopwatch.startNew();
- if (bundle != null) {
- result.bundle = bundle;
- result.name = new File(sourceInfo.getFileTitleOrName()).getName();
- for (Entry streamEntry : bundle.getAll().entrySet()) {
- InputStream stream = streamEntry.getValue();
- stream.reset();
- CancellableWorker worker = new CancellableWorker() {
- @Override
- public SWF doInBackground() throws Exception {
- final CancellableWorker worker = this;
- SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() {
- @Override
- public void progress(int p) {
- startWork(AppStrings.translate("work.reading.swf"), p, worker);
- }
- }, Configuration.parallelSpeedUp.get());
- return swf;
- }
- };
- loadingDialog.setWroker(worker);
- worker.execute();
-
- try {
- result.add(worker.get());
- } catch (CancellationException ex) {
- logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", streamEntry.getKey());
- }
- }
- } else {
- InputStream fInputStream = inputStream;
-
- final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
-
- CancellableWorker worker = new CancellableWorker() {
-
- private boolean yestoall = false;
-
- private boolean notoall = false;
-
- private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
- final CancellableWorker worker = this;
-
- SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
- @Override
- public void progress(int p) {
- startWork(AppStrings.translate("work.reading.swf"), p, worker);
- }
- }, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
- @Override
- public SWF resolveUrl(final String url) {
- int opt = -1;
- if (!(yestoall || notoall)) {
- opt = View.showOptionDialog(null, AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
- if (opt == 2) {
- yestoall = true;
- }
- if (opt == 3) {
- notoall = true;
- }
- }
-
- if (yestoall) {
- opt = 0; // yes
- } else if (notoall) {
- opt = 1; // no
- }
-
- if (opt == 1) //no
- {
- return null;
- }
-
- if (url.startsWith("http://") || url.startsWith("https://")) {
- try {
- URL u = new URL(url);
- return open(u.openStream(), null, url); //?
- } catch (Exception ex) {
- //ignore
- }
- } else {
- File f = new File(new File(file).getParentFile(), url);
- if (f.exists()) {
- try {
- return open(new FileInputStream(f), f.getAbsolutePath(), f.getName());
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- Reference ret = new Reference<>(null);
- View.execInEventDispatch(new Runnable() {
- @Override
- public void run() {
-
- while (JOptionPane.YES_OPTION == View.showConfirmDialog(null, AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
-
- JFileChooser fc = new JFileChooser();
- fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
- FileFilter allSupportedFilter = new FileFilter() {
- private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
-
- @Override
- public boolean accept(File f) {
- String name = f.getName().toLowerCase();
- for (String ext : supportedExtensions) {
- if (name.endsWith(ext)) {
- return true;
- }
- }
- return f.isDirectory();
- }
-
- @Override
- public String getDescription() {
- String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
- return AppStrings.translate("filter.supported") + " (" + exts + ")";
- }
- };
- fc.setFileFilter(allSupportedFilter);
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
- fc.addChoosableFileFilter(swfFilter);
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
- fc.addChoosableFileFilter(gfxFilter);
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- int returnVal = fc.showOpenDialog(f);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
- File selFile = Helper.fixDialogFile(fc.getSelectedFile());
- try {
- ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
- break;
- } catch (Exception ex) {
- //ignore;
- }
- } else {
- break;
- }
- }
- }
- });
- return ret.getVal();
- }
- });
- return swf;
- }
-
- @Override
-
- public SWF doInBackground() throws Exception {
- return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
- }
- };
- if (loadingDialog != null) {
- loadingDialog.setWroker(worker);
- }
- worker.execute();
-
- try {
- result.add(worker.get());
- } catch (CancellationException ex) {
- logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", sourceInfo.getFileTitleOrName());
- }
- }
-
- if (fis != null) {
- logger.log(Level.INFO, "File loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
- fis.close();
- } else {
- logger.log(Level.INFO, "Stream loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
- }
-
- result.sourceInfo = sourceInfo;
- for (SWF swf : result) {
- logger.log(Level.INFO, "");
- logger.log(Level.INFO, "== File information ==");
- logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
- logger.log(Level.INFO, "Flash version: {0}", swf.version);
- int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
- int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
- logger.log(Level.INFO, "Width: {0}", width);
- logger.log(Level.INFO, "Height: {0}", height);
-
- swf.swfList = result;
- swf.addEventListener(new EventListener() {
- @Override
- public void handleExportingEvent(String type, int index, int count, Object data) {
- String text = AppStrings.translate("work.exporting");
- if (type != null && type.length() > 0) {
- text += " " + type;
- }
-
- startWork(text + " " + index + "/" + count + " " + data, null);
- }
-
- @Override
- public void handleExportedEvent(String type, int index, int count, Object data) {
- String text = AppStrings.translate("work.exported");
- if (type != null && type.length() > 0) {
- text += " " + type;
- }
-
- startWork(text + " " + index + "/" + count + " " + data, null);
- }
-
- @Override
- public void handleEvent(String event, Object data) {
- if (event.equals("exporting") || event.equals("exported")) {
- throw new Error("Event is not supported by this handler.");
- }
- if (event.equals("getVariables")) {
- startWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data, null);
- }
- if (event.equals("deobfuscate")) {
- startWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data, null);
- }
- if (event.equals("rename")) {
- startWork(AppStrings.translate("work.renaming") + "..." + (String) data, null);
- }
- }
- });
- }
-
- return result;
- }
-
- public static void saveFile(SWF swf, String outfile) throws IOException {
- saveFile(swf, outfile, SaveFileMode.SAVE, null);
- }
-
- public static void saveFile(SWF swf, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
- if (mode == SaveFileMode.SAVEAS && !swf.swfList.isBundle()) {
- swf.setFile(outfile);
- swf.swfList.sourceInfo.setFile(outfile);
- }
- File outfileF = new File(outfile);
- File tmpFile = new File(outfile + ".tmp");
- try (FileOutputStream fos = new FileOutputStream(tmpFile);
- BufferedOutputStream bos = new BufferedOutputStream(fos)) {
- if (mode == SaveFileMode.EXE) {
- switch (exeExportMode) {
- case WRAPPER:
- InputStream exeStream = View.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/Swf2Exe.bin");
- Helper.copyStream(exeStream, bos);
- int width = swf.displayRect.Xmax - swf.displayRect.Xmin;
- int height = swf.displayRect.Ymax - swf.displayRect.Ymin;
- bos.write(width & 0xff);
- bos.write((width >> 8) & 0xff);
- bos.write((width >> 16) & 0xff);
- bos.write((width >> 24) & 0xff);
- bos.write(height & 0xff);
- bos.write((height >> 8) & 0xff);
- bos.write((height >> 16) & 0xff);
- bos.write((height >> 24) & 0xff);
- bos.write(Configuration.saveAsExeScaleMode.get());
- break;
- case PROJECTOR_WIN:
- case PROJECTOR_MAC:
- case PROJECTOR_LINUX:
- File projectorFile = Configuration.getProjectorFile(exeExportMode);
- if (projectorFile == null) {
- String message = "Projector not found, please place it to " + Configuration.getProjectorPath();
- logger.log(Level.SEVERE, message);
- throw new IOException(message);
- }
- Helper.copyStream(new FileInputStream(projectorFile), bos);
- bos.flush();
- break;
- }
- }
-
- long pos = fos.getChannel().position();
- swf.saveTo(bos);
-
- if (mode == SaveFileMode.EXE) {
- switch (exeExportMode) {
- case PROJECTOR_WIN:
- case PROJECTOR_MAC:
- case PROJECTOR_LINUX:
- bos.flush();
- int swfSize = (int) (fos.getChannel().position() - pos);
-
- // write magic number
- bos.write(0x56);
- bos.write(0x34);
- bos.write(0x12);
- bos.write(0xfa);
-
- bos.write(swfSize & 0xff);
- bos.write((swfSize >> 8) & 0xff);
- bos.write((swfSize >> 16) & 0xff);
- bos.write((swfSize >> 24) & 0xff);
- }
- }
- }
- if (tmpFile.exists()) {
- if (tmpFile.length() > 0) {
- outfileF.delete();
- if (!tmpFile.renameTo(outfileF)) {
- tmpFile.delete();
- throw new IOException("Cannot access " + outfile);
- }
- } else {
- throw new IOException("Output is empty");
- }
- } else {
- throw new IOException("Output not found");
- }
- }
-
- private static class OpenFileWorker extends SwingWorker {
-
- private final SWFSourceInfo[] sourceInfos;
-
- private final Runnable executeAfterOpen;
-
- private final int[] reloadIndices;
-
- public OpenFileWorker(SWFSourceInfo sourceInfo) {
- this(sourceInfo, -1);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, int reloadIndex) {
- this(sourceInfo, null, reloadIndex);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
- this(sourceInfo, executeAfterOpen, -1);
- }
-
- public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
- this.sourceInfos = new SWFSourceInfo[]{sourceInfo};
- this.executeAfterOpen = executeAfterOpen;
- this.reloadIndices = new int[]{reloadIndex};
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
- this(sourceInfos, null, null);
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
- this(sourceInfos, executeAfterOpen, null);
- }
-
- public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
- this.sourceInfos = sourceInfos;
- this.executeAfterOpen = executeAfterOpen;
- int indices[] = new int[sourceInfos.length];
- for (int i = 0; i < indices.length; i++) {
- indices[i] = -1;
- }
- this.reloadIndices = reloadIndices == null ? indices : reloadIndices;
- }
-
- @Override
- protected Object doInBackground() throws Exception {
- boolean first = true;
- SWF firstSWF = null;
- for (int index = 0; index < sourceInfos.length; index++) {
- SWFSourceInfo sourceInfo = sourceInfos[index];
- SWFList swfs = null;
- try {
- Main.startWork(AppStrings.translate("work.reading.swf") + "...", null);
- try {
- swfs = parseSWF(sourceInfo);
- } catch (ExecutionException ex) {
- Throwable cause = ex.getCause();
- if (cause instanceof SwfOpenException) {
- throw (SwfOpenException) cause;
- }
-
- throw ex;
- }
- } catch (OutOfMemoryError ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
- continue;
- } catch (SwfOpenException ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, ex.getMessage());
- continue;
- } catch (Exception ex) {
- logger.log(Level.SEVERE, null, ex);
- View.showMessageDialog(null, "Cannot load SWF file.");
- continue;
- }
-
- final SWFList swfs1 = swfs;
- final boolean first1 = first;
- first = false;
- if (firstSWF == null && swfs1.size() > 0) {
- firstSWF = swfs1.get(0);
- }
-
- final int findex = index;
- try {
- View.execInEventDispatch(() -> {
- Main.startWork(AppStrings.translate("work.creatingwindow") + "...", null);
- ensureMainFrame();
- if (reloadIndices[findex] > -1) {
- mainFrame.getPanel().loadSwfAtPos(swfs1, reloadIndices[findex]);
- } else {
- mainFrame.getPanel().load(swfs1, first1);
- }
- });
- } catch (Exception ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- loadingDialog.setVisible(false);
- shouldCloseWhenClosingLoadingDialog = false;
-
- final SWF fswf = firstSWF;
- View.execInEventDispatch(() -> {
- if (mainFrame != null) {
- mainFrame.setVisible(true);
- }
-
- Main.stopWork();
-
- if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) {
- mainFrame.getPanel().gotoDocumentClass(fswf);
- }
-
- if (mainFrame != null && fswf != null) {
- SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortFileName());
- if (swfConf != null) {
- String pathStr = swfConf.lastSelectedPath;
- mainFrame.getPanel().tagTree.setSelectionPathString(pathStr);
- }
- }
-
- if (executeAfterOpen != null) {
- executeAfterOpen.run();
- }
- });
-
- return true;
- }
- }
-
- public static boolean reloadSWFs() {
- CancellableWorker.cancelBackgroundThreads();
- if (Main.sourceInfos.isEmpty()) {
- Helper.freeMem();
- showModeFrame();
- return true;
- } else {
- SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
- sourceInfos.toArray(sourceInfosCopy);
- sourceInfos.clear();
- openFile(sourceInfosCopy);
- return true;
- }
- }
-
- public static void reloadApp() {
- if (debugDialog != null) {
- debugDialog.setVisible(false);
- debugDialog.dispose();
- debugDialog = null;
- }
- if (loadingDialog != null) {
- synchronized (Main.class) {
- if (loadingDialog != null) {
- loadingDialog.setVisible(false);
- loadingDialog.dispose();
- loadingDialog = null;
- }
- }
- }
- if (proxyFrame != null) {
- proxyFrame.setVisible(false);
- proxyFrame.dispose();
- proxyFrame = null;
- }
- if (loadFromMemoryFrame != null) {
- loadFromMemoryFrame.setVisible(false);
- loadFromMemoryFrame.dispose();
- loadFromMemoryFrame = null;
- }
- if (loadFromCacheFrame != null) {
- loadFromCacheFrame.setVisible(false);
- loadFromCacheFrame.dispose();
- loadFromCacheFrame = null;
- }
- if (mainFrame != null) {
- mainFrame.setVisible(false);
- mainFrame.getPanel().closeAll(false);
- mainFrame.dispose();
- mainFrame = null;
- }
- FontTag.reload();
- Cache.clearAll();
- initGui();
- reloadSWFs();
- }
-
- public static OpenFileResult openFile(String swfFile, String fileTitle) {
- return openFile(swfFile, fileTitle, null);
- }
-
- public static OpenFileResult openFile(String swfFile, String fileTitle, Runnable executeAfterOpen) {
- try {
- File file = new File(swfFile);
- if (!file.exists()) {
- View.showMessageDialog(null, AppStrings.translate("open.error.fileNotFound"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
- return OpenFileResult.NOT_FOUND;
- }
- swfFile = file.getCanonicalPath();
- Configuration.addRecentFile(swfFile);
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
- OpenFileResult openResult = openFile(sourceInfo);
- return openResult;
- } catch (IOException ex) {
- View.showMessageDialog(null, AppStrings.translate("open.error.cannotOpen"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
- return OpenFileResult.ERROR;
- }
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
- return openFile(new SWFSourceInfo[]{sourceInfo});
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
- return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
- return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
- return openFile(newSourceInfos, null);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
- return openFile(newSourceInfos, executeAfterOpen, null);
- }
-
- public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
- if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
- sourceInfos.clear();
- mainFrame.getPanel().closeAll(false);
- mainFrame.setVisible(false);
- Helper.freeMem();
- reloadIndices = null;
- }
-
- loadingDialog.setVisible(true);
-
- OpenFileWorker wrk = new OpenFileWorker(newSourceInfos, executeAfterOpen, reloadIndices);
- wrk.execute();
- if (reloadIndices == null) {
- sourceInfos.addAll(Arrays.asList(newSourceInfos));
- } else {
- for (int i = 0; i < reloadIndices.length; i++) {
- sourceInfos.set(reloadIndices[i], newSourceInfos[i]);
- }
- }
- return OpenFileResult.OK;
- }
-
- public static void closeFile(SWFList swf) {
- sourceInfos.remove(swf.sourceInfo);
- mainFrame.getPanel().close(swf);
- }
-
- public static void reloadFile(SWFList swf) {
- //mainFrame.getPanel().close(swf);
- openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
- }
-
- public static boolean closeAll() {
- boolean closeResult = mainFrame.getPanel().closeAll(true);
- if (closeResult) {
- sourceInfos.clear();
- }
-
- return closeResult;
- }
-
- public static boolean saveFileDialog(SWF swf, final SaveFileMode mode) {
- JFileChooser fc = new JFileChooser();
- fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
- String ext = ".swf";
- switch (mode) {
- case SAVE:
- case SAVEAS:
- if (swf.getFile() != null) {
- ext = Path.getExtension(swf.getFile());
- }
- break;
- case EXE:
- ext = ".exe";
- break;
- }
-
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
-
- ExeExportMode exeExportMode = null;
- if (mode == SaveFileMode.EXE) {
- exeExportMode = Configuration.exeExportMode.get();
- if (exeExportMode == null) {
- exeExportMode = ExeExportMode.WRAPPER;
- }
- String filterDescription = null;
- switch (exeExportMode) {
- case WRAPPER:
- case PROJECTOR_WIN:
- ext = ".exe";
- filterDescription = "filter.exe";
- break;
- case PROJECTOR_MAC:
- ext = ".dmg";
- filterDescription = "filter.dmg";
- break;
- case PROJECTOR_LINUX:
- // linux projector is compressed with tar.gz
- // todo: decompress
- ext = "";
- filterDescription = "filter.linuxExe";
- break;
- }
-
- String fext = ext;
- String ffilterDescription = filterDescription;
- FileFilter exeFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(fext)) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate(ffilterDescription);
- }
- };
- fc.setFileFilter(exeFilter);
- } else if (swf.gfx) {
- fc.addChoosableFileFilter(swfFilter);
- fc.setFileFilter(gfxFilter);
- } else {
- fc.setFileFilter(swfFilter);
- fc.addChoosableFileFilter(gfxFilter);
- }
- final String extension = ext;
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- if (fc.showSaveDialog(f) == JFileChooser.APPROVE_OPTION) {
- File file = Helper.fixDialogFile(fc.getSelectedFile());
- FileFilter selFilter = fc.getFileFilter();
- try {
- String fileName = file.getAbsolutePath();
- if (selFilter == swfFilter) {
- if (!fileName.toLowerCase().endsWith(extension)) {
- fileName += extension;
- }
- swf.gfx = false;
- }
- if (selFilter == gfxFilter) {
- if (!fileName.toLowerCase().endsWith(".gfx")) {
- fileName += ".gfx";
- }
- swf.gfx = true;
- }
- Main.saveFile(swf, fileName, mode, exeExportMode);
- Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
- return true;
- } catch (IOException ex) {
- View.showMessageDialog(null, AppStrings.translate("error.file.write"));
- }
- }
- return false;
- }
-
- public static boolean openFileDialog() {
- JFileChooser fc = new JFileChooser();
- if (Configuration.openMultipleFiles.get()) {
- fc.setMultiSelectionEnabled(true);
- }
- fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
- FileFilter allSupportedFilter = new FileFilter() {
- private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip"};
-
- @Override
- public boolean accept(File f) {
- String name = f.getName().toLowerCase();
- for (String ext : supportedExtensions) {
- if (name.endsWith(ext)) {
- return true;
- }
- }
- return f.isDirectory();
- }
-
- @Override
- public String getDescription() {
- String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
- return AppStrings.translate("filter.supported") + " (" + exts + ")";
- }
- };
- fc.setFileFilter(allSupportedFilter);
- FileFilter swfFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swf");
- }
- };
- fc.addChoosableFileFilter(swfFilter);
-
- FileFilter swcFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".swc")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.swc");
- }
- };
- fc.addChoosableFileFilter(swcFilter);
-
- FileFilter gfxFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.gfx");
- }
- };
- fc.addChoosableFileFilter(gfxFilter);
-
- FileFilter zipFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return (f.getName().toLowerCase().endsWith(".zip")) || (f.isDirectory());
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.zip");
- }
- };
- fc.addChoosableFileFilter(zipFilter);
-
- FileFilter binaryFilter = new FileFilter() {
- @Override
- public boolean accept(File f) {
- return true;
- }
-
- @Override
- public String getDescription() {
- return AppStrings.translate("filter.binary");
- }
- };
- fc.addChoosableFileFilter(binaryFilter);
-
- fc.setAcceptAllFileFilterUsed(false);
- JFrame f = new JFrame();
- View.setWindowIcon(f);
- int returnVal = fc.showOpenDialog(f);
- if (returnVal == JFileChooser.APPROVE_OPTION) {
- Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
- File[] selFiles = fc.getSelectedFiles();
- for (File file : selFiles) {
- File selfile = Helper.fixDialogFile(file);
- Main.openFile(selfile.getAbsolutePath(), null);
- }
- return true;
- } else {
- return false;
- }
- }
-
- public static void displayErrorFrame() {
- ErrorLogFrame.getInstance().setVisible(true);
- }
-
- private static String md5(byte data[]) {
- try {
- java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
- byte[] array = md.digest(data);
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < array.length; ++i) {
- sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
- }
- return sb.toString();
- } catch (java.security.NoSuchAlgorithmException e) {
- }
- return null;
- }
-
- private static void initGui() {
- if (GraphicsEnvironment.isHeadless()) {
- System.err.println("Error: Your system does not support Graphic User Interface");
- exit();
- }
-
- System.setProperty("sun.java2d.d3d", "false");
- System.setProperty("sun.java2d.noddraw", "true");
-
- if (Configuration.hwAcceleratedGraphics.get()) {
- System.setProperty("sun.java2d.opengl", Configuration._debugMode.get() ? "True" : "true");
- } else {
- System.setProperty("sun.java2d.opengl", "false");
- }
-
- initUiLang();
-
- if (Configuration.useRibbonInterface.get()) {
- View.setLookAndFeel();
- } else {
- try {
- UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null);
- UIManager.put("Tree.expandedIcon", null);
- UIManager.put("Tree.collapsedIcon", null);
- UIManager.put("ColorChooserUI", null);
- UIManager.put("ColorChooser.swatchesRecentSwatchSize", null);
- UIManager.put("ColorChooser.swatchesSwatchSize", null);
- UIManager.put("RibbonApplicationMenuPopupPanelUI", null);
- UIManager.put("RibbonApplicationMenuButtonUI", null);
- UIManager.put("ProgressBarUI", null);
- UIManager.put("TextField.background", null);
- UIManager.put("FormattedTextField.background", null);
- UIManager.put("CommandButtonUI", null);
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- View.execInEventDispatch(() -> {
- ErrorLogFrame.createNewInstance();
-
- autoCheckForUpdates();
- offerAssociation();
- loadingDialog = new LoadingDialog();
-
- DebuggerTools.initDebugger().addMessageListener(new DebugListener() {
-
- @Override
- public void onMessage(String clientId, String msg) {
- }
-
- @Override
- public void onLoaderURL(String clientId, String url) {
- }
-
- @Override
- public void onLoaderBytes(String clientId, byte[] data) {
- String hash = md5(data);
- for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
- for (int s = 0; s < sl.size(); s++) {
- String t = sl.get(s).getFileTitle();
- if (t == null) {
- t = "";
- }
- if (t.endsWith(":" + hash)) { //this one is already opened
- return;
- }
- }
- }
- SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
-
- String title = swf == null ? "?" : swf.getFileTitle();
- title = title + ":" + hash;
- String tfile;
- try {
- tfile = tempFile(title);
- Helper.writeFile(tfile, data);
- openFile(new SWFSourceInfo(null, tfile, title));
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "Cannot create tempfile");
- }
- }
-
- @Override
- public void onFinish(String clientId) {
- }
- });
-
- try {
- flashDebugger = new Debugger();
- debugHandler = new DebuggerHandler();
- debugHandler.addBreakListener(new DebuggerHandler.BreakListener() {
-
- @Override
- public void doContinue() {
- mainFrame.getPanel().clearDebuggerColors();
- }
-
- @Override
- public void breakAt(String scriptName, int line, final int classIndex, final int traitIndex, final int methodIndex) {
- View.execInEventDispatch(new Runnable() {
-
- @Override
- public void run() {
- mainFrame.getPanel().gotoScriptLine(getMainFrame().getPanel().getCurrentSwf(), scriptName, line, classIndex, traitIndex, methodIndex);
- }
- });
- }
- });
- debugHandler.addConnectionListener(new DebuggerHandler.ConnectionListener() {
-
- @Override
- public void connected() {
- Main.mainFrame.getMenu().updateComponents();
- }
-
- @Override
- public void disconnected() {
- if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
- Main.mainFrame.getPanel().refreshBreakPoints();
- }
- }
- });
- flashDebugger.addConnectionListener(debugHandler);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "eeex", ex);
- }
- });
- }
-
- public static void startDebugger() {
- flashDebugger.startDebugger();
- }
-
- public static void stopDebugger() {
- flashDebugger.stopDebugger();
- }
-
- public static void showModeFrame() {
- ensureMainFrame();
- mainFrame.setVisible(true);
- }
-
- private static void offerAssociation() {
- boolean offered = Configuration.offeredAssociation.get();
- if (!offered) {
- if (Platform.isWindows()) {
- if ((!ContextMenuTools.isAddedToContextMenu()) && View.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
- ContextMenuTools.addToContextMenu(true, false);
- }
- }
-
- Configuration.offeredAssociation.set(true);
- }
- }
-
- public static void initUiLang() {
- if (GraphicsEnvironment.isHeadless()) { //No GUI in OS
- return;
- }
- try {
- Class> cl = Class.forName("org.pushingpixels.substance.api.SubstanceLookAndFeel");
- Field field = cl.getDeclaredField("LABEL_BUNDLE");
- field.setAccessible(true);
- field.set(null, null);
- } catch (Throwable ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- UIManager.put("OptionPane.okButtonText", AppStrings.translate("button.ok"));
- UIManager.put("OptionPane.yesButtonText", AppStrings.translate("button.yes"));
- UIManager.put("OptionPane.noButtonText", AppStrings.translate("button.no"));
- UIManager.put("OptionPane.cancelButtonText", AppStrings.translate("button.cancel"));
- UIManager.put("OptionPane.messageDialogTitle", AppStrings.translate("dialog.message.title"));
- UIManager.put("OptionPane.titleText", AppStrings.translate("dialog.select.title"));
-
- UIManager.put("FileChooser.acceptAllFileFilterText", AppStrings.translate("FileChooser.acceptAllFileFilterText"));
- UIManager.put("FileChooser.lookInLabelText", AppStrings.translate("FileChooser.lookInLabelText"));
- UIManager.put("FileChooser.cancelButtonText", AppStrings.translate("button.cancel"));
- UIManager.put("FileChooser.cancelButtonToolTipText", AppStrings.translate("button.cancel"));
- UIManager.put("FileChooser.openButtonText", AppStrings.translate("FileChooser.openButtonText"));
- UIManager.put("FileChooser.openButtonToolTipText", AppStrings.translate("FileChooser.openButtonToolTipText"));
- UIManager.put("FileChooser.filesOfTypeLabelText", AppStrings.translate("FileChooser.filesOfTypeLabelText"));
- UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
- UIManager.put("FileChooser.listViewButtonToolTipText", AppStrings.translate("FileChooser.listViewButtonToolTipText"));
- UIManager.put("FileChooser.listViewButtonAccessibleName", AppStrings.translate("FileChooser.listViewButtonAccessibleName"));
- UIManager.put("FileChooser.detailsViewButtonToolTipText", AppStrings.translate("FileChooser.detailsViewButtonToolTipText"));
- UIManager.put("FileChooser.detailsViewButtonAccessibleName", AppStrings.translate("FileChooser.detailsViewButtonAccessibleName"));
- UIManager.put("FileChooser.upFolderToolTipText", AppStrings.translate("FileChooser.upFolderToolTipText"));
- UIManager.put("FileChooser.upFolderAccessibleName", AppStrings.translate("FileChooser.upFolderAccessibleName"));
- UIManager.put("FileChooser.homeFolderToolTipText", AppStrings.translate("FileChooser.homeFolderToolTipText"));
- UIManager.put("FileChooser.homeFolderAccessibleName", AppStrings.translate("FileChooser.homeFolderAccessibleName"));
- UIManager.put("FileChooser.fileNameHeaderText", AppStrings.translate("FileChooser.fileNameHeaderText"));
- UIManager.put("FileChooser.fileSizeHeaderText", AppStrings.translate("FileChooser.fileSizeHeaderText"));
- UIManager.put("FileChooser.fileTypeHeaderText", AppStrings.translate("FileChooser.fileTypeHeaderText"));
- UIManager.put("FileChooser.fileDateHeaderText", AppStrings.translate("FileChooser.fileDateHeaderText"));
- UIManager.put("FileChooser.fileAttrHeaderText", AppStrings.translate("FileChooser.fileAttrHeaderText"));
- UIManager.put("FileChooser.openDialogTitleText", AppStrings.translate("FileChooser.openDialogTitleText"));
- UIManager.put("FileChooser.directoryDescriptionText", AppStrings.translate("FileChooser.directoryDescriptionText"));
- UIManager.put("FileChooser.directoryOpenButtonText", AppStrings.translate("FileChooser.directoryOpenButtonText"));
- UIManager.put("FileChooser.directoryOpenButtonToolTipText", AppStrings.translate("FileChooser.directoryOpenButtonToolTipText"));
- UIManager.put("FileChooser.fileDescriptionText", AppStrings.translate("FileChooser.fileDescriptionText"));
- UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
- UIManager.put("FileChooser.helpButtonText", AppStrings.translate("FileChooser.helpButtonText"));
- UIManager.put("FileChooser.helpButtonToolTipText", AppStrings.translate("FileChooser.helpButtonToolTipText"));
- UIManager.put("FileChooser.newFolderAccessibleName", AppStrings.translate("FileChooser.newFolderAccessibleName"));
- UIManager.put("FileChooser.newFolderErrorText", AppStrings.translate("FileChooser.newFolderErrorText"));
- UIManager.put("FileChooser.newFolderToolTipText", AppStrings.translate("FileChooser.newFolderToolTipText"));
- UIManager.put("FileChooser.other.newFolder", AppStrings.translate("FileChooser.other.newFolder"));
- UIManager.put("FileChooser.other.newFolder.subsequent", AppStrings.translate("FileChooser.other.newFolder.subsequent"));
- UIManager.put("FileChooser.win32.newFolder", AppStrings.translate("FileChooser.win32.newFolder"));
- UIManager.put("FileChooser.win32.newFolder.subsequent", AppStrings.translate("FileChooser.win32.newFolder.subsequent"));
- UIManager.put("FileChooser.saveButtonText", AppStrings.translate("FileChooser.saveButtonText"));
- UIManager.put("FileChooser.saveButtonToolTipText", AppStrings.translate("FileChooser.saveButtonToolTipText"));
- UIManager.put("FileChooser.saveDialogTitleText", AppStrings.translate("FileChooser.saveDialogTitleText"));
- UIManager.put("FileChooser.saveInLabelText", AppStrings.translate("FileChooser.saveInLabelText"));
- UIManager.put("FileChooser.updateButtonText", AppStrings.translate("FileChooser.updateButtonText"));
- UIManager.put("FileChooser.updateButtonToolTipText", AppStrings.translate("FileChooser.updateButtonToolTipText"));
-
- UIManager.put("FileChooser.detailsViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.detailsViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewButtonToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.fileAttrHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileAttrHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileDateHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileDateHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileNameHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileNameHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.fileNameLabel.textAndMnemonic"));
- UIManager.put("FileChooser.fileSizeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileSizeHeader.textAndMnemonic"));
- UIManager.put("FileChooser.fileTypeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileTypeHeader.textAndMnemonic"));
- UIManager.put("FileChooser.filesOfTypeLabel.textAndMnemonic", AppStrings.translate("FileChooser.filesOfTypeLabel.textAndMnemonic"));
- UIManager.put("FileChooser.folderNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.folderNameLabel.textAndMnemonic"));
- UIManager.put("FileChooser.homeFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.homeFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.listViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.listViewActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.listViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.listViewButtonToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.lookInLabel.textAndMnemonic", AppStrings.translate("FileChooser.lookInLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.newFolderActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.newFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.refreshActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.refreshActionLabel.textAndMnemonic"));
- UIManager.put("FileChooser.saveInLabel.textAndMnemonic", AppStrings.translate("FileChooser.saveInLabel.textAndMnemonic"));
- UIManager.put("FileChooser.upFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.upFolderToolTip.textAndMnemonic"));
- UIManager.put("FileChooser.viewMenuButtonAccessibleName", AppStrings.translate("FileChooser.viewMenuButtonAccessibleName"));
- UIManager.put("FileChooser.viewMenuButtonToolTipText", AppStrings.translate("FileChooser.viewMenuButtonToolTipText"));
- UIManager.put("FileChooser.viewMenuLabel.textAndMnemonic", AppStrings.translate("FileChooser.viewMenuLabel.textAndMnemonic"));
- UIManager.put("FileChooser.newFolderActionLabelText", AppStrings.translate("FileChooser.newFolderActionLabelText"));
- UIManager.put("FileChooser.listViewActionLabelText", AppStrings.translate("FileChooser.listViewActionLabelText"));
- UIManager.put("FileChooser.detailsViewActionLabelText", AppStrings.translate("FileChooser.detailsViewActionLabelText"));
- UIManager.put("FileChooser.refreshActionLabelText", AppStrings.translate("FileChooser.refreshActionLabelText"));
- UIManager.put("FileChooser.sortMenuLabelText", AppStrings.translate("FileChooser.sortMenuLabelText"));
- UIManager.put("FileChooser.viewMenuLabelText", AppStrings.translate("FileChooser.viewMenuLabelText"));
- UIManager.put("FileChooser.fileSizeKiloBytes", AppStrings.translate("FileChooser.fileSizeKiloBytes"));
- UIManager.put("FileChooser.fileSizeMegaBytes", AppStrings.translate("FileChooser.fileSizeMegaBytes"));
- UIManager.put("FileChooser.fileSizeGigaBytes", AppStrings.translate("FileChooser.fileSizeGigaBytes"));
- UIManager.put("FileChooser.folderNameLabelText", AppStrings.translate("FileChooser.folderNameLabelText"));
-
- UIManager.put("ColorChooser.okText", AppStrings.translate("ColorChooser.okText"));
- UIManager.put("ColorChooser.cancelText", AppStrings.translate("ColorChooser.cancelText"));
- UIManager.put("ColorChooser.resetText", AppStrings.translate("ColorChooser.resetText"));
- UIManager.put("ColorChooser.previewText", AppStrings.translate("ColorChooser.previewText"));
- UIManager.put("ColorChooser.swatchesNameText", AppStrings.translate("ColorChooser.swatchesNameText"));
- UIManager.put("ColorChooser.swatchesRecentText", AppStrings.translate("ColorChooser.swatchesRecentText"));
- UIManager.put("ColorChooser.sampleText", AppStrings.translate("ColorChooser.sampleText"));
-
- }
-
- public static void initLang() {
- if (!Configuration.locale.hasValue()) {
- if (Platform.isWindows()) {
- //Load from Installer
- String uninstKey = "{E618D276-6596-41F4-8A98-447D442A77DB}_is1";
- uninstKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uninstKey;
- try {
- if (Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey)) {
- if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language")) {
- String installedLoc = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language");
- int lcid = Integer.parseInt(installedLoc);
- char buf[] = new char[9];
- int cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO639LANGNAME, buf, 9);
- String langCode = new String(buf, 0, cnt).trim().toLowerCase();
-
- cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO3166CTRYNAME, buf, 9);
- String countryCode = new String(buf, 0, cnt).trim().toLowerCase();
-
- List langs = Arrays.asList(SelectLanguageDialog.getAvailableLanguages());
- for (int i = 0; i < langs.size(); i++) {
- langs.set(i, langs.get(i).toLowerCase());
- }
-
- String selectedLang = null;
-
- if (langs.contains(langCode + "-" + countryCode)) {
- selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode + "-" + countryCode)];
- } else if (langs.contains(langCode)) {
- selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode)];
- }
- if (selectedLang != null) {
- Configuration.locale.set(selectedLang);
- }
- }
- }
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get()));
- AppStrings.updateLanguage();
-
- Helper.decompilationErrorAdd = AppStrings.translate(Configuration.autoDeobfuscate.get() ? "deobfuscation.comment.failed" : "deobfuscation.comment.tryenable");
- }
-
- /**
- * Clear old FFDec/JavactiveX temp files
- */
- private static void clearTemp() {
- String tempDirPath = System.getProperty("java.io.tmpdir");
- if (tempDirPath == null) {
- return;
- }
- File tempDir = new File(tempDirPath);
- if (!tempDir.exists()) {
- return;
- }
- File delFiles[] = tempDir.listFiles(new FilenameFilter() {
-
- @Override
- public boolean accept(File dir, String name) {
- return name.matches("ffdec_cache.*\\.tmp") || name.matches("javactivex_.*\\.exe") || name.matches("temp[0-9]+\\.swf") || name.matches("ffdec_view_.*\\.swf");
- }
- });
-
- if (delFiles != null) {
- for (File f : delFiles) {
- try {
- f.delete();
- } catch (Exception ex) {
- //ignore
- }
- }
- }
- }
-
- /**
- * @param args the command line arguments
- * @throws IOException On error
- */
- public static void main(String[] args) throws IOException {
- setSessionLoaded(false);
- clearTemp();
-
- try {
- SWFDecompilerPlugin.loadPlugins();
- } catch (Throwable ex) {
- logger.log(Level.SEVERE, "Failed to load plugins", ex);
- }
-
- AppStrings.setResourceClass(MainFrame.class);
- initLogging(Configuration._debugMode.get());
-
- initLang();
-
- if (Configuration.cacheOnDisk.get()) {
- Cache.setStorageType(Cache.STORAGE_FILES);
- } else {
- Cache.setStorageType(Cache.STORAGE_MEMORY);
- }
-
- if (args.length == 0) {
- initGui();
- View.execInEventDispatch(() -> {
- if (Configuration.allowOnlyOneInstance.get() && FirstInstance.focus()) { //Try to focus first instance
- Main.exit();
- } else {
- showModeFrame();
- reloadLastSession();
- }
- });
- } else {
- setSessionLoaded(true);
- String[] filesToOpen = CommandLineArgumentParser.parseArguments(args);
- if (filesToOpen != null && filesToOpen.length > 0) {
- View.execInEventDispatch(() -> {
- initGui();
- shouldCloseWhenClosingLoadingDialog = true;
- if (Configuration.allowOnlyOneInstance.get() && FirstInstance.openFiles(Arrays.asList(filesToOpen))) { //Try to open in first instance
- Main.exit();
- } else {
- for (String fileToOpen : filesToOpen) {
- openFile(fileToOpen, null);
- }
- }
- });
- }
- }
- }
-
- private static void reloadLastSession() {
- boolean openingFiles = false;
- if (Configuration.saveSessionOnExit.get()) {
- String lastSession = Configuration.lastSessionFiles.get();
- if (lastSession != null && lastSession.length() > 0) {
- String[] filesToOpen = lastSession.split(File.pathSeparator, -1);
- List exfiles = new ArrayList<>();
- List extitles = new ArrayList<>();
- String lastSessionTitles = Configuration.lastSessionFileTitles.get();
- String fileTitles[] = new String[0];
- if (lastSessionTitles != null && !lastSessionTitles.isEmpty()) {
- fileTitles = lastSessionTitles.split(File.pathSeparator, -1);
- }
- for (int i = 0; i < filesToOpen.length; i++) {
- if (new File(filesToOpen[i]).exists()) {
- exfiles.add(filesToOpen[i]);
- if (fileTitles.length > i) {
- extitles.add(fileTitles[i]);
- } else {
- extitles.add(null);
- }
- }
- }
- SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()];
- for (int i = 0; i < exfiles.size(); i++) {
- String extitle = extitles.get(i);
- sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
- }
- if (sourceInfos.length > 0) {
- openingFiles = true;
- openFile(sourceInfos, () -> {
- mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get());
- setSessionLoaded(true);
- });
- }
- }
- }
-
- if (!openingFiles) {
- setSessionLoaded(true);
- }
- }
-
- public static String tempFile(String url) throws IOException {
- File f = new File(Configuration.getFFDecHome() + "saved" + File.separator);
- Path.createDirectorySafe(f);
- return Configuration.getFFDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
- }
-
- public static void removeTrayIcon() {
- if (SystemTray.isSupported()) {
- SystemTray tray = SystemTray.getSystemTray();
- if (trayIcon != null) {
- tray.remove(trayIcon);
- trayIcon = null;
- }
- }
- }
-
- public static void switchProxy() {
- proxyFrame.switchState();
- if (stopMenuItem != null) {
- if (proxyFrame.isRunning()) {
- stopMenuItem.setLabel(AppStrings.translate("proxy.stop"));
- } else {
- stopMenuItem.setLabel(AppStrings.translate("proxy.start"));
- }
- }
- }
-
- public static void addTrayIcon() {
- if (trayIcon != null) {
- return;
- }
- if (SystemTray.isSupported()) {
- SystemTray tray = SystemTray.getSystemTray();
- trayIcon = new TrayIcon(View.loadImage("proxy16"), ApplicationInfo.VENDOR + " " + ApplicationInfo.SHORT_APPLICATION_NAME + " " + AppStrings.translate("proxy"));
- trayIcon.setImageAutoSize(true);
- PopupMenu trayPopup = new PopupMenu();
-
- ActionListener trayListener = new ActionListener() {
- /**
- * Invoked when an action occurs.
- */
- @Override
- public void actionPerformed(ActionEvent e) {
- if (e.getActionCommand().equals("EXIT")) {
- Main.exit();
- }
- if (e.getActionCommand().equals("SHOW")) {
- Main.showProxy();
- }
- if (e.getActionCommand().equals("SWITCH")) {
- Main.switchProxy();
- }
- }
- };
-
- MenuItem showMenuItem = new MenuItem(AppStrings.translate("proxy.show"));
- showMenuItem.setActionCommand("SHOW");
- showMenuItem.addActionListener(trayListener);
- trayPopup.add(showMenuItem);
- stopMenuItem = new MenuItem(AppStrings.translate("proxy.start"));
- stopMenuItem.setActionCommand("SWITCH");
- stopMenuItem.addActionListener(trayListener);
- trayPopup.add(stopMenuItem);
- trayPopup.addSeparator();
- MenuItem exitMenuItem = new MenuItem(AppStrings.translate("exit"));
- exitMenuItem.setActionCommand("EXIT");
- exitMenuItem.addActionListener(trayListener);
- trayPopup.add(exitMenuItem);
-
- trayIcon.setPopupMenu(trayPopup);
- trayIcon.addMouseListener(new MouseAdapter() {
- /**
- * {@inheritDoc}
- */
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getButton() == MouseEvent.BUTTON1) {
- Main.showProxy();
- }
- }
- });
- try {
- tray.add(trayIcon);
- } catch (AWTException ex) {
- }
- }
- }
-
- public static void exit() {
- Configuration.saveConfig();
- if (mainFrame != null && mainFrame.getPanel() != null) {
- mainFrame.getPanel().unloadFlashPlayer();
- mainFrame.dispose();
- }
- if (fileTxt != null) {
- try {
- fileTxt.flush();
- fileTxt.close();
- } catch (Exception ex) {
- //ignore
- }
- }
- System.exit(0);
- }
-
- public static void about() {
- (new AboutDialog()).setVisible(true);
- }
-
- public static void advancedSettings() {
- advancedSettings(null);
- }
-
- public static void advancedSettings(String category) {
- (new AdvancedSettingsDialog(category)).setVisible(true);
- }
-
- public static void autoCheckForUpdates() {
- if (Configuration.checkForUpdatesAuto.get()) {
- Calendar lastUpdatesCheckDate = Configuration.lastUpdatesCheckDate.get();
- if ((lastUpdatesCheckDate == null) || (lastUpdatesCheckDate.getTime().getTime() < Calendar.getInstance().getTime().getTime() - Configuration.checkForUpdatesDelay.get())) {
- new SwingWorker() {
- @Override
- protected Object doInBackground() throws Exception {
- checkForUpdates();
- return null;
- }
- }.execute();
- }
- }
- }
-
- public static boolean checkForUpdates() {
- String currentVersion = ApplicationInfo.version;
- if (currentVersion.equals("unknown")) {
- // sometimes during development the version information is not available
- return false;
- }
-
- List accepted = new ArrayList<>();
- if (Configuration.checkForUpdatesStable.get()) {
- accepted.add("stable");
- }
- if (Configuration.checkForUpdatesNightly.get()) {
- accepted.add("nightly");
- }
-
- if (accepted.isEmpty()) {
- return false;
- }
-
- String acceptVersions = String.join(",", accepted);
- try {
- String proxyAddress = Configuration.updateProxyAddress.get();
- URL url = new URL(ApplicationInfo.updateCheckUrl);
-
- URLConnection uc;
- if (proxyAddress != null && !proxyAddress.isEmpty()) {
- int port = 8080;
- if (proxyAddress.contains(":")) {
- String[] parts = proxyAddress.split(":");
- port = Integer.parseInt(parts[1]);
- proxyAddress = parts[0];
- }
-
- uc = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, port)));
- } else {
- uc = url.openConnection();
- }
- uc.setRequestProperty("X-Accept-Versions", acceptVersions);
- uc.setRequestProperty("X-Update-Major", "" + UPDATE_SYSTEM_MAJOR);
- uc.setRequestProperty("X-Update-Minor", "" + UPDATE_SYSTEM_MINOR);
- uc.setRequestProperty("User-Agent", ApplicationInfo.shortApplicationVerName);
- String currentLoc = Configuration.locale.get("en");
- uc.setRequestProperty("Accept-Language", currentLoc + ("en".equals(currentLoc) ? "" : ", en;q=0.8"));
-
- uc.connect();
-
- BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
- String s;
- final java.util.List versions = new ArrayList<>();
- String header = "";
- Pattern headerPat = Pattern.compile("\\[([a-zA-Z0-9]+)\\]");
- int updateMajor;
- int updateMinor;
- Version ver = null;
- while ((s = br.readLine()) != null) {
-
- Matcher m = headerPat.matcher(s);
- if (m.matches()) {
- header = m.group(1);
- if (header.equals("version")) {
- ver = new Version();
- versions.add(ver);
- }
- if (header.equals("noversion")) {
- break;
- }
- } else if (s.contains("=")) {
- String key = s.substring(0, s.indexOf('='));
- String val = s.substring(s.indexOf('=') + 1);
- if ("updateSystem".equals(header)) {
- if (key.equals("majorVersion")) {
- updateMajor = Integer.parseInt(val);
- if (updateMajor > UPDATE_SYSTEM_MAJOR) {
- break;
- }
- }
- if (key.equals("minorVersion")) {
- updateMinor = Integer.parseInt(val);
- }
- }
- if ("version".equals(header) && (ver != null)) {
- if (key.equals("versionId")) {
- ver.versionId = Integer.parseInt(val);
- }
- if (key.equals("versionName")) {
- ver.versionName = val;
- }
- if (key.equals("nightly")) {
- ver.nightly = val.equals("true");
- }
- if (key.equals("revision")) {
- ver.revision = val;
- }
- if (key.equals("build")) {
- ver.build = Integer.parseInt(val);
- }
- if (key.equals("major")) {
- ver.major = Integer.parseInt(val);
- }
- if (key.equals("minor")) {
- ver.minor = Integer.parseInt(val);
- }
- if (key.equals("release")) {
- ver.release = Integer.parseInt(val);
- }
- if (key.equals("longVersionName")) {
- ver.longVersionName = val;
- }
- if (key.equals("releaseDate")) {
- ver.releaseDate = val;
- }
- if (key.equals("appName")) {
- ver.appName = val;
- }
- if (key.equals("appFullName")) {
- ver.appFullName = val;
- }
- if (key.equals("updateLink")) {
- ver.updateLink = val;
- }
- if (key.equals("change[]")) {
- String changeType = val.substring(0, val.indexOf('|'));
- String change = val.substring(val.indexOf('|') + 1);
- if (!ver.changes.containsKey(changeType)) {
- ver.changes.put(changeType, new ArrayList<>());
- }
- List chlist = ver.changes.get(changeType);
- chlist.add(change);
- }
- }
- }
- }
-
- if (!versions.isEmpty()) {
- View.execInEventDispatch(() -> {
- NewVersionDialog newVersionDialog = new NewVersionDialog(versions);
- newVersionDialog.setVisible(true);
- Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
- });
-
- return true;
- }
- } catch (IOException | NumberFormatException ex) {
- return false;
- }
- Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
- return false;
- }
-
- private static FileHandler fileTxt;
-
- public static void clearLogFile() {
- Logger logger = Logger.getLogger("");
-
- FileHandler oldFileTxt = fileTxt;
- fileTxt = null;
- if (oldFileTxt != null) {
- logger.removeHandler(fileTxt);
- oldFileTxt.flush();
- oldFileTxt.close();
- }
-
- String fileName = null;
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
-
- try {
- fileName = Configuration.getFFDecHome() + "logs" + File.separator;
- if (Configuration.useDetailedLogging.get()) {
- fileName += "log-" + sdf.format(new Date()) + ".txt";
- } else {
- fileName += "log.txt";
- }
- File f = new File(fileName).getParentFile();
- if (!f.exists()) {
- f.mkdir();
- }
- fileTxt = new FileHandler(fileName);
- } catch (IOException | SecurityException ex) {
- //cannot get lock error
- if (ex.getMessage().contains("lock for")) {
- //remove all old log files and their .lck
- for (int i = 0; i <= 100; i++) {
- File flog = new File(fileName + (i == 0 ? "" : "." + i));
- File flog_lock = new File(fileName + (i == 0 ? "" : "." + i) + ".lck");
- flog.delete();
- flog_lock.delete();
- }
- try {
- fileTxt = new FileHandler(fileName);
- } catch (IOException | SecurityException ex1) {
- logger.log(Level.SEVERE, "Cannot initialize logging", ex);
- }
- } else {
- logger.log(Level.SEVERE, "Cannot initialize logging", ex);
- }
- }
-
- Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
-
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- logger.log(Level.SEVERE, "Uncaught exception in thread: " + t.getName(), e);
- if (e instanceof OutOfMemoryError || !Helper.is64BitJre() && Helper.is64BitOs()) {
- View.showMessageDialog(null, AppStrings.translate("message.warning.outOfMemory32BitJre"), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE);
- }
- }
- });
-
- Formatter formatterTxt = new LogFormatter();
- if (fileTxt != null) {
- fileTxt.setFormatter(formatterTxt);
- logger.addHandler(fileTxt);
- }
-
- if (!GraphicsEnvironment.isHeadless() && ErrorLogFrame.hasInstance()) {
- ErrorLogFrame.getInstance().clearErrorState();
- }
-
- sdf = new SimpleDateFormat("yyyy-MM-dd");
- logger.log(Level.INFO, "Date: {0}", sdf.format(new Date()));
- logger.log(Level.INFO, ApplicationInfo.applicationVerName);
- logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
- System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")});
- logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
- System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("os.arch")});
- }
-
- public static void initLogging(boolean debug) {
- try {
- Logger logger = Logger.getLogger("");
- logger.setLevel(Configuration.logLevel);
-
- Handler[] handlers = logger.getHandlers();
- for (int i = handlers.length - 1; i >= 0; i--) {
- logger.removeHandler(handlers[i]);
- }
-
- ConsoleHandler conHan = new ConsoleHandler();
- conHan.setLevel(debug ? Level.CONFIG : Level.WARNING);
- SimpleFormatter formatterTxt = new SimpleFormatter();
- conHan.setFormatter(formatterTxt);
- logger.addHandler(conHan);
- clearLogFile();
-
- } catch (Exception ex) {
- throw new RuntimeException("Problems with creating the log files");
- }
- }
-}
+/*
+ * Copyright (C) 2010-2016 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.gui;
+
+import com.jpexs.debugger.flash.Debugger;
+import com.jpexs.debugger.flash.DebuggerCommands;
+import com.jpexs.debugger.flash.Variable;
+import com.jpexs.decompiler.flash.ApplicationInfo;
+import com.jpexs.decompiler.flash.EventListener;
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFBundle;
+import com.jpexs.decompiler.flash.SWFSourceInfo;
+import com.jpexs.decompiler.flash.SearchMode;
+import com.jpexs.decompiler.flash.SwfOpenException;
+import com.jpexs.decompiler.flash.UrlResolver;
+import com.jpexs.decompiler.flash.Version;
+import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
+import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
+import com.jpexs.decompiler.flash.configuration.Configuration;
+import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
+import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
+import com.jpexs.decompiler.flash.console.ContextMenuTools;
+import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
+import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
+import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
+import com.jpexs.decompiler.flash.gui.pipes.FirstInstance;
+import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
+import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
+import com.jpexs.decompiler.flash.tags.Tag;
+import com.jpexs.decompiler.flash.tags.base.FontTag;
+import com.jpexs.decompiler.flash.tags.base.ImportTag;
+import com.jpexs.decompiler.flash.treeitems.SWFList;
+import com.jpexs.helpers.Cache;
+import com.jpexs.helpers.CancellableWorker;
+import com.jpexs.helpers.Helper;
+import com.jpexs.helpers.Path;
+import com.jpexs.helpers.ProgressListener;
+import com.jpexs.helpers.Stopwatch;
+import com.jpexs.helpers.streams.SeekableInputStream;
+import com.sun.jna.Platform;
+import com.sun.jna.platform.win32.Advapi32Util;
+import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.WinReg;
+import java.awt.AWTException;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.MenuItem;
+import java.awt.PopupMenu;
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedInputStream;
+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.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.FileHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingWorker;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.filechooser.FileFilter;
+import org.pushingpixels.substance.api.SubstanceLookAndFeel;
+
+/**
+ * Main executable class
+ *
+ * @author JPEXS
+ */
+public class Main {
+
+ protected static ProxyFrame proxyFrame;
+
+ private static List sourceInfos = new ArrayList<>();
+
+ public static LoadingDialog loadingDialog;
+
+ private static boolean working = false;
+
+ private static TrayIcon trayIcon;
+
+ private static MenuItem stopMenuItem;
+
+ private static volatile MainFrame mainFrame;
+
+ public static final int UPDATE_SYSTEM_MAJOR = 1;
+
+ public static final int UPDATE_SYSTEM_MINOR = 3;
+
+ private static LoadFromMemoryFrame loadFromMemoryFrame;
+
+ private static LoadFromCacheFrame loadFromCacheFrame;
+
+ private static final Logger logger = Logger.getLogger(Main.class.getName());
+
+ public static DebugLogDialog debugDialog;
+
+ public static boolean shouldCloseWhenClosingLoadingDialog;
+
+ private static Debugger flashDebugger;
+
+ private static DebuggerHandler debugHandler = null;
+
+ //private static int ip = 0;
+ //private static String ipClass = null;
+ private static Process runProcess;
+
+ private static boolean runProcessDebug;
+
+ private static boolean runProcessDebugPCode;
+
+ private static boolean inited = false;
+
+ private static File runTempFile;
+
+ private static List runTempFiles = new ArrayList<>();
+
+ public static void freeRun() {
+ synchronized (Main.class) {
+ if (runTempFile != null) {
+ runTempFile.delete();
+ runTempFile = null;
+ }
+ for (File f : runTempFiles) {
+ f.delete();
+ }
+ runTempFiles.clear();
+
+ runProcess = null;
+ }
+ if (mainFrame != null && mainFrame.getPanel() != null) {
+ mainFrame.getPanel().clearDebuggerColors();
+ }
+ if (runProcessDebug) {
+ Main.getDebugHandler().disconnect();
+ }
+ }
+
+ public static synchronized boolean isDebugPaused() {
+ return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
+ }
+
+ public static synchronized boolean isDebugRunning() {
+ return runProcess != null && runProcessDebug;
+ }
+
+ public static synchronized boolean isDebugPCode() {
+ return runProcessDebugPCode;
+ }
+
+ public static synchronized boolean isDebugConnected() {
+ return getDebugHandler().isConnected();
+ }
+
+ public static synchronized boolean isRunning() {
+ return runProcess != null && !runProcessDebug;
+ }
+
+ public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
+ DebuggerCommands.Watch w = getDebugHandler().addWatch(v, v_id, watchRead, watchWrite);
+ return w != null;
+ }
+
+ public static void runPlayer(String title, final String exePath, String file, String flashVars) {
+ if (!new File(file).exists()) {
+ return;
+ }
+ if (flashVars != null && !flashVars.isEmpty()) {
+ file += "?" + flashVars;
+ }
+ final String ffile = file;
+
+ CancellableWorker runWorker = new CancellableWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+ Process proc;
+ try {
+ proc = Runtime.getRuntime().exec(new String[]{exePath, ffile});
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ return null;
+ }
+ boolean isDebug;
+
+ synchronized (Main.class) {
+ runProcess = proc;
+ isDebug = runProcessDebug;
+ }
+ if (isDebug) {
+ mainFrame.getMenu().hilightPath("/debugging");
+ }
+ mainFrame.getMenu().updateComponents();
+ try {
+ if (proc != null) {
+ proc.waitFor();
+ }
+ } catch (InterruptedException ex) {
+ if (proc != null) {
+ try {
+ proc.destroy();
+ } catch (Exception ex2) {
+ //ignore
+ }
+ }
+ }
+ freeRun();
+ stopDebugger();
+ mainFrame.getMenu().updateComponents();
+ return null;
+ }
+
+ @Override
+ protected void done() {
+ Main.stopWork();
+ }
+
+ @Override
+ public void workerCancelled() {
+ Main.stopWork();
+ synchronized (Main.class) {
+ if (runProcess != null) {
+ try {
+ runProcess.destroy();
+ } catch (Exception ex) {
+
+ }
+ }
+ }
+ freeRun();
+ mainFrame.getMenu().updateComponents();
+ }
+ };
+
+ mainFrame.getMenu().updateComponents();
+ Main.startWork(title + "...", runWorker);
+ runWorker.execute();
+ }
+
+ public static void stopRun() {
+
+ synchronized (Main.class) {
+ if (runProcess != null) {
+ runProcess.destroy();
+ }
+ }
+ freeRun();
+ stopDebugger();
+ mainFrame.getMenu().updateComponents();
+ }
+
+ private static interface SwfPreparation {
+
+ public SWF prepare(SWF swf);
+ }
+
+ private static class SwfRunPrepare implements SwfPreparation {
+
+ @Override
+ public SWF prepare(SWF swf) {
+ if (Configuration.autoOpenLoadedSWFs.get()) {
+ if (!DebuggerTools.hasDebugger(swf)) {
+ DebuggerTools.switchDebugger(swf);
+ }
+ DebuggerTools.injectDebugLoader(swf);
+ }
+ return swf;
+ }
+ }
+
+ private static class SwfDebugPrepare extends SwfRunPrepare {
+
+ private boolean doPCode;
+
+ public SwfDebugPrepare(boolean doPCode) {
+ this.doPCode = doPCode;
+ }
+
+ @Override
+ public SWF prepare(SWF instrSWF) {
+ instrSWF = super.prepare(instrSWF);
+ try {
+ File fTempFile = new File(instrSWF.getFile());
+ instrSWF.enableDebugging(true, new File("."), true, doPCode);
+ FileOutputStream fos = new FileOutputStream(fTempFile);
+ instrSWF.saveTo(fos);
+ fos.close();
+ if (!instrSWF.isAS3()) {
+ //Read again, because line file offsets changed with adding debug tags
+ //TODO: handle somehow without rereading?
+ instrSWF = null;
+ try (FileInputStream fis = new FileInputStream(fTempFile)) {
+ instrSWF = new SWF(fis, false, false);
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ if (instrSWF != null) {
+ String swfFileName = fTempFile.getAbsolutePath();
+ if (swfFileName.toLowerCase().endsWith(".swf")) {
+ swfFileName = swfFileName.substring(0, swfFileName.length() - 4) + ".swd";
+ } else {
+ swfFileName = swfFileName + ".swd";
+ }
+ File swdFile = new File(swfFileName);
+ if (doPCode) {
+ instrSWF.generatePCodeSwdFile(swdFile, getPackBreakPoints(true));
+ } else {
+ instrSWF.generateSwdFile(swdFile, getPackBreakPoints(true));
+ }
+ }
+ }
+ } catch (IOException ex) {
+ //ignore, return instrSWF
+ }
+ return instrSWF;
+ }
+ }
+
+ private static void prepareSwf(SwfPreparation prep, File toPrepareFile, File origFile, List tempFiles) throws IOException {
+ SWF instrSWF = null;
+ try (FileInputStream fis = new FileInputStream(toPrepareFile)) {
+ instrSWF = new SWF(fis, toPrepareFile.getAbsolutePath(), origFile.getName(), false);
+ } catch (InterruptedException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ if (instrSWF != null) {
+ for (Tag t : instrSWF.getLocalTags()) {
+ if (t instanceof ImportTag) {
+ ImportTag it = (ImportTag) t;
+ String url = it.getUrl();
+ File importedFile = new File(origFile.getParentFile(), url);
+ if (importedFile.exists()) {
+ File newTempFile = File.createTempFile("ffdec_run_import_", ".swf");
+ it.setUrl("./" + newTempFile.getName());
+ byte[] impData = Helper.readFile(importedFile.getAbsolutePath());
+ Helper.writeFile(newTempFile.getAbsolutePath(), impData);
+ tempFiles.add(newTempFile);
+ prepareSwf(prep, newTempFile, importedFile, tempFiles);
+ }
+ }
+ }
+ if (prep != null) {
+ instrSWF = prep.prepare(instrSWF);
+ }
+ try (FileOutputStream fos = new FileOutputStream(toPrepareFile)) {
+ instrSWF.saveTo(fos);
+ }
+ }
+ }
+
+ public static void run(SWF swf) {
+ String flashVars = "";//key=val&key2=val2
+ String playerLocation = Configuration.playerLocation.get();
+ if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
+ View.showMessageDialog(null, AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ advancedSettings("paths");
+ return;
+ }
+ if (swf == null) {
+ return;
+ }
+ File tempFile;
+ List tempFiles = new ArrayList<>();
+ try {
+ tempFile = File.createTempFile("ffdec_run_", ".swf");
+
+ try (FileOutputStream fos = new FileOutputStream(tempFile)) {
+ swf.saveTo(fos);
+ }
+
+ prepareSwf(new SwfRunPrepare(), tempFile, new File(swf.getFile()), tempFiles);
+
+ } catch (IOException ex) {
+ return;
+
+ }
+ if (tempFile != null) {
+ synchronized (Main.class) {
+ runTempFile = tempFile;
+ runTempFiles = tempFiles;
+ runProcessDebug = false;
+ }
+ runPlayer(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
+ }
+ }
+
+ public static void runDebug(SWF swf, final boolean doPCode) {
+ String flashVars = "";//key=val&key2=val2
+ String playerLocation = Configuration.playerDebugLocation.get();
+ if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
+ View.showMessageDialog(null, AppStrings.translate("message.playerpath.debug.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
+ Main.advancedSettings("paths");
+ return;
+ }
+ if (swf == null) {
+ return;
+ }
+ File tempFile = null;
+
+ try {
+ tempFile = File.createTempFile("ffdec_debug_", ".swf");
+ } catch (Exception ex) {
+
+ }
+
+ if (tempFile != null) {
+ final File fTempFile = tempFile;
+ final List tempFiles = new ArrayList<>();
+ CancellableWorker instrumentWorker = new CancellableWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+
+ try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
+ swf.saveTo(fos);
+ }
+ prepareSwf(new SwfDebugPrepare(doPCode), fTempFile, new File(swf.getFile()), tempFiles);
+ return null;
+ }
+
+ @Override
+ public void workerCancelled() {
+ Main.stopWork();
+ }
+
+ @Override
+ protected void done() {
+ synchronized (Main.class) {
+ runTempFile = fTempFile;
+ runProcessDebug = true;
+ runProcessDebugPCode = doPCode;
+ runTempFiles = tempFiles;
+ }
+ Main.stopWork();
+ Main.startDebugger();
+ runPlayer(AppStrings.translate("work.debugging.wait"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
+ }
+ };
+
+ Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
+ instrumentWorker.execute();
+ }
+ }
+
+ /* public static void debuggerNotSuspended() {
+
+ }*/
+ public static boolean isDebugging() {
+ return isDebugRunning();
+ }
+
+ public synchronized static int getIp(Object pack) {
+ return getDebugHandler().getBreakIp();
+ }
+
+ public synchronized static String getIpClass() {
+ return getDebugHandler().getBreakScriptName();
+ }
+
+ public static synchronized boolean isBreakPointValid(String scriptName, int line) {
+ return !getDebugHandler().isBreakpointInvalid(scriptName, line);
+ }
+
+ public synchronized static void addBreakPoint(String scriptName, int line) {
+ getDebugHandler().addBreakPoint(scriptName, line);
+ }
+
+ public synchronized static void removeBreakPoint(String scriptName, int line) {
+ getDebugHandler().removeBreakPoint(scriptName, line);
+ }
+
+ public synchronized static boolean toggleBreakPoint(String scriptName, int line) {
+ if (getDebugHandler().isBreakpointToAdd(scriptName, line) || getDebugHandler().isBreakpointConfirmed(scriptName, line) || getDebugHandler().isBreakpointInvalid(scriptName, line)) {
+ getDebugHandler().removeBreakPoint(scriptName, line);
+ return false;
+ } else {
+ getDebugHandler().addBreakPoint(scriptName, line);
+ return true;
+ }
+ }
+
+ public synchronized static Map> getPackBreakPoints(boolean validOnly) {
+ return getDebugHandler().getAllBreakPoints(validOnly);
+ }
+
+ public synchronized static Set getScriptBreakPoints(String pack, boolean onlyValid) {
+ return getDebugHandler().getBreakPoints(pack, onlyValid);
+ }
+
+ public static DebuggerHandler getDebugHandler() {
+ return debugHandler;
+ }
+
+ public static void ensureMainFrame() {
+ if (mainFrame == null) {
+ synchronized (Main.class) {
+ if (mainFrame == null) {
+ MainFrame frame;
+ if (Configuration.useRibbonInterface.get()) {
+ frame = new MainFrameRibbon();
+ } else {
+ frame = new MainFrameClassic();
+ }
+ frame.getPanel().setErrorState(ErrorLogFrame.getInstance().getErrorState());
+ mainFrame = frame;
+ }
+ }
+ }
+ }
+
+ public static MainFrame getMainFrame() {
+ return mainFrame;
+ }
+
+ public static void loadFromCache() {
+ if (loadFromCacheFrame == null) {
+ loadFromCacheFrame = new LoadFromCacheFrame();
+ }
+ loadFromCacheFrame.setVisible(true);
+ }
+
+ public static void loadFromMemory() {
+ if (loadFromMemoryFrame == null) {
+ loadFromMemoryFrame = new LoadFromMemoryFrame(mainFrame);
+ }
+ loadFromMemoryFrame.setVisible(true);
+ }
+
+ public static void setVariable(long parentId, String varName, int valueType, Object value) {
+ getDebugHandler().setVariable(parentId, varName, valueType, value);
+ }
+
+ public static void setSubLimiter(boolean value) {
+ if (value) {
+ AVM2Code.toSourceLimit = Configuration.sublimiter.get();
+ } else {
+ AVM2Code.toSourceLimit = -1;
+ }
+ }
+
+ public synchronized static boolean isInited() {
+ return inited;
+ }
+
+ public synchronized static void setSessionLoaded(boolean v) {
+ inited = v;
+ }
+
+ public static boolean isWorking() {
+ return working;
+ }
+
+ public static void startProxy(int port) {
+ if (proxyFrame == null) {
+ proxyFrame = new ProxyFrame(mainFrame);
+ }
+
+ proxyFrame.setPort(port);
+ addTrayIcon();
+ switchProxy();
+ }
+
+ public static void showProxy() {
+ if (proxyFrame == null) {
+ proxyFrame = new ProxyFrame(mainFrame);
+ }
+ proxyFrame.setVisible(true);
+ proxyFrame.setState(Frame.NORMAL);
+ }
+
+ public static void startWork(String name, CancellableWorker worker) {
+ startWork(name, -1, worker);
+ }
+
+ public static void startWork(final String name, final int percent, final CancellableWorker worker) {
+ working = true;
+ View.execInEventDispatchLater(() -> {
+ if (mainFrame != null) {
+ mainFrame.getPanel().setWorkStatus(name, worker);
+ if (percent == -1) {
+ mainFrame.getPanel().hidePercent();
+ } else {
+ mainFrame.getPanel().setPercent(percent);
+ }
+ }
+ if (loadingDialog != null) {
+ loadingDialog.setDetail(name);
+ loadingDialog.setPercent(percent);
+ }
+ if (CommandLineArgumentParser.isCommandLineMode()) {
+ System.out.println(name);
+ }
+ });
+ }
+
+ public static void stopWork() {
+ working = false;
+ View.execInEventDispatchLater(() -> {
+ if (mainFrame != null) {
+ mainFrame.getPanel().setWorkStatus("", null);
+ }
+ if (loadingDialog != null) {
+ loadingDialog.setDetail("");
+ }
+ });
+ }
+
+ public static SWFList parseSWF(SWFSourceInfo sourceInfo) throws Exception {
+ SWFList result = new SWFList();
+
+ InputStream inputStream = sourceInfo.getInputStream();
+ SWFBundle bundle = null;
+ FileInputStream fis = null;
+ if (inputStream == null) {
+ inputStream = new BufferedInputStream(fis = new FileInputStream(sourceInfo.getFile()));
+ bundle = sourceInfo.getBundle(false, SearchMode.ALL);
+ logger.log(Level.INFO, "Load file: {0}", sourceInfo.getFile());
+ } else if (inputStream instanceof SeekableInputStream
+ || inputStream instanceof BufferedInputStream) {
+ try {
+ inputStream.reset();
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ logger.log(Level.INFO, "Load stream: {0}", sourceInfo.getFileTitle());
+ }
+
+ Stopwatch sw = Stopwatch.startNew();
+ if (bundle != null) {
+ result.bundle = bundle;
+ result.name = new File(sourceInfo.getFileTitleOrName()).getName();
+ for (Entry streamEntry : bundle.getAll().entrySet()) {
+ InputStream stream = streamEntry.getValue();
+ stream.reset();
+ CancellableWorker worker = new CancellableWorker() {
+ @Override
+ public SWF doInBackground() throws Exception {
+ final CancellableWorker worker = this;
+ SWF swf = new SWF(stream, null, streamEntry.getKey(), new ProgressListener() {
+ @Override
+ public void progress(int p) {
+ startWork(AppStrings.translate("work.reading.swf"), p, worker);
+ }
+ }, Configuration.parallelSpeedUp.get());
+ return swf;
+ }
+ };
+ loadingDialog.setWroker(worker);
+ worker.execute();
+
+ try {
+ result.add(worker.get());
+ } catch (CancellationException ex) {
+ logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", streamEntry.getKey());
+ }
+ }
+ } else {
+ InputStream fInputStream = inputStream;
+
+ final String[] yesno = new String[]{AppStrings.translate("button.yes"), AppStrings.translate("button.no"), AppStrings.translate("button.yes.all"), AppStrings.translate("button.no.all")};
+
+ CancellableWorker worker = new CancellableWorker() {
+ private boolean yestoall = false;
+
+ private boolean notoall = false;
+
+ private SWF open(InputStream is, String file, String fileTitle) throws IOException, InterruptedException {
+ final CancellableWorker worker = this;
+
+ SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
+ @Override
+ public void progress(int p) {
+ startWork(AppStrings.translate("work.reading.swf"), p, worker);
+ }
+ }, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
+ @Override
+ public SWF resolveUrl(final String url) {
+ int opt = -1;
+ if (!(yestoall || notoall)) {
+ opt = View.showOptionDialog(null, AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
+ if (opt == 2) {
+ yestoall = true;
+ }
+ if (opt == 3) {
+ notoall = true;
+ }
+ }
+
+ if (yestoall) {
+ opt = 0; // yes
+ } else if (notoall) {
+ opt = 1; // no
+ }
+
+ if (opt == 1) //no
+ {
+ return null;
+ }
+
+ if (url.startsWith("http://") || url.startsWith("https://")) {
+ try {
+ URL u = new URL(url);
+ return open(u.openStream(), null, url); //?
+ } catch (Exception ex) {
+ //ignore
+ }
+ } else {
+ File f = new File(new File(file).getParentFile(), url);
+ if (f.exists()) {
+ try {
+ return open(new FileInputStream(f), f.getAbsolutePath(), f.getName());
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ Reference ret = new Reference<>(null);
+ View.execInEventDispatch(new Runnable() {
+ @Override
+ public void run() {
+
+ while (JOptionPane.YES_OPTION == View.showConfirmDialog(null, AppStrings.translate("message.imported.swf.manually").replace("%url%", url), AppStrings.translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE)) {
+
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
+ FileFilter allSupportedFilter = new FileFilter() {
+ private final String[] supportedExtensions = new String[]{".swf", ".gfx"};
+
+ @Override
+ public boolean accept(File f) {
+ String name = f.getName().toLowerCase();
+ for (String ext : supportedExtensions) {
+ if (name.endsWith(ext)) {
+ return true;
+ }
+ }
+ return f.isDirectory();
+ }
+
+ @Override
+ public String getDescription() {
+ String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
+ return AppStrings.translate("filter.supported") + " (" + exts + ")";
+ }
+ };
+ fc.setFileFilter(allSupportedFilter);
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+ fc.addChoosableFileFilter(swfFilter);
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+ fc.addChoosableFileFilter(gfxFilter);
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ int returnVal = fc.showOpenDialog(f);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
+ File selFile = Helper.fixDialogFile(fc.getSelectedFile());
+ try {
+ ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
+ break;
+ } catch (Exception ex) {
+ //ignore;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ });
+ return ret.getVal();
+ }
+ });
+ return swf;
+ }
+
+ @Override
+ public SWF doInBackground() throws Exception {
+ return open(fInputStream, sourceInfo.getFile(), sourceInfo.getFileTitle());
+ }
+ };
+ if (loadingDialog != null) {
+ loadingDialog.setWroker(worker);
+ }
+ worker.execute();
+
+ try {
+ result.add(worker.get());
+ } catch (CancellationException ex) {
+ logger.log(Level.WARNING, "Loading SWF {0} was cancelled.", sourceInfo.getFileTitleOrName());
+ }
+ }
+
+ if (fis != null) {
+ logger.log(Level.INFO, "File loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
+ fis.close();
+ } else {
+ logger.log(Level.INFO, "Stream loaded in {0} seconds.", (sw.getElapsedMilliseconds() / 1000));
+ }
+
+ result.sourceInfo = sourceInfo;
+ for (SWF swf : result) {
+ logger.log(Level.INFO, "");
+ logger.log(Level.INFO, "== File information ==");
+ logger.log(Level.INFO, "Size: {0}", Helper.formatFileSize(swf.fileSize));
+ logger.log(Level.INFO, "Flash version: {0}", swf.version);
+ int width = (int) ((swf.displayRect.Xmax - swf.displayRect.Xmin) / SWF.unitDivisor);
+ int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
+ logger.log(Level.INFO, "Width: {0}", width);
+ logger.log(Level.INFO, "Height: {0}", height);
+
+ swf.swfList = result;
+ swf.addEventListener(new EventListener() {
+ @Override
+ public void handleExportingEvent(String type, int index, int count, Object data) {
+ String text = AppStrings.translate("work.exporting");
+ if (type != null && type.length() > 0) {
+ text += " " + type;
+ }
+
+ startWork(text + " " + index + "/" + count + " " + data, null);
+ }
+
+ @Override
+ public void handleExportedEvent(String type, int index, int count, Object data) {
+ String text = AppStrings.translate("work.exported");
+ if (type != null && type.length() > 0) {
+ text += " " + type;
+ }
+
+ startWork(text + " " + index + "/" + count + " " + data, null);
+ }
+
+ @Override
+ public void handleEvent(String event, Object data) {
+ if (event.equals("exporting") || event.equals("exported")) {
+ throw new Error("Event is not supported by this handler.");
+ }
+ if (event.equals("getVariables")) {
+ startWork(AppStrings.translate("work.gettingvariables") + "..." + (String) data, null);
+ }
+ if (event.equals("deobfuscate")) {
+ startWork(AppStrings.translate("work.deobfuscating") + "..." + (String) data, null);
+ }
+ if (event.equals("rename")) {
+ startWork(AppStrings.translate("work.renaming") + "..." + (String) data, null);
+ }
+ }
+ });
+ }
+
+ return result;
+ }
+
+ public static void saveFile(SWF swf, String outfile) throws IOException {
+ saveFile(swf, outfile, SaveFileMode.SAVE, null);
+ }
+
+ public static void saveFile(SWF swf, String outfile, SaveFileMode mode, ExeExportMode exeExportMode) throws IOException {
+ if (mode == SaveFileMode.SAVEAS && !swf.swfList.isBundle()) {
+ swf.setFile(outfile);
+ swf.swfList.sourceInfo.setFile(outfile);
+ }
+ File outfileF = new File(outfile);
+ File tmpFile = new File(outfile + ".tmp");
+ try (FileOutputStream fos = new FileOutputStream(tmpFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos)) {
+ if (mode == SaveFileMode.EXE) {
+ switch (exeExportMode) {
+ case WRAPPER:
+ InputStream exeStream = View.class.getClassLoader().getResourceAsStream("com/jpexs/helpers/resource/Swf2Exe.bin");
+ Helper.copyStream(exeStream, bos);
+ int width = swf.displayRect.Xmax - swf.displayRect.Xmin;
+ int height = swf.displayRect.Ymax - swf.displayRect.Ymin;
+ bos.write(width & 0xff);
+ bos.write((width >> 8) & 0xff);
+ bos.write((width >> 16) & 0xff);
+ bos.write((width >> 24) & 0xff);
+ bos.write(height & 0xff);
+ bos.write((height >> 8) & 0xff);
+ bos.write((height >> 16) & 0xff);
+ bos.write((height >> 24) & 0xff);
+ bos.write(Configuration.saveAsExeScaleMode.get());
+ break;
+ case PROJECTOR_WIN:
+ case PROJECTOR_MAC:
+ case PROJECTOR_LINUX:
+ File projectorFile = Configuration.getProjectorFile(exeExportMode);
+ if (projectorFile == null) {
+ String message = "Projector not found, please place it to " + Configuration.getProjectorPath();
+ logger.log(Level.SEVERE, message);
+ throw new IOException(message);
+ }
+ Helper.copyStream(new FileInputStream(projectorFile), bos);
+ bos.flush();
+ break;
+ }
+ }
+
+ long pos = fos.getChannel().position();
+ swf.saveTo(bos);
+
+ if (mode == SaveFileMode.EXE) {
+ switch (exeExportMode) {
+ case PROJECTOR_WIN:
+ case PROJECTOR_MAC:
+ case PROJECTOR_LINUX:
+ bos.flush();
+ int swfSize = (int) (fos.getChannel().position() - pos);
+
+ // write magic number
+ bos.write(0x56);
+ bos.write(0x34);
+ bos.write(0x12);
+ bos.write(0xfa);
+
+ bos.write(swfSize & 0xff);
+ bos.write((swfSize >> 8) & 0xff);
+ bos.write((swfSize >> 16) & 0xff);
+ bos.write((swfSize >> 24) & 0xff);
+ }
+ }
+ }
+ if (tmpFile.exists()) {
+ if (tmpFile.length() > 0) {
+ outfileF.delete();
+ if (!tmpFile.renameTo(outfileF)) {
+ tmpFile.delete();
+ throw new IOException("Cannot access " + outfile);
+ }
+ } else {
+ throw new IOException("Output is empty");
+ }
+ } else {
+ throw new IOException("Output not found");
+ }
+ }
+
+ private static class OpenFileWorker extends SwingWorker {
+
+ private final SWFSourceInfo[] sourceInfos;
+
+ private final Runnable executeAfterOpen;
+
+ private final int[] reloadIndices;
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo) {
+ this(sourceInfo, -1);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, int reloadIndex) {
+ this(sourceInfo, null, reloadIndex);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
+ this(sourceInfo, executeAfterOpen, -1);
+ }
+
+ public OpenFileWorker(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
+ this.sourceInfos = new SWFSourceInfo[]{sourceInfo};
+ this.executeAfterOpen = executeAfterOpen;
+ this.reloadIndices = new int[]{reloadIndex};
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
+ this(sourceInfos, null, null);
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen) {
+ this(sourceInfos, executeAfterOpen, null);
+ }
+
+ public OpenFileWorker(SWFSourceInfo[] sourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
+ this.sourceInfos = sourceInfos;
+ this.executeAfterOpen = executeAfterOpen;
+ int[] indices = new int[sourceInfos.length];
+ for (int i = 0; i < indices.length; i++) {
+ indices[i] = -1;
+ }
+ this.reloadIndices = reloadIndices == null ? indices : reloadIndices;
+ }
+
+ @Override
+ protected Object doInBackground() throws Exception {
+ boolean first = true;
+ SWF firstSWF = null;
+ for (int index = 0; index < sourceInfos.length; index++) {
+ SWFSourceInfo sourceInfo = sourceInfos[index];
+ SWFList swfs = null;
+ try {
+ Main.startWork(AppStrings.translate("work.reading.swf") + "...", null);
+ try {
+ swfs = parseSWF(sourceInfo);
+ } catch (ExecutionException ex) {
+ Throwable cause = ex.getCause();
+ if (cause instanceof SwfOpenException) {
+ throw (SwfOpenException) cause;
+ }
+
+ throw ex;
+ }
+ } catch (OutOfMemoryError ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
+ continue;
+ } catch (SwfOpenException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, ex.getMessage());
+ continue;
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, null, ex);
+ View.showMessageDialog(null, "Cannot load SWF file.");
+ continue;
+ }
+
+ final SWFList swfs1 = swfs;
+ final boolean first1 = first;
+ first = false;
+ if (firstSWF == null && swfs1.size() > 0) {
+ firstSWF = swfs1.get(0);
+ }
+
+ final int findex = index;
+ try {
+ View.execInEventDispatch(() -> {
+ Main.startWork(AppStrings.translate("work.creatingwindow") + "...", null);
+ ensureMainFrame();
+ if (reloadIndices[findex] > -1) {
+ mainFrame.getPanel().loadSwfAtPos(swfs1, reloadIndices[findex]);
+ } else {
+ mainFrame.getPanel().load(swfs1, first1);
+ }
+ });
+ } catch (Exception ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ }
+
+ loadingDialog.setVisible(false);
+ shouldCloseWhenClosingLoadingDialog = false;
+
+ final SWF fswf = firstSWF;
+ View.execInEventDispatch(() -> {
+ if (mainFrame != null) {
+ mainFrame.setVisible(true);
+ }
+
+ Main.stopWork();
+
+ if (mainFrame != null && Configuration.gotoMainClassOnStartup.get()) {
+ mainFrame.getPanel().gotoDocumentClass(fswf);
+ }
+
+ if (mainFrame != null && fswf != null) {
+ SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortFileName());
+ if (swfConf != null) {
+ String pathStr = swfConf.lastSelectedPath;
+ mainFrame.getPanel().tagTree.setSelectionPathString(pathStr);
+ }
+ }
+
+ if (executeAfterOpen != null) {
+ executeAfterOpen.run();
+ }
+ });
+
+ return true;
+ }
+ }
+
+ public static boolean reloadSWFs() {
+ CancellableWorker.cancelBackgroundThreads();
+ if (Main.sourceInfos.isEmpty()) {
+ Helper.freeMem();
+ showModeFrame();
+ return true;
+ } else {
+ SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
+ sourceInfos.toArray(sourceInfosCopy);
+ sourceInfos.clear();
+ openFile(sourceInfosCopy);
+ return true;
+ }
+ }
+
+ public static void reloadApp() {
+ if (debugDialog != null) {
+ debugDialog.setVisible(false);
+ debugDialog.dispose();
+ debugDialog = null;
+ }
+ if (loadingDialog != null) {
+ synchronized (Main.class) {
+ if (loadingDialog != null) {
+ loadingDialog.setVisible(false);
+ loadingDialog.dispose();
+ loadingDialog = null;
+ }
+ }
+ }
+ if (proxyFrame != null) {
+ proxyFrame.setVisible(false);
+ proxyFrame.dispose();
+ proxyFrame = null;
+ }
+ if (loadFromMemoryFrame != null) {
+ loadFromMemoryFrame.setVisible(false);
+ loadFromMemoryFrame.dispose();
+ loadFromMemoryFrame = null;
+ }
+ if (loadFromCacheFrame != null) {
+ loadFromCacheFrame.setVisible(false);
+ loadFromCacheFrame.dispose();
+ loadFromCacheFrame = null;
+ }
+ if (mainFrame != null) {
+ mainFrame.setVisible(false);
+ mainFrame.getPanel().closeAll(false);
+ mainFrame.dispose();
+ mainFrame = null;
+ }
+ FontTag.reload();
+ Cache.clearAll();
+ initGui();
+ reloadSWFs();
+ }
+
+ public static OpenFileResult openFile(String swfFile, String fileTitle) {
+ return openFile(swfFile, fileTitle, null);
+ }
+
+ public static OpenFileResult openFile(String swfFile, String fileTitle, Runnable executeAfterOpen) {
+ try {
+ File file = new File(swfFile);
+ if (!file.exists()) {
+ View.showMessageDialog(null, AppStrings.translate("open.error.fileNotFound"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
+ return OpenFileResult.NOT_FOUND;
+ }
+ swfFile = file.getCanonicalPath();
+ Configuration.addRecentFile(swfFile);
+ SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
+ OpenFileResult openResult = openFile(sourceInfo);
+ return openResult;
+ } catch (IOException ex) {
+ View.showMessageDialog(null, AppStrings.translate("open.error.cannotOpen"), AppStrings.translate("open.error"), JOptionPane.ERROR_MESSAGE);
+ return OpenFileResult.ERROR;
+ }
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
+ return openFile(new SWFSourceInfo[]{sourceInfo});
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen) {
+ return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo sourceInfo, Runnable executeAfterOpen, int reloadIndex) {
+ return openFile(new SWFSourceInfo[]{sourceInfo}, executeAfterOpen, new int[]{reloadIndex});
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
+ return openFile(newSourceInfos, null);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen) {
+ return openFile(newSourceInfos, executeAfterOpen, null);
+ }
+
+ public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos, Runnable executeAfterOpen, int[] reloadIndices) {
+ if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
+ sourceInfos.clear();
+ mainFrame.getPanel().closeAll(false);
+ mainFrame.setVisible(false);
+ Helper.freeMem();
+ reloadIndices = null;
+ }
+
+ loadingDialog.setVisible(true);
+
+ OpenFileWorker wrk = new OpenFileWorker(newSourceInfos, executeAfterOpen, reloadIndices);
+ wrk.execute();
+ if (reloadIndices == null) {
+ sourceInfos.addAll(Arrays.asList(newSourceInfos));
+ } else {
+ for (int i = 0; i < reloadIndices.length; i++) {
+ sourceInfos.set(reloadIndices[i], newSourceInfos[i]);
+ }
+ }
+ return OpenFileResult.OK;
+ }
+
+ public static void closeFile(SWFList swf) {
+ sourceInfos.remove(swf.sourceInfo);
+ mainFrame.getPanel().close(swf);
+ }
+
+ public static void reloadFile(SWFList swf) {
+ //mainFrame.getPanel().close(swf);
+ openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
+ }
+
+ public static boolean closeAll() {
+ boolean closeResult = mainFrame.getPanel().closeAll(true);
+ if (closeResult) {
+ sourceInfos.clear();
+ }
+
+ return closeResult;
+ }
+
+ public static boolean saveFileDialog(SWF swf, final SaveFileMode mode) {
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(Configuration.lastSaveDir.get()));
+ String ext = ".swf";
+ switch (mode) {
+ case SAVE:
+ case SAVEAS:
+ if (swf.getFile() != null) {
+ ext = Path.getExtension(swf.getFile());
+ }
+ break;
+ case EXE:
+ ext = ".exe";
+ break;
+ }
+
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+
+ ExeExportMode exeExportMode = null;
+ if (mode == SaveFileMode.EXE) {
+ exeExportMode = Configuration.exeExportMode.get();
+ if (exeExportMode == null) {
+ exeExportMode = ExeExportMode.WRAPPER;
+ }
+ String filterDescription = null;
+ switch (exeExportMode) {
+ case WRAPPER:
+ case PROJECTOR_WIN:
+ ext = ".exe";
+ filterDescription = "filter.exe";
+ break;
+ case PROJECTOR_MAC:
+ ext = ".dmg";
+ filterDescription = "filter.dmg";
+ break;
+ case PROJECTOR_LINUX:
+ // linux projector is compressed with tar.gz
+ // todo: decompress
+ ext = "";
+ filterDescription = "filter.linuxExe";
+ break;
+ }
+
+ String fext = ext;
+ String ffilterDescription = filterDescription;
+ FileFilter exeFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(fext)) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate(ffilterDescription);
+ }
+ };
+ fc.setFileFilter(exeFilter);
+ } else if (swf.gfx) {
+ fc.addChoosableFileFilter(swfFilter);
+ fc.setFileFilter(gfxFilter);
+ } else {
+ fc.setFileFilter(swfFilter);
+ fc.addChoosableFileFilter(gfxFilter);
+ }
+ final String extension = ext;
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ if (fc.showSaveDialog(f) == JFileChooser.APPROVE_OPTION) {
+ File file = Helper.fixDialogFile(fc.getSelectedFile());
+ FileFilter selFilter = fc.getFileFilter();
+ try {
+ String fileName = file.getAbsolutePath();
+ if (selFilter == swfFilter) {
+ if (!fileName.toLowerCase().endsWith(extension)) {
+ fileName += extension;
+ }
+ swf.gfx = false;
+ }
+ if (selFilter == gfxFilter) {
+ if (!fileName.toLowerCase().endsWith(".gfx")) {
+ fileName += ".gfx";
+ }
+ swf.gfx = true;
+ }
+ Main.saveFile(swf, fileName, mode, exeExportMode);
+ Configuration.lastSaveDir.set(file.getParentFile().getAbsolutePath());
+ return true;
+ } catch (IOException ex) {
+ View.showMessageDialog(null, AppStrings.translate("error.file.write"));
+ }
+ }
+ return false;
+ }
+
+ public static boolean openFileDialog() {
+ JFileChooser fc = new JFileChooser();
+ if (Configuration.openMultipleFiles.get()) {
+ fc.setMultiSelectionEnabled(true);
+ }
+ fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
+ FileFilter allSupportedFilter = new FileFilter() {
+ private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip"};
+
+ @Override
+ public boolean accept(File f) {
+ String name = f.getName().toLowerCase();
+ for (String ext : supportedExtensions) {
+ if (name.endsWith(ext)) {
+ return true;
+ }
+ }
+ return f.isDirectory();
+ }
+
+ @Override
+ public String getDescription() {
+ String exts = Helper.joinStrings(supportedExtensions, "*%s", "; ");
+ return AppStrings.translate("filter.supported") + " (" + exts + ")";
+ }
+ };
+ fc.setFileFilter(allSupportedFilter);
+ FileFilter swfFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swf")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swf");
+ }
+ };
+ fc.addChoosableFileFilter(swfFilter);
+
+ FileFilter swcFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".swc")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.swc");
+ }
+ };
+ fc.addChoosableFileFilter(swcFilter);
+
+ FileFilter gfxFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".gfx")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.gfx");
+ }
+ };
+ fc.addChoosableFileFilter(gfxFilter);
+
+ FileFilter zipFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return (f.getName().toLowerCase().endsWith(".zip")) || (f.isDirectory());
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.zip");
+ }
+ };
+ fc.addChoosableFileFilter(zipFilter);
+
+ FileFilter binaryFilter = new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ return true;
+ }
+
+ @Override
+ public String getDescription() {
+ return AppStrings.translate("filter.binary");
+ }
+ };
+ fc.addChoosableFileFilter(binaryFilter);
+
+ fc.setAcceptAllFileFilterUsed(false);
+ JFrame f = new JFrame();
+ View.setWindowIcon(f);
+ int returnVal = fc.showOpenDialog(f);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath());
+ File[] selFiles = fc.getSelectedFiles();
+ for (File file : selFiles) {
+ File selfile = Helper.fixDialogFile(file);
+ Main.openFile(selfile.getAbsolutePath(), null);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void displayErrorFrame() {
+ ErrorLogFrame.getInstance().setVisible(true);
+ }
+
+ private static String md5(byte data[]) {
+ try {
+ java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
+ byte[] array = md.digest(data);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < array.length; ++i) {
+ sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
+ }
+ return sb.toString();
+ } catch (java.security.NoSuchAlgorithmException e) {
+ }
+ return null;
+ }
+
+ private static void initGui() {
+ if (GraphicsEnvironment.isHeadless()) {
+ System.err.println("Error: Your system does not support Graphic User Interface");
+ exit();
+ }
+
+ System.setProperty("sun.java2d.d3d", "false");
+ System.setProperty("sun.java2d.noddraw", "true");
+
+ if (Configuration.hwAcceleratedGraphics.get()) {
+ System.setProperty("sun.java2d.opengl", Configuration._debugMode.get() ? "True" : "true");
+ } else {
+ System.setProperty("sun.java2d.opengl", "false");
+ }
+
+ initUiLang();
+
+ if (Configuration.useRibbonInterface.get()) {
+ View.setLookAndFeel();
+ } else {
+ try {
+ UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null);
+ UIManager.put("Tree.expandedIcon", null);
+ UIManager.put("Tree.collapsedIcon", null);
+ UIManager.put("ColorChooserUI", null);
+ UIManager.put("ColorChooser.swatchesRecentSwatchSize", null);
+ UIManager.put("ColorChooser.swatchesSwatchSize", null);
+ UIManager.put("RibbonApplicationMenuPopupPanelUI", null);
+ UIManager.put("RibbonApplicationMenuButtonUI", null);
+ UIManager.put("ProgressBarUI", null);
+ UIManager.put("TextField.background", null);
+ UIManager.put("FormattedTextField.background", null);
+ UIManager.put("CommandButtonUI", null);
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+ }
+
+ View.execInEventDispatch(() -> {
+ ErrorLogFrame.createNewInstance();
+
+ autoCheckForUpdates();
+ offerAssociation();
+ loadingDialog = new LoadingDialog();
+
+ DebuggerTools.initDebugger().addMessageListener(new DebugListener() {
+ @Override
+ public void onMessage(String clientId, String msg) {
+ }
+
+ @Override
+ public void onLoaderURL(String clientId, String url) {
+ }
+
+ @Override
+ public void onLoaderBytes(String clientId, byte[] data) {
+ String hash = md5(data);
+ for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
+ for (int s = 0; s < sl.size(); s++) {
+ String t = sl.get(s).getFileTitle();
+ if (t == null) {
+ t = "";
+ }
+ if (t.endsWith(":" + hash)) { //this one is already opened
+ return;
+ }
+ }
+ }
+ SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
+
+ String title = swf == null ? "?" : swf.getFileTitle();
+ title = title + ":" + hash;
+ String tfile;
+ try {
+ tfile = tempFile(title);
+ Helper.writeFile(tfile, data);
+ openFile(new SWFSourceInfo(null, tfile, title));
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "Cannot create tempfile");
+ }
+ }
+
+ @Override
+ public void onFinish(String clientId) {
+ }
+ });
+
+ try {
+ flashDebugger = new Debugger();
+ debugHandler = new DebuggerHandler();
+ debugHandler.addBreakListener(new DebuggerHandler.BreakListener() {
+ @Override
+ public void doContinue() {
+ mainFrame.getPanel().clearDebuggerColors();
+ }
+
+ @Override
+ public void breakAt(String scriptName, int line, final int classIndex, final int traitIndex, final int methodIndex) {
+ View.execInEventDispatch(new Runnable() {
+ @Override
+ public void run() {
+ mainFrame.getPanel().gotoScriptLine(getMainFrame().getPanel().getCurrentSwf(), scriptName, line, classIndex, traitIndex, methodIndex);
+ }
+ });
+ }
+ });
+ debugHandler.addConnectionListener(new DebuggerHandler.ConnectionListener() {
+ @Override
+ public void connected() {
+ Main.mainFrame.getMenu().updateComponents();
+ }
+
+ @Override
+ public void disconnected() {
+ if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
+ Main.mainFrame.getPanel().refreshBreakPoints();
+ }
+ }
+ });
+ flashDebugger.addConnectionListener(debugHandler);
+ } catch (IOException ex) {
+ logger.log(Level.SEVERE, "eeex", ex);
+ }
+ });
+ }
+
+ public static void startDebugger() {
+ flashDebugger.startDebugger();
+ }
+
+ public static void stopDebugger() {
+ flashDebugger.stopDebugger();
+ }
+
+ public static void showModeFrame() {
+ ensureMainFrame();
+ mainFrame.setVisible(true);
+ }
+
+ private static void offerAssociation() {
+ boolean offered = Configuration.offeredAssociation.get();
+ if (!offered) {
+ if (Platform.isWindows()) {
+ if ((!ContextMenuTools.isAddedToContextMenu()) && View.showConfirmDialog(null, "Do you want to add FFDec to context menu of SWF files?\n(Can be changed later from main menu)", "Context menu", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
+ ContextMenuTools.addToContextMenu(true, false);
+ }
+ }
+
+ Configuration.offeredAssociation.set(true);
+ }
+ }
+
+ public static void initUiLang() {
+ if (GraphicsEnvironment.isHeadless()) { //No GUI in OS
+ return;
+ }
+ try {
+ Class> cl = Class.forName("org.pushingpixels.substance.api.SubstanceLookAndFeel");
+ Field field = cl.getDeclaredField("LABEL_BUNDLE");
+ field.setAccessible(true);
+ field.set(null, null);
+ } catch (Throwable ex) {
+ logger.log(Level.SEVERE, null, ex);
+ }
+
+ UIManager.put("OptionPane.okButtonText", AppStrings.translate("button.ok"));
+ UIManager.put("OptionPane.yesButtonText", AppStrings.translate("button.yes"));
+ UIManager.put("OptionPane.noButtonText", AppStrings.translate("button.no"));
+ UIManager.put("OptionPane.cancelButtonText", AppStrings.translate("button.cancel"));
+ UIManager.put("OptionPane.messageDialogTitle", AppStrings.translate("dialog.message.title"));
+ UIManager.put("OptionPane.titleText", AppStrings.translate("dialog.select.title"));
+
+ UIManager.put("FileChooser.acceptAllFileFilterText", AppStrings.translate("FileChooser.acceptAllFileFilterText"));
+ UIManager.put("FileChooser.lookInLabelText", AppStrings.translate("FileChooser.lookInLabelText"));
+ UIManager.put("FileChooser.cancelButtonText", AppStrings.translate("button.cancel"));
+ UIManager.put("FileChooser.cancelButtonToolTipText", AppStrings.translate("button.cancel"));
+ UIManager.put("FileChooser.openButtonText", AppStrings.translate("FileChooser.openButtonText"));
+ UIManager.put("FileChooser.openButtonToolTipText", AppStrings.translate("FileChooser.openButtonToolTipText"));
+ UIManager.put("FileChooser.filesOfTypeLabelText", AppStrings.translate("FileChooser.filesOfTypeLabelText"));
+ UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
+ UIManager.put("FileChooser.listViewButtonToolTipText", AppStrings.translate("FileChooser.listViewButtonToolTipText"));
+ UIManager.put("FileChooser.listViewButtonAccessibleName", AppStrings.translate("FileChooser.listViewButtonAccessibleName"));
+ UIManager.put("FileChooser.detailsViewButtonToolTipText", AppStrings.translate("FileChooser.detailsViewButtonToolTipText"));
+ UIManager.put("FileChooser.detailsViewButtonAccessibleName", AppStrings.translate("FileChooser.detailsViewButtonAccessibleName"));
+ UIManager.put("FileChooser.upFolderToolTipText", AppStrings.translate("FileChooser.upFolderToolTipText"));
+ UIManager.put("FileChooser.upFolderAccessibleName", AppStrings.translate("FileChooser.upFolderAccessibleName"));
+ UIManager.put("FileChooser.homeFolderToolTipText", AppStrings.translate("FileChooser.homeFolderToolTipText"));
+ UIManager.put("FileChooser.homeFolderAccessibleName", AppStrings.translate("FileChooser.homeFolderAccessibleName"));
+ UIManager.put("FileChooser.fileNameHeaderText", AppStrings.translate("FileChooser.fileNameHeaderText"));
+ UIManager.put("FileChooser.fileSizeHeaderText", AppStrings.translate("FileChooser.fileSizeHeaderText"));
+ UIManager.put("FileChooser.fileTypeHeaderText", AppStrings.translate("FileChooser.fileTypeHeaderText"));
+ UIManager.put("FileChooser.fileDateHeaderText", AppStrings.translate("FileChooser.fileDateHeaderText"));
+ UIManager.put("FileChooser.fileAttrHeaderText", AppStrings.translate("FileChooser.fileAttrHeaderText"));
+ UIManager.put("FileChooser.openDialogTitleText", AppStrings.translate("FileChooser.openDialogTitleText"));
+ UIManager.put("FileChooser.directoryDescriptionText", AppStrings.translate("FileChooser.directoryDescriptionText"));
+ UIManager.put("FileChooser.directoryOpenButtonText", AppStrings.translate("FileChooser.directoryOpenButtonText"));
+ UIManager.put("FileChooser.directoryOpenButtonToolTipText", AppStrings.translate("FileChooser.directoryOpenButtonToolTipText"));
+ UIManager.put("FileChooser.fileDescriptionText", AppStrings.translate("FileChooser.fileDescriptionText"));
+ UIManager.put("FileChooser.fileNameLabelText", AppStrings.translate("FileChooser.fileNameLabelText"));
+ UIManager.put("FileChooser.helpButtonText", AppStrings.translate("FileChooser.helpButtonText"));
+ UIManager.put("FileChooser.helpButtonToolTipText", AppStrings.translate("FileChooser.helpButtonToolTipText"));
+ UIManager.put("FileChooser.newFolderAccessibleName", AppStrings.translate("FileChooser.newFolderAccessibleName"));
+ UIManager.put("FileChooser.newFolderErrorText", AppStrings.translate("FileChooser.newFolderErrorText"));
+ UIManager.put("FileChooser.newFolderToolTipText", AppStrings.translate("FileChooser.newFolderToolTipText"));
+ UIManager.put("FileChooser.other.newFolder", AppStrings.translate("FileChooser.other.newFolder"));
+ UIManager.put("FileChooser.other.newFolder.subsequent", AppStrings.translate("FileChooser.other.newFolder.subsequent"));
+ UIManager.put("FileChooser.win32.newFolder", AppStrings.translate("FileChooser.win32.newFolder"));
+ UIManager.put("FileChooser.win32.newFolder.subsequent", AppStrings.translate("FileChooser.win32.newFolder.subsequent"));
+ UIManager.put("FileChooser.saveButtonText", AppStrings.translate("FileChooser.saveButtonText"));
+ UIManager.put("FileChooser.saveButtonToolTipText", AppStrings.translate("FileChooser.saveButtonToolTipText"));
+ UIManager.put("FileChooser.saveDialogTitleText", AppStrings.translate("FileChooser.saveDialogTitleText"));
+ UIManager.put("FileChooser.saveInLabelText", AppStrings.translate("FileChooser.saveInLabelText"));
+ UIManager.put("FileChooser.updateButtonText", AppStrings.translate("FileChooser.updateButtonText"));
+ UIManager.put("FileChooser.updateButtonToolTipText", AppStrings.translate("FileChooser.updateButtonToolTipText"));
+
+ UIManager.put("FileChooser.detailsViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.detailsViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.detailsViewButtonToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.fileAttrHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileAttrHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileDateHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileDateHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileNameHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileNameHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.fileNameLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.fileSizeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileSizeHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.fileTypeHeader.textAndMnemonic", AppStrings.translate("FileChooser.fileTypeHeader.textAndMnemonic"));
+ UIManager.put("FileChooser.filesOfTypeLabel.textAndMnemonic", AppStrings.translate("FileChooser.filesOfTypeLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.folderNameLabel.textAndMnemonic", AppStrings.translate("FileChooser.folderNameLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.homeFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.homeFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.listViewActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.listViewActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.listViewButtonToolTip.textAndMnemonic", AppStrings.translate("FileChooser.listViewButtonToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.lookInLabel.textAndMnemonic", AppStrings.translate("FileChooser.lookInLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.newFolderActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.newFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.refreshActionLabel.textAndMnemonic", AppStrings.translate("FileChooser.refreshActionLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.saveInLabel.textAndMnemonic", AppStrings.translate("FileChooser.saveInLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.upFolderToolTip.textAndMnemonic", AppStrings.translate("FileChooser.upFolderToolTip.textAndMnemonic"));
+ UIManager.put("FileChooser.viewMenuButtonAccessibleName", AppStrings.translate("FileChooser.viewMenuButtonAccessibleName"));
+ UIManager.put("FileChooser.viewMenuButtonToolTipText", AppStrings.translate("FileChooser.viewMenuButtonToolTipText"));
+ UIManager.put("FileChooser.viewMenuLabel.textAndMnemonic", AppStrings.translate("FileChooser.viewMenuLabel.textAndMnemonic"));
+ UIManager.put("FileChooser.newFolderActionLabelText", AppStrings.translate("FileChooser.newFolderActionLabelText"));
+ UIManager.put("FileChooser.listViewActionLabelText", AppStrings.translate("FileChooser.listViewActionLabelText"));
+ UIManager.put("FileChooser.detailsViewActionLabelText", AppStrings.translate("FileChooser.detailsViewActionLabelText"));
+ UIManager.put("FileChooser.refreshActionLabelText", AppStrings.translate("FileChooser.refreshActionLabelText"));
+ UIManager.put("FileChooser.sortMenuLabelText", AppStrings.translate("FileChooser.sortMenuLabelText"));
+ UIManager.put("FileChooser.viewMenuLabelText", AppStrings.translate("FileChooser.viewMenuLabelText"));
+ UIManager.put("FileChooser.fileSizeKiloBytes", AppStrings.translate("FileChooser.fileSizeKiloBytes"));
+ UIManager.put("FileChooser.fileSizeMegaBytes", AppStrings.translate("FileChooser.fileSizeMegaBytes"));
+ UIManager.put("FileChooser.fileSizeGigaBytes", AppStrings.translate("FileChooser.fileSizeGigaBytes"));
+ UIManager.put("FileChooser.folderNameLabelText", AppStrings.translate("FileChooser.folderNameLabelText"));
+
+ UIManager.put("ColorChooser.okText", AppStrings.translate("ColorChooser.okText"));
+ UIManager.put("ColorChooser.cancelText", AppStrings.translate("ColorChooser.cancelText"));
+ UIManager.put("ColorChooser.resetText", AppStrings.translate("ColorChooser.resetText"));
+ UIManager.put("ColorChooser.previewText", AppStrings.translate("ColorChooser.previewText"));
+ UIManager.put("ColorChooser.swatchesNameText", AppStrings.translate("ColorChooser.swatchesNameText"));
+ UIManager.put("ColorChooser.swatchesRecentText", AppStrings.translate("ColorChooser.swatchesRecentText"));
+ UIManager.put("ColorChooser.sampleText", AppStrings.translate("ColorChooser.sampleText"));
+
+ }
+
+ public static void initLang() {
+ if (!Configuration.locale.hasValue()) {
+ if (Platform.isWindows()) {
+ //Load from Installer
+ String uninstKey = "{E618D276-6596-41F4-8A98-447D442A77DB}_is1";
+ uninstKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + uninstKey;
+ try {
+ if (Advapi32Util.registryKeyExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey)) {
+ if (Advapi32Util.registryValueExists(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language")) {
+ String installedLoc = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, uninstKey, "NSIS: Language");
+ int lcid = Integer.parseInt(installedLoc);
+ char[] buf = new char[9];
+ int cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO639LANGNAME, buf, 9);
+ String langCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ cnt = Kernel32.INSTANCE.GetLocaleInfo(lcid, Kernel32.LOCALE_SISO3166CTRYNAME, buf, 9);
+ String countryCode = new String(buf, 0, cnt).trim().toLowerCase();
+
+ List langs = Arrays.asList(SelectLanguageDialog.getAvailableLanguages());
+ for (int i = 0; i < langs.size(); i++) {
+ langs.set(i, langs.get(i).toLowerCase());
+ }
+
+ String selectedLang = null;
+
+ if (langs.contains(langCode + "-" + countryCode)) {
+ selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode + "-" + countryCode)];
+ } else if (langs.contains(langCode)) {
+ selectedLang = SelectLanguageDialog.getAvailableLanguages()[langs.indexOf(langCode)];
+ }
+ if (selectedLang != null) {
+ Configuration.locale.set(selectedLang);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get()));
+ AppStrings.updateLanguage();
+
+ Helper.decompilationErrorAdd = AppStrings.translate(Configuration.autoDeobfuscate.get() ? "deobfuscation.comment.failed" : "deobfuscation.comment.tryenable");
+ }
+
+ /**
+ * Clear old FFDec/JavactiveX temp files
+ */
+ private static void clearTemp() {
+ String tempDirPath = System.getProperty("java.io.tmpdir");
+ if (tempDirPath == null) {
+ return;
+ }
+ File tempDir = new File(tempDirPath);
+ if (!tempDir.exists()) {
+ return;
+ }
+ File[] delFiles = tempDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.matches("ffdec_cache.*\\.tmp") || name.matches("javactivex_.*\\.exe") || name.matches("temp[0-9]+\\.swf") || name.matches("ffdec_view_.*\\.swf");
+ }
+ });
+
+ if (delFiles != null) {
+ for (File f : delFiles) {
+ try {
+ f.delete();
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * @param args the command line arguments
+ * @throws IOException On error
+ */
+ public static void main(String[] args) throws IOException {
+ setSessionLoaded(false);
+ clearTemp();
+
+ try {
+ SWFDecompilerPlugin.loadPlugins();
+ } catch (Throwable ex) {
+ logger.log(Level.SEVERE, "Failed to load plugins", ex);
+ }
+
+ AppStrings.setResourceClass(MainFrame.class);
+ initLogging(Configuration._debugMode.get());
+
+ initLang();
+
+ if (Configuration.cacheOnDisk.get()) {
+ Cache.setStorageType(Cache.STORAGE_FILES);
+ } else {
+ Cache.setStorageType(Cache.STORAGE_MEMORY);
+ }
+
+ if (args.length == 0) {
+ initGui();
+ View.execInEventDispatch(() -> {
+ if (Configuration.allowOnlyOneInstance.get() && FirstInstance.focus()) { //Try to focus first instance
+ Main.exit();
+ } else {
+ showModeFrame();
+ reloadLastSession();
+ }
+ });
+ } else {
+ setSessionLoaded(true);
+ String[] filesToOpen = CommandLineArgumentParser.parseArguments(args);
+ if (filesToOpen != null && filesToOpen.length > 0) {
+ View.execInEventDispatch(() -> {
+ initGui();
+ shouldCloseWhenClosingLoadingDialog = true;
+ if (Configuration.allowOnlyOneInstance.get() && FirstInstance.openFiles(Arrays.asList(filesToOpen))) { //Try to open in first instance
+ Main.exit();
+ } else {
+ for (String fileToOpen : filesToOpen) {
+ openFile(fileToOpen, null);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private static void reloadLastSession() {
+ boolean openingFiles = false;
+ if (Configuration.saveSessionOnExit.get()) {
+ String lastSession = Configuration.lastSessionFiles.get();
+ if (lastSession != null && lastSession.length() > 0) {
+ String[] filesToOpen = lastSession.split(File.pathSeparator, -1);
+ List exfiles = new ArrayList<>();
+ List extitles = new ArrayList<>();
+ String lastSessionTitles = Configuration.lastSessionFileTitles.get();
+ String[] fileTitles = new String[0];
+ if (lastSessionTitles != null && !lastSessionTitles.isEmpty()) {
+ fileTitles = lastSessionTitles.split(File.pathSeparator, -1);
+ }
+ for (int i = 0; i < filesToOpen.length; i++) {
+ if (new File(filesToOpen[i]).exists()) {
+ exfiles.add(filesToOpen[i]);
+ if (fileTitles.length > i) {
+ extitles.add(fileTitles[i]);
+ } else {
+ extitles.add(null);
+ }
+ }
+ }
+ SWFSourceInfo[] sourceInfos = new SWFSourceInfo[exfiles.size()];
+ for (int i = 0; i < exfiles.size(); i++) {
+ String extitle = extitles.get(i);
+ sourceInfos[i] = new SWFSourceInfo(null, exfiles.get(i), extitle == null || extitle.isEmpty() ? null : extitle);
+ }
+ if (sourceInfos.length > 0) {
+ openingFiles = true;
+ openFile(sourceInfos, () -> {
+ mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get());
+ setSessionLoaded(true);
+ });
+ }
+ }
+ }
+
+ if (!openingFiles) {
+ setSessionLoaded(true);
+ }
+ }
+
+ public static String tempFile(String url) throws IOException {
+ File f = new File(Configuration.getFFDecHome() + "saved" + File.separator);
+ Path.createDirectorySafe(f);
+ return Configuration.getFFDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
+ }
+
+ public static void removeTrayIcon() {
+ if (SystemTray.isSupported()) {
+ SystemTray tray = SystemTray.getSystemTray();
+ if (trayIcon != null) {
+ tray.remove(trayIcon);
+ trayIcon = null;
+ }
+ }
+ }
+
+ public static void switchProxy() {
+ proxyFrame.switchState();
+ if (stopMenuItem != null) {
+ if (proxyFrame.isRunning()) {
+ stopMenuItem.setLabel(AppStrings.translate("proxy.stop"));
+ } else {
+ stopMenuItem.setLabel(AppStrings.translate("proxy.start"));
+ }
+ }
+ }
+
+ public static void addTrayIcon() {
+ if (trayIcon != null) {
+ return;
+ }
+ if (SystemTray.isSupported()) {
+ SystemTray tray = SystemTray.getSystemTray();
+ trayIcon = new TrayIcon(View.loadImage("proxy16"), ApplicationInfo.VENDOR + " " + ApplicationInfo.SHORT_APPLICATION_NAME + " " + AppStrings.translate("proxy"));
+ trayIcon.setImageAutoSize(true);
+ PopupMenu trayPopup = new PopupMenu();
+
+ ActionListener trayListener = new ActionListener() {
+ /**
+ * Invoked when an action occurs.
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("EXIT")) {
+ Main.exit();
+ }
+ if (e.getActionCommand().equals("SHOW")) {
+ Main.showProxy();
+ }
+ if (e.getActionCommand().equals("SWITCH")) {
+ Main.switchProxy();
+ }
+ }
+ };
+
+ MenuItem showMenuItem = new MenuItem(AppStrings.translate("proxy.show"));
+ showMenuItem.setActionCommand("SHOW");
+ showMenuItem.addActionListener(trayListener);
+ trayPopup.add(showMenuItem);
+ stopMenuItem = new MenuItem(AppStrings.translate("proxy.start"));
+ stopMenuItem.setActionCommand("SWITCH");
+ stopMenuItem.addActionListener(trayListener);
+ trayPopup.add(stopMenuItem);
+ trayPopup.addSeparator();
+ MenuItem exitMenuItem = new MenuItem(AppStrings.translate("exit"));
+ exitMenuItem.setActionCommand("EXIT");
+ exitMenuItem.addActionListener(trayListener);
+ trayPopup.add(exitMenuItem);
+
+ trayIcon.setPopupMenu(trayPopup);
+ trayIcon.addMouseListener(new MouseAdapter() {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getButton() == MouseEvent.BUTTON1) {
+ Main.showProxy();
+ }
+ }
+ });
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException ex) {
+ }
+ }
+ }
+
+ public static void exit() {
+ Configuration.saveConfig();
+ if (mainFrame != null && mainFrame.getPanel() != null) {
+ mainFrame.getPanel().unloadFlashPlayer();
+ mainFrame.dispose();
+ }
+ if (fileTxt != null) {
+ try {
+ fileTxt.flush();
+ fileTxt.close();
+ } catch (Exception ex) {
+ //ignore
+ }
+ }
+ System.exit(0);
+ }
+
+ public static void about() {
+ (new AboutDialog()).setVisible(true);
+ }
+
+ public static void advancedSettings() {
+ advancedSettings(null);
+ }
+
+ public static void advancedSettings(String category) {
+ (new AdvancedSettingsDialog(category)).setVisible(true);
+ }
+
+ public static void autoCheckForUpdates() {
+ if (Configuration.checkForUpdatesAuto.get()) {
+ Calendar lastUpdatesCheckDate = Configuration.lastUpdatesCheckDate.get();
+ if ((lastUpdatesCheckDate == null) || (lastUpdatesCheckDate.getTime().getTime() < Calendar.getInstance().getTime().getTime() - Configuration.checkForUpdatesDelay.get())) {
+ new SwingWorker() {
+ @Override
+ protected Object doInBackground() throws Exception {
+ checkForUpdates();
+ return null;
+ }
+ }.execute();
+ }
+ }
+ }
+
+ public static boolean checkForUpdates() {
+ String currentVersion = ApplicationInfo.version;
+ if (currentVersion.equals("unknown")) {
+ // sometimes during development the version information is not available
+ return false;
+ }
+
+ List accepted = new ArrayList<>();
+ if (Configuration.checkForUpdatesStable.get()) {
+ accepted.add("stable");
+ }
+ if (Configuration.checkForUpdatesNightly.get()) {
+ accepted.add("nightly");
+ }
+
+ if (accepted.isEmpty()) {
+ return false;
+ }
+
+ String acceptVersions = String.join(",", accepted);
+ try {
+ String proxyAddress = Configuration.updateProxyAddress.get();
+ URL url = new URL(ApplicationInfo.updateCheckUrl);
+
+ URLConnection uc;
+ if (proxyAddress != null && !proxyAddress.isEmpty()) {
+ int port = 8080;
+ if (proxyAddress.contains(":")) {
+ String[] parts = proxyAddress.split(":");
+ port = Integer.parseInt(parts[1]);
+ proxyAddress = parts[0];
+ }
+
+ uc = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, port)));
+ } else {
+ uc = url.openConnection();
+ }
+ uc.setRequestProperty("X-Accept-Versions", acceptVersions);
+ uc.setRequestProperty("X-Update-Major", "" + UPDATE_SYSTEM_MAJOR);
+ uc.setRequestProperty("X-Update-Minor", "" + UPDATE_SYSTEM_MINOR);
+ uc.setRequestProperty("User-Agent", ApplicationInfo.shortApplicationVerName);
+ String currentLoc = Configuration.locale.get("en");
+ uc.setRequestProperty("Accept-Language", currentLoc + ("en".equals(currentLoc) ? "" : ", en;q=0.8"));
+
+ uc.connect();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
+ String s;
+ final java.util.List versions = new ArrayList<>();
+ String header = "";
+ Pattern headerPat = Pattern.compile("\\[([a-zA-Z0-9]+)\\]");
+ int updateMajor;
+ int updateMinor;
+ Version ver = null;
+ while ((s = br.readLine()) != null) {
+
+ Matcher m = headerPat.matcher(s);
+ if (m.matches()) {
+ header = m.group(1);
+ if (header.equals("version")) {
+ ver = new Version();
+ versions.add(ver);
+ }
+ if (header.equals("noversion")) {
+ break;
+ }
+ } else if (s.contains("=")) {
+ String key = s.substring(0, s.indexOf('='));
+ String val = s.substring(s.indexOf('=') + 1);
+ if ("updateSystem".equals(header)) {
+ if (key.equals("majorVersion")) {
+ updateMajor = Integer.parseInt(val);
+ if (updateMajor > UPDATE_SYSTEM_MAJOR) {
+ break;
+ }
+ }
+ if (key.equals("minorVersion")) {
+ updateMinor = Integer.parseInt(val);
+ }
+ }
+ if ("version".equals(header) && (ver != null)) {
+ if (key.equals("versionId")) {
+ ver.versionId = Integer.parseInt(val);
+ }
+ if (key.equals("versionName")) {
+ ver.versionName = val;
+ }
+ if (key.equals("nightly")) {
+ ver.nightly = val.equals("true");
+ }
+ if (key.equals("revision")) {
+ ver.revision = val;
+ }
+ if (key.equals("build")) {
+ ver.build = Integer.parseInt(val);
+ }
+ if (key.equals("major")) {
+ ver.major = Integer.parseInt(val);
+ }
+ if (key.equals("minor")) {
+ ver.minor = Integer.parseInt(val);
+ }
+ if (key.equals("release")) {
+ ver.release = Integer.parseInt(val);
+ }
+ if (key.equals("longVersionName")) {
+ ver.longVersionName = val;
+ }
+ if (key.equals("releaseDate")) {
+ ver.releaseDate = val;
+ }
+ if (key.equals("appName")) {
+ ver.appName = val;
+ }
+ if (key.equals("appFullName")) {
+ ver.appFullName = val;
+ }
+ if (key.equals("updateLink")) {
+ ver.updateLink = val;
+ }
+ if (key.equals("change[]")) {
+ String changeType = val.substring(0, val.indexOf('|'));
+ String change = val.substring(val.indexOf('|') + 1);
+ if (!ver.changes.containsKey(changeType)) {
+ ver.changes.put(changeType, new ArrayList<>());
+ }
+ List chlist = ver.changes.get(changeType);
+ chlist.add(change);
+ }
+ }
+ }
+ }
+
+ if (!versions.isEmpty()) {
+ View.execInEventDispatch(() -> {
+ NewVersionDialog newVersionDialog = new NewVersionDialog(versions);
+ newVersionDialog.setVisible(true);
+ Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
+ });
+
+ return true;
+ }
+ } catch (IOException | NumberFormatException ex) {
+ return false;
+ }
+ Configuration.lastUpdatesCheckDate.set(Calendar.getInstance());
+ return false;
+ }
+
+ private static FileHandler fileTxt;
+
+ public static void clearLogFile() {
+ Logger logger = Logger.getLogger("");
+
+ FileHandler oldFileTxt = fileTxt;
+ fileTxt = null;
+ if (oldFileTxt != null) {
+ logger.removeHandler(fileTxt);
+ oldFileTxt.flush();
+ oldFileTxt.close();
+ }
+
+ String fileName = null;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
+
+ try {
+ fileName = Configuration.getFFDecHome() + "logs" + File.separator;
+ if (Configuration.useDetailedLogging.get()) {
+ fileName += "log-" + sdf.format(new Date()) + ".txt";
+ } else {
+ fileName += "log.txt";
+ }
+ File f = new File(fileName).getParentFile();
+ if (!f.exists()) {
+ f.mkdir();
+ }
+ fileTxt = new FileHandler(fileName);
+ } catch (IOException | SecurityException ex) {
+ //cannot get lock error
+ if (ex.getMessage().contains("lock for")) {
+ //remove all old log files and their .lck
+ for (int i = 0; i <= 100; i++) {
+ File flog = new File(fileName + (i == 0 ? "" : "." + i));
+ File flog_lock = new File(fileName + (i == 0 ? "" : "." + i) + ".lck");
+ flog.delete();
+ flog_lock.delete();
+ }
+ try {
+ fileTxt = new FileHandler(fileName);
+ } catch (IOException | SecurityException ex1) {
+ logger.log(Level.SEVERE, "Cannot initialize logging", ex);
+ }
+ } else {
+ logger.log(Level.SEVERE, "Cannot initialize logging", ex);
+ }
+ }
+
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ logger.log(Level.SEVERE, "Uncaught exception in thread: " + t.getName(), e);
+ if (e instanceof OutOfMemoryError || !Helper.is64BitJre() && Helper.is64BitOs()) {
+ View.showMessageDialog(null, AppStrings.translate("message.warning.outOfMemory32BitJre"), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ });
+
+ Formatter formatterTxt = new LogFormatter();
+ if (fileTxt != null) {
+ fileTxt.setFormatter(formatterTxt);
+ logger.addHandler(fileTxt);
+ }
+
+ if (!GraphicsEnvironment.isHeadless() && ErrorLogFrame.hasInstance()) {
+ ErrorLogFrame.getInstance().clearErrorState();
+ }
+
+ sdf = new SimpleDateFormat("yyyy-MM-dd");
+ logger.log(Level.INFO, "Date: {0}", sdf.format(new Date()));
+ logger.log(Level.INFO, ApplicationInfo.applicationVerName);
+ logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
+ System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")});
+ logger.log(Level.INFO, "{0} {1} {2}", new Object[]{
+ System.getProperty("java.version"), System.getProperty("java.vendor"), System.getProperty("os.arch")});
+ }
+
+ public static void initLogging(boolean debug) {
+ try {
+ Logger logger = Logger.getLogger("");
+ logger.setLevel(Configuration.logLevel);
+
+ Handler[] handlers = logger.getHandlers();
+ for (int i = handlers.length - 1; i >= 0; i--) {
+ logger.removeHandler(handlers[i]);
+ }
+
+ ConsoleHandler conHan = new ConsoleHandler();
+ conHan.setLevel(debug ? Level.CONFIG : Level.WARNING);
+ SimpleFormatter formatterTxt = new SimpleFormatter();
+ conHan.setFormatter(formatterTxt);
+ logger.addHandler(conHan);
+ clearLogFile();
+
+ } catch (Exception ex) {
+ throw new RuntimeException("Problems with creating the log files");
+ }
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
index ce5577f9e..d954d3fb2 100644
--- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java
@@ -463,7 +463,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
tagTree = new TagTree(null, this);
tagTree.addTreeSelectionListener(this);
tagTree.setSelectionModel(new DefaultTreeSelectionModel() {
-
private boolean isModified() {
if (abcPanel != null && abcPanel.isEditing()) {
abcPanel.tryAutoSave();
@@ -2097,7 +2096,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
String selFile = Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath();
File textsFile = new File(Path.combine(selFile, TextExportSettings.EXPORT_FOLDER_NAME, TextExporter.TEXT_EXPORT_FILENAME_FORMATTED));
TextImporter textImporter = new TextImporter(getMissingCharacterHandler(), new TextImportErrorHandler() {
-
// "configuration items" for the current replace only
private final ConfigurationItem showAgainImportError = new ConfigurationItem<>("showAgainImportError", true, true);
@@ -2520,7 +2518,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private MissingCharacterHandler getMissingCharacterHandler() {
return new MissingCharacterHandler() {
-
// "configuration items" for the current replace only
private final ConfigurationItem showAgainIgnoreMissingCharacters = new ConfigurationItem<>("showAgainIgnoreMissingCharacters", true, true);
@@ -2637,6 +2634,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
boolean ok = false;
try {
ok = ds.setSound(new FileInputStream(selfile), soundFormat);
+ ds.getSwf().clearSoundCache();
} catch (IOException ex) {
//ignore
}
@@ -2832,7 +2830,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
FileFilter ff = new FileFilter() {
-
@Override
public boolean accept(File f) {
if (f.isDirectory()) {
@@ -3046,12 +3043,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
treePanelMode = TreePanelMode.TAG_TREE;
treePanel.addComponentListener(new ComponentAdapter() {
-
@Override
public void componentResized(ComponentEvent e) {
tagTree.scrollPathToVisible(tagTree.getSelectionPath());
}
-
});
reload(true);
@@ -3101,7 +3096,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
Main.loadingDialog.setVisible(true);
new CancellableWorker() {
-
@Override
protected Void doInBackground() throws Exception {
try {
@@ -3109,7 +3103,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
try {
InputStream is = new ByteArrayInputStream(binaryDataTag.binaryData.getRangeData());
SWF bswf = new SWF(is, null, "(SWF Data)", new ProgressListener() {
-
@Override
public void progress(int p) {
Main.loadingDialog.setPercent(p);
@@ -3281,7 +3274,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
if (!Main.isInited() || !Main.isWorking() || Main.isDebugging()) {
CancellableWorker worker = new CancellableWorker() {
-
@Override
protected Void doInBackground() throws Exception {
ABCPanel abcPanel = getABCPanel();
@@ -3487,7 +3479,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
public static Timelined makeTimelined(final Tag tag, final int fontFrameNum) {
return new Timelined() {
-
private Timeline tim;
@Override
diff --git a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
index 5afa7f416..7ff683d89 100644
--- a/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
+++ b/src/com/jpexs/decompiler/flash/gui/dumpview/DumpViewPanel.java
@@ -195,8 +195,10 @@ public class DumpViewPanel extends JPanel {
}
});
- add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
- add(searchPanel, BorderLayout.SOUTH);
+ JPanel hexPanel = new JPanel(new BorderLayout());
+ hexPanel.add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
+ hexPanel.add(searchPanel, BorderLayout.SOUTH);
+ add(hexPanel, BorderLayout.CENTER);
}
public void closeDumpViewSearch() {