mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-12 06:18:12 +00:00
Added: Open in the Flash Player context menu on graphic/sound tags and frames
This commit is contained in:
@@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Disable AS1/2/3 direct editation when editing P-code
|
||||
- AS3 - navigation to definition in other SWF file and also player/airglobal
|
||||
- [#2463] Export subsprites animation context menu on frames
|
||||
- Open in the Flash Player context menu on graphic/sound tags and frames
|
||||
|
||||
### Changed
|
||||
- AS1/2 - Single DoAction tag inside frame is now displayed directly as frame node
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
|
||||
import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineMorphShape2Tag;
|
||||
@@ -43,6 +44,7 @@ import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
@@ -58,6 +60,7 @@ import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont;
|
||||
import com.jpexs.decompiler.flash.timeline.DepthState;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.SoundStreamFrameRange;
|
||||
import com.jpexs.decompiler.flash.timeline.TagScript;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
|
||||
@@ -252,6 +255,10 @@ public class PreviewExporter {
|
||||
public SWFHeader exportSwf(OutputStream os, TreeItem treeItem, Color backgroundColor, int fontPageNum, boolean showControls) throws IOException, ActionParseException {
|
||||
SWF swf = (SWF) treeItem.getOpenable();
|
||||
|
||||
if (treeItem instanceof TagScript) {
|
||||
treeItem = ((TagScript) treeItem).getTag();
|
||||
}
|
||||
|
||||
int frameCount = 1;
|
||||
float frameRate = swf.frameRate;
|
||||
HashMap<Integer, VideoFrameTag> videoFrames = new HashMap<>();
|
||||
@@ -347,18 +354,21 @@ public class PreviewExporter {
|
||||
setBgColorTag.writeTag(sos2);
|
||||
}
|
||||
|
||||
Set<Integer> doneCharacters = new LinkedHashSet<>();
|
||||
if (treeItem instanceof Frame) {
|
||||
Frame fn = (Frame) treeItem;
|
||||
Timelined parent = fn.timeline.timelined;
|
||||
|
||||
Set<Integer> doneCharacters = new LinkedHashSet<>();
|
||||
for (Tag t : parent.getTags()) {
|
||||
if (t instanceof FileAttributesTag || t instanceof SetBackgroundColorTag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t instanceof DoActionTag || t instanceof DoInitActionTag) {
|
||||
// todo: Maybe DoABC tags should be removed, too
|
||||
if (t instanceof DoActionTag
|
||||
|| t instanceof DoInitActionTag
|
||||
|| t instanceof ABCContainerTag
|
||||
|| t instanceof SymbolClassTag
|
||||
|| t instanceof ExportAssetsTag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -366,8 +376,7 @@ public class PreviewExporter {
|
||||
t.getNeededCharactersDeep(needed);
|
||||
for (int n : needed) {
|
||||
if (!doneCharacters.contains(n)) {
|
||||
writeTag(swf.getCharacter(n), sos2);
|
||||
doneCharacters.add(n);
|
||||
writeTag(swf.getCharacter(n), sos2, doneCharacters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,8 +386,7 @@ public class PreviewExporter {
|
||||
if (t instanceof CharacterTag) {
|
||||
int characterId = ((CharacterTag) t).getCharacterId();
|
||||
if (characterId != -1) {
|
||||
doneCharacters.add(characterId);
|
||||
writeTag(t, sos2);
|
||||
writeTag(t, sos2, doneCharacters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,11 +435,11 @@ public class PreviewExporter {
|
||||
}
|
||||
}
|
||||
|
||||
writeTag(characterTag, sos2);
|
||||
writeTag(characterTag, sos2, doneCharacters);
|
||||
}
|
||||
}
|
||||
|
||||
writeTag((Tag) treeItem, sos2);
|
||||
writeTag((Tag) treeItem, sos2, doneCharacters);
|
||||
|
||||
MATRIX mat = new MATRIX();
|
||||
mat.hasRotate = false;
|
||||
@@ -569,25 +577,6 @@ public class PreviewExporter {
|
||||
DoActionTag doa;
|
||||
|
||||
doa = new DoActionTag(swf, null);
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\"\n"
|
||||
+ "Push \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\" 0.0 \"Sound\"\n"
|
||||
+ "NewObject\n"
|
||||
+ "SetMember\n"
|
||||
+ "Push \"my_define_sound\" 1 \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push \"attachSound\"\n"
|
||||
+ "CallMethod\n"
|
||||
+ "Pop\n"
|
||||
+ "Stop", swf.version, false, swf.getCharset());
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n"
|
||||
+ "StopSounds\n"
|
||||
@@ -614,59 +603,6 @@ public class PreviewExporter {
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, false,
|
||||
"ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"onSoundComplete\" \"start\" \"execParam\"\n"
|
||||
+ "StopSounds\n"
|
||||
+ "Push \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\" 0.0 \"Sound\"\n"
|
||||
+ "NewObject\n"
|
||||
+ "SetMember\n"
|
||||
+ "Push \"my_define_sound\" 1 \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push \"attachSound\"\n"
|
||||
+ "CallMethod\n"
|
||||
+ "Pop\n"
|
||||
+ "Push \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push \"onSoundComplete\"\n"
|
||||
+ "DefineFunction2 \"\" 0 2 false true true false true false true false false {\n"
|
||||
+ "Push 0.0 register1 \"my_sound\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push \"start\"\n"
|
||||
+ "CallMethod\n"
|
||||
+ "Pop\n"
|
||||
+ "}\n"
|
||||
+ "SetMember\n"
|
||||
+ "Push \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"execParam\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push 1 \"_root\"\n"
|
||||
+ "GetVariable\n"
|
||||
+ "Push \"my_sound\"\n"
|
||||
+ "GetMember\n"
|
||||
+ "Push \"start\"\n"
|
||||
+ "CallMethod\n"
|
||||
+ "Pop\n"
|
||||
+ "Stop", swf.version, false, swf.getCharset());
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
actions = ASMParser.parse(0, false,
|
||||
"StopSounds\n"
|
||||
+ "Stop", swf.version, false, swf.getCharset());
|
||||
doa.setActions(actions);
|
||||
doa.writeTag(sos2);
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
|
||||
new ShowFrameTag(swf).writeTag(sos2);
|
||||
} else if (treeItem instanceof DefineVideoStreamTag) {
|
||||
List<VideoFrameTag> frs = new ArrayList<>(videoFrames.values());
|
||||
Collections.sort(frs, new Comparator<VideoFrameTag>() {
|
||||
@@ -705,8 +641,10 @@ public class PreviewExporter {
|
||||
MATRIX m2 = new Matrix(m).preConcatenate(new Matrix(mat)).toMATRIX();
|
||||
pt.writeTagWithMatrix(sos2, m2);
|
||||
lastTag = t;
|
||||
} else if (t instanceof DoActionTag) {
|
||||
//ignore
|
||||
} else {
|
||||
t.writeTag(sos2);
|
||||
t.writeTagNoScripts(sos2);
|
||||
lastTag = t;
|
||||
}
|
||||
}
|
||||
@@ -746,16 +684,33 @@ public class PreviewExporter {
|
||||
return t;
|
||||
}
|
||||
|
||||
private static void writeTag(Tag t, SWFOutputStream sos) throws IOException {
|
||||
private static void writeTag(Tag t, SWFOutputStream sos, Set<Integer> doneCharacters) throws IOException {
|
||||
t = classicTag(t);
|
||||
|
||||
if (t instanceof CharacterIdTag) {
|
||||
int chId = ((CharacterIdTag) t).getCharacterId();
|
||||
if (doneCharacters.contains(chId)) {
|
||||
return;
|
||||
}
|
||||
doneCharacters.add(chId);
|
||||
}
|
||||
|
||||
t.writeTag(sos);
|
||||
if (t instanceof CharacterIdTag) {
|
||||
List<CharacterIdTag> chIdTags = t.getSwf().getCharacterIdTags(((CharacterIdTag) t).getCharacterId());
|
||||
if (chIdTags != null) {
|
||||
for (CharacterIdTag chIdTag : chIdTags) {
|
||||
if (!(chIdTag instanceof PlaceObjectTypeTag || chIdTag instanceof RemoveTag)) {
|
||||
((Tag) chIdTag).writeTag(sos);
|
||||
|
||||
Set<Integer> needed = new LinkedHashSet<>();
|
||||
((Tag) chIdTag).getNeededCharactersDeep(needed);
|
||||
for (int n : needed) {
|
||||
if (!doneCharacters.contains(n)) {
|
||||
writeTag(((Tag) chIdTag).getSwf().getCharacter(n), sos, doneCharacters);
|
||||
}
|
||||
}
|
||||
|
||||
((Tag) chIdTag).writeTagNoScripts(sos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,21 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
|
||||
sos.writeBUTTONCONDACTIONList(actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeUB(7, reserved);
|
||||
sos.writeUB(1, trackAsMenu ? 1 : 0);
|
||||
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
try (SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion(), getCharset())) {
|
||||
sos2.writeBUTTONRECORDList(characters, true);
|
||||
}
|
||||
byte[] brdata = baos2.toByteArray();
|
||||
sos.writeUI16(0);
|
||||
sos.write(brdata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
|
||||
@@ -118,6 +118,12 @@ public class DefineButtonTag extends ButtonTag implements ASMSourceContainer {
|
||||
sos.write(getActionBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUI16(buttonId);
|
||||
sos.writeBUTTONRECORDList(characters, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterId() {
|
||||
return buttonId;
|
||||
|
||||
@@ -259,6 +259,39 @@ public class PlaceObject2Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUB(1, 0); //no clip actions
|
||||
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagMove ? 1 : 0);
|
||||
sos.writeUI16(depth);
|
||||
if (placeFlagHasCharacter) {
|
||||
sos.writeUI16(characterId);
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
sos.writeMatrix(matrix);
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
sos.writeCXFORMWITHALPHA(colorTransform);
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
sos.writeUI16(ratio);
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
sos.writeString(name);
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
sos.writeUI16(clipDepth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getPlaceObjectNum() {
|
||||
return 2;
|
||||
|
||||
@@ -442,6 +442,68 @@ public class PlaceObject3Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUB(1, 0); //no clip actions
|
||||
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagMove ? 1 : 0);
|
||||
sos.writeUB(1, reserved ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
|
||||
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
|
||||
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
|
||||
sos.writeUI16(depth);
|
||||
|
||||
if (placeFlagHasClassName) {
|
||||
sos.writeString(className);
|
||||
}
|
||||
if (placeFlagHasCharacter) {
|
||||
sos.writeUI16(characterId);
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
sos.writeMatrix(matrix);
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
sos.writeCXFORMWITHALPHA(colorTransform);
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
sos.writeUI16(ratio);
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
sos.writeString(name);
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
sos.writeUI16(clipDepth);
|
||||
}
|
||||
if (placeFlagHasFilterList) {
|
||||
sos.writeFILTERLIST(surfaceFilterList);
|
||||
}
|
||||
if (placeFlagHasBlendMode) {
|
||||
sos.writeUI8(blendMode);
|
||||
}
|
||||
if (placeFlagHasCacheAsBitmap) {
|
||||
if (!bitmapCacheBug) {
|
||||
sos.writeUI8(bitmapCache);
|
||||
}
|
||||
}
|
||||
if (placeFlagHasVisible) {
|
||||
sos.writeUI8(visible);
|
||||
}
|
||||
if (placeFlagOpaqueBackground) {
|
||||
sos.writeRGBA(backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getPlaceObjectNum() {
|
||||
return 3;
|
||||
|
||||
@@ -463,6 +463,68 @@ public class PlaceObject4Tag extends PlaceObjectTypeTag implements ASMSourceCont
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
sos.writeUB(1, 0); //No clip actions
|
||||
sos.writeUB(1, placeFlagHasClipDepth ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasRatio ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasColorTransform ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasMatrix ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCharacter ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagMove ? 1 : 0);
|
||||
sos.writeUB(1, reserved ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagOpaqueBackground ? 1 : 0); //SWF11
|
||||
sos.writeUB(1, placeFlagHasVisible ? 1 : 0); //SWF11
|
||||
sos.writeUB(1, placeFlagHasImage ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasClassName ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasCacheAsBitmap ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasBlendMode ? 1 : 0);
|
||||
sos.writeUB(1, placeFlagHasFilterList ? 1 : 0);
|
||||
sos.writeUI16(depth);
|
||||
|
||||
if (placeFlagHasClassName) {
|
||||
sos.writeString(className);
|
||||
}
|
||||
if (placeFlagHasCharacter) {
|
||||
sos.writeUI16(characterId);
|
||||
}
|
||||
if (placeFlagHasMatrix) {
|
||||
sos.writeMatrix(matrix);
|
||||
}
|
||||
if (placeFlagHasColorTransform) {
|
||||
sos.writeCXFORMWITHALPHA(colorTransform);
|
||||
}
|
||||
if (placeFlagHasRatio) {
|
||||
sos.writeUI16(ratio);
|
||||
}
|
||||
if (placeFlagHasName) {
|
||||
sos.writeString(name);
|
||||
}
|
||||
if (placeFlagHasClipDepth) {
|
||||
sos.writeUI16(clipDepth);
|
||||
}
|
||||
if (placeFlagHasFilterList) {
|
||||
sos.writeFILTERLIST(surfaceFilterList);
|
||||
}
|
||||
if (placeFlagHasBlendMode) {
|
||||
sos.writeUI8(blendMode);
|
||||
}
|
||||
if (placeFlagHasCacheAsBitmap) {
|
||||
if (!bitmapCacheBug) {
|
||||
sos.writeUI8(bitmapCache);
|
||||
}
|
||||
}
|
||||
if (placeFlagHasVisible) {
|
||||
sos.writeUI8(visible);
|
||||
}
|
||||
if (placeFlagOpaqueBackground) {
|
||||
sos.writeRGBA(backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getPlaceObjectNum() {
|
||||
return 4;
|
||||
|
||||
@@ -561,6 +561,18 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
sos.write(originalRange.getArray(), originalRange.getPos(), originalRange.getLength());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes Tag value to the stream, ignoring all scripts
|
||||
* @param sos
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeTagNoScripts(SWFOutputStream sos) throws IOException {
|
||||
byte[] newData = getDataNoScript();
|
||||
byte[] newHeaderData = getHeader(newData.length);
|
||||
sos.write(newHeaderData);
|
||||
sos.write(newData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the tag.
|
||||
@@ -625,7 +637,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public abstract void getData(SWFOutputStream sos) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Gets data bytes
|
||||
*
|
||||
@@ -652,6 +664,30 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data bytes ignoring all scripts
|
||||
* @param sos SWF output stream
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public void getDataNoScript(SWFOutputStream sos) throws IOException {
|
||||
getData(sos);
|
||||
}
|
||||
|
||||
public byte[] getDataNoScript() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStream os = baos;
|
||||
try (SWFOutputStream sos = new SWFOutputStream(os, getVersion(), getCharset())) {
|
||||
getDataNoScript(sos);
|
||||
if (remainingData != null) {
|
||||
sos.write(remainingData);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error("This should never happen.", e);
|
||||
}
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets original byte range.
|
||||
|
||||
@@ -607,12 +607,12 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
public static void runAsync(File swfFile) {
|
||||
public static boolean runAsync(File swfFile) {
|
||||
String playerLocation = Configuration.playerLocation.get();
|
||||
if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
|
||||
ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
advancedSettings("paths");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final Process process = Runtime.getRuntime().exec(new String[]{playerLocation, swfFile.getAbsolutePath()});
|
||||
@@ -624,8 +624,10 @@ public class Main {
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
src/com/jpexs/decompiler/flash/gui/graphics/playflash16.png
Normal file
BIN
src/com/jpexs/decompiler/flash/gui/graphics/playflash16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -1073,4 +1073,6 @@ message.link.type.otherFile = Link to other SWF file (usually playerglobal.swc)
|
||||
message.link.type.otherFile.sample = String
|
||||
message.link.reallyGo = Do you really want to go to another SWF?
|
||||
|
||||
contextmenu.exportSubspriteAnimation = Export subsprite animation
|
||||
contextmenu.exportSubspriteAnimation = Export subsprite animation
|
||||
|
||||
contextmenu.showInFlashPlayer = Show in the Flash Player
|
||||
@@ -1072,4 +1072,6 @@ message.link.type.otherFile = Odkaz do jin\u00e9ho SWF souboru (obvykle playergl
|
||||
message.link.type.otherFile.sample = String
|
||||
message.link.reallyGo = Opravdu chcete p\u0159ej\u00edt do jin\u00e9ho SWF?
|
||||
|
||||
contextmenu.exportSubspriteAnimation = Export animace podsprit\u016f
|
||||
contextmenu.exportSubspriteAnimation = Export animace podsprit\u016f
|
||||
|
||||
contextmenu.showInFlashPlayer = Zobrazit ve Flash Playeru
|
||||
@@ -79,7 +79,7 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
rulerButton.addActionListener(this::rulerActionPerformed);
|
||||
rulerButton.setToolTipText(AppStrings.translate("button.ruler.hint"));
|
||||
rulerButton.setSelected(Configuration.showRuler.get());
|
||||
|
||||
|
||||
Configuration.showRuler.addListener(new ConfigurationItemChangeListener<Boolean>() {
|
||||
@Override
|
||||
public void configurationItemChanged(Boolean newValue) {
|
||||
@@ -114,7 +114,7 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
guidesOptionsButton.setToolTipText(AppStrings.translate("button.guides_options"));
|
||||
|
||||
snapOptionsButton = new SnapOptionsButton();
|
||||
|
||||
|
||||
PopupButton gridButton = new PopupButton(View.getIcon("grid16")) {
|
||||
@Override
|
||||
protected JPopupMenu getPopupMenu() {
|
||||
@@ -123,15 +123,15 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
showGridCheckBoxMenuItem.addActionListener(ZoomPanel.this::showGridCheckBoxMenuItemActionPerformed);
|
||||
showGridCheckBoxMenuItem.setSelected(Configuration.showGrid.get());
|
||||
menu.add(showGridCheckBoxMenuItem);
|
||||
|
||||
|
||||
JMenuItem editGridMenuItem = new JMenuItem(AppStrings.translate("grid_options.edit"));
|
||||
editGridMenuItem.addActionListener(ZoomPanel.this::editGridMenuItemActionPerformed);
|
||||
menu.add(editGridMenuItem);
|
||||
|
||||
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
};
|
||||
gridButton.setToolTipText(AppStrings.translate("button.grid_options"));
|
||||
gridButton.setToolTipText(AppStrings.translate("button.grid_options"));
|
||||
|
||||
|
||||
percentLabel.setToolTipText(AppStrings.translate("zoom.hint"));
|
||||
@@ -152,11 +152,11 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
} catch (NumberFormatException nfe) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
setLayout(new FlowLayout());
|
||||
add(percentLabel);
|
||||
add(zoomInButton);
|
||||
@@ -170,12 +170,12 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
|
||||
display.addEventListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void editGridMenuItemActionPerformed(ActionEvent evt) {
|
||||
new GridDialog(Main.getDefaultDialogsOwner()).setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
private void showGridCheckBoxMenuItemActionPerformed(ActionEvent evt) {
|
||||
JCheckBoxMenuItem source = (JCheckBoxMenuItem) evt.getSource();
|
||||
Configuration.showGrid.set(source.isSelected());
|
||||
@@ -194,7 +194,7 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
private void guidesEditActionPerformed(ActionEvent evt) {
|
||||
new GuidesDialog(Main.getDefaultDialogsOwner(), display).setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
private void guidesClearActionPerformed(ActionEvent evt) {
|
||||
display.clearGuides();
|
||||
}
|
||||
@@ -295,7 +295,7 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
zoomToFit = zoom.fit;
|
||||
realZoom = zoom.value;
|
||||
updateZoomDisplay();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui.tagtree;
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFHeader;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.TagRemoveListener;
|
||||
@@ -34,6 +35,7 @@ import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.CustomConfigurationKeys;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration;
|
||||
import com.jpexs.decompiler.flash.exporters.PreviewExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfFlashDevelopExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfIntelliJIdeaExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfVsCodeExporter;
|
||||
@@ -99,16 +101,21 @@ import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DepthTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PackedBinaryData;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.tags.converters.PlaceObjectTypeConverter;
|
||||
import com.jpexs.decompiler.flash.tags.converters.ShapeTypeConverter;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalSound;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.DefineExternalStreamSound;
|
||||
import com.jpexs.decompiler.flash.tags.gfx.ExporterInfo;
|
||||
import com.jpexs.decompiler.flash.timeline.AS2Package;
|
||||
import com.jpexs.decompiler.flash.timeline.AS3Package;
|
||||
@@ -140,14 +147,17 @@ import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.LinkedIdentityHashSet;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -202,7 +212,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
private JMenuItem undoTagMenuItem;
|
||||
|
||||
private JMenuItem exportSelectionMenuItem;
|
||||
|
||||
|
||||
private JMenuItem exportSubspriteAnimationMenuItem;
|
||||
|
||||
private JMenuItem exportABCMenuItem;
|
||||
@@ -325,6 +335,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
private JMenuItem showInEasyViewTagMenuItem;
|
||||
|
||||
private JMenuItem showInFlashPlayerMenuItem;
|
||||
|
||||
private JMenuItem showInFramesFolderMenuItem;
|
||||
|
||||
private JMenuItem addFramesMenuItem;
|
||||
@@ -468,6 +480,11 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
showInEasyViewTagMenuItem.setIcon(View.getIcon("easy16"));
|
||||
add(showInEasyViewTagMenuItem);
|
||||
|
||||
showInFlashPlayerMenuItem = new JMenuItem(mainPanel.translate("contextmenu.showInFlashPlayer"));
|
||||
showInFlashPlayerMenuItem.addActionListener(this::showInFlashPlayerActionPerformed);
|
||||
showInFlashPlayerMenuItem.setIcon(View.getIcon("playflash16"));
|
||||
add(showInFlashPlayerMenuItem);
|
||||
|
||||
textSearchMenuItem = new JMenuItem(mainPanel.translate("menu.tools.search"));
|
||||
textSearchMenuItem.addActionListener(this::textSearchActionPerformed);
|
||||
textSearchMenuItem.setIcon(View.getIcon("search16"));
|
||||
@@ -484,7 +501,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
});
|
||||
exportSelectionMenuItem.setIcon(View.getIcon("exportsel16"));
|
||||
add(exportSelectionMenuItem);
|
||||
|
||||
|
||||
exportSubspriteAnimationMenuItem = new JMenuItem(mainPanel.translate("contextmenu.exportSubspriteAnimation"));
|
||||
exportSubspriteAnimationMenuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -494,7 +511,6 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
});
|
||||
exportSubspriteAnimationMenuItem.setIcon(View.getIcon("exportsubsprites16"));
|
||||
add(exportSubspriteAnimationMenuItem);
|
||||
|
||||
|
||||
exportABCMenuItem = new JMenuItem(mainPanel.translate("contextmenu.exportAbc"));
|
||||
exportABCMenuItem.addActionListener(this::exportABCActionPerformed);
|
||||
@@ -1385,6 +1401,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
showInTagListViewTagMenuItem.setVisible(false);
|
||||
showInHexDumpViewTagMenuItem.setVisible(false);
|
||||
showInEasyViewTagMenuItem.setVisible(false);
|
||||
showInFlashPlayerMenuItem.setVisible(false);
|
||||
showInFramesFolderMenuItem.setVisible(false);
|
||||
addFramesMenuItem.setVisible(false);
|
||||
addFramesBeforeMenuItem.setVisible(false);
|
||||
@@ -1711,6 +1728,20 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
if (firstItem instanceof Timelined) {
|
||||
showInEasyViewTagMenuItem.setVisible(true);
|
||||
}
|
||||
if (((firstItem instanceof DrawableTag)
|
||||
|| (firstItem instanceof Frame)
|
||||
|| (firstItem instanceof TagScript)
|
||||
|| (firstItem instanceof SoundStreamHeadTypeTag)
|
||||
|| (firstItem instanceof DefineSoundTag)
|
||||
|| (firstItem instanceof DefineExternalSound)
|
||||
|| (firstItem instanceof DefineExternalStreamSound))
|
||||
&& !(firstItem instanceof ImageTag)
|
||||
&& ((firstItem instanceof SoundStreamHeadTypeTag)
|
||||
|| (firstItem instanceof DefineExternalStreamSound)
|
||||
|| !((firstItem instanceof CharacterIdTag) && !(firstItem instanceof CharacterTag)))
|
||||
&& !(firstItem instanceof FontTag)) {
|
||||
showInFlashPlayerMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if ((firstItem instanceof Tag)
|
||||
|| (firstItem instanceof CLIPACTIONRECORD)
|
||||
@@ -1789,7 +1820,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
changeCharsetMenu.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (firstItem instanceof Frame) {
|
||||
exportSubspriteAnimationMenuItem.setVisible(true);
|
||||
}
|
||||
@@ -4623,6 +4654,49 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
mainPanel.updateMenu();
|
||||
}
|
||||
|
||||
private void showInFlashPlayerActionPerformed(ActionEvent evt) {
|
||||
File tempFile = null;
|
||||
try {
|
||||
tempFile = File.createTempFile("ffdec_view_", ".swf");
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
Color backgroundColor = View.getSwfBackgroundColor();
|
||||
TreeItem treeItem = getCurrentItem();
|
||||
|
||||
if (treeItem instanceof PlaceObjectTypeTag) {
|
||||
treeItem = Main.getMainFrame().getPanel().getCurrentTree().getFullModel().getParent(treeItem); //should be a frame
|
||||
} else if (treeItem instanceof Tag) {
|
||||
Tag tag = (Tag) treeItem;
|
||||
if (tag instanceof FontTag) { //Fonts are always black on white
|
||||
backgroundColor = View.getDefaultBackgroundColor();
|
||||
}
|
||||
} else if (treeItem instanceof Frame) {
|
||||
Frame fn = (Frame) treeItem;
|
||||
SWF sourceSwf = (SWF) fn.getOpenable();
|
||||
if (fn.timeline.timelined == sourceSwf) {
|
||||
SetBackgroundColorTag setBgColorTag = sourceSwf.getBackgroundColor();
|
||||
if (setBgColorTag != null) {
|
||||
backgroundColor = setBgColorTag.backgroundColor.toColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
|
||||
new PreviewExporter().exportSwf(fos, treeItem, backgroundColor, 1/*fontPageNum ???*/, false);
|
||||
} catch (ActionParseException ex) {
|
||||
Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (!Main.runAsync(tempFile)) {
|
||||
tempFile.delete();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(TagTreeContextMenu.class.getName()).log(Level.SEVERE, null, ex);
|
||||
if (tempFile != null && tempFile.exists()) {
|
||||
tempFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void moveTagActionPerformed(ActionEvent evt) {
|
||||
Tag t = (Tag) getCurrentItem();
|
||||
TreePath path = getTree().getFullModel().getTreePath(t);
|
||||
|
||||
Reference in New Issue
Block a user