diff --git a/trunk/lib/FlashPlayer.exe b/trunk/lib/FlashPlayer.exe index 6d3df290b..fd24e7944 100644 Binary files a/trunk/lib/FlashPlayer.exe and b/trunk/lib/FlashPlayer.exe differ diff --git a/trunk/libsrc/FlashPlayer/uMain.pas b/trunk/libsrc/FlashPlayer/uMain.pas index e873eebe5..8d8ab24c4 100644 --- a/trunk/libsrc/FlashPlayer/uMain.pas +++ b/trunk/libsrc/FlashPlayer/uMain.pas @@ -23,72 +23,113 @@ type type TMySWF = class(TShockwaveFlash) public - Procedure CreateWnd; override; + procedure CreateWnd; override; end; - type +type TPipeThread = class(TThread) protected - flashFile:string; - w:integer; - h:integer; - bgColor:TColor; + flashFile: string; + w: integer; + h: integer; + bgColor: TColor; procedure Execute; override; procedure displaySWF; + procedure freeSWF; procedure setPos; procedure setBGColor; end; TBuf = array[0..255] of byte; + var - frmMain: TfrmMain; - k:String; - t:TPipeThread; + frmMain: TfrmMain; + k: string; + t: TPipeThread; flaPreview: TMySWF; - target:HWND=0; + target: HWND = 0; + implementation {$R *.dfm} -Procedure TMySWF.CreateWnd; +procedure TMySWF.CreateWnd; begin inherited; -end; - -function arrToStr(k:TBuf;len:integer):string ; -var s:string; -i:integer; -begin - s:=''; - for i:=0 to len-1 do - begin - if k[i]=0 then - break; - s:=s +''+ chr(k[i]); - end; - Result:=s; end; -procedure TPipeThread.displaySWF(); +function arrToStr(k: TBuf; len: integer): string; +var + s: string; + i: integer; +begin + s := ''; + for i := 0 to len - 1 do + begin + if k[i] = 0 then + break; + s := s + '' + chr(k[i]); + end; + Result := s; +end; + +procedure ReadPipe(pipe: cardinal; var buffer: TBuf; bytesToRead: cardinal); +var + numBytesRead: DWORD; + readResult: longbool; +begin + numBytesRead := 0; + readResult := ReadFile(pipe, buffer, bytesToRead, numBytesRead, nil); + if (not readResult) or (numBytesRead <> bytesToRead) then + begin + Application.Terminate; + end; +end; + +procedure WritePipe(pipe: cardinal; var buffer: TBuf; bytesToWrite: cardinal); +var + written: cardinal; + writeResult: longbool; +begin + written := 0; + writeResult := WriteFile(pipe, buffer, bytesToWrite, written, nil); + if (not writeResult) or (written <> bytesToWrite) then + begin + Application.Terminate; + end; +end; + +procedure TPipeThread.freeSWF(); begin - windows.SetParent(frmMain.Handle,target); if Assigned(flaPreview) then begin + try flaPreview.Stop; flaPreview.Movie := ''; flaPreview.Free; flaPreview := nil; + except + on E: Exception do + begin + end; + end; end; +end; + +procedure TPipeThread.displaySWF(); +begin + Windows.SetParent(frmMain.Handle, target); + freeSWF(); flaPreview := TMySWF.Create(frmMain); - flaPreview.Left:=0; - flaPreview.Top:=0; - flaPreview.Width:=self.w; - flaPreview.Height:=self.h; - frmMain.Caption:='set movie:'+flashFile; + flaPreview.Left := 0; + flaPreview.Top := 0; + flaPreview.Width := self.w; + flaPreview.Height := self.h; + frmMain.Caption := 'set movie:' + flashFile; flaPreview.Parent := frmMain; - flaPreview.Movie:=flashFile; + flaPreview.Movie := flashFile; flaPreview.SetFocus; end; @@ -100,240 +141,345 @@ end; procedure TPipeThread.setPos(); begin -SetWindowPos(frmMain.Handle,0,0,0,self.w,self.h,SWP_SHOWWINDOW); -flaPreview.Left:=0; -flaPreview.Top:=0; -flaPreview.Width:=self.w; -flaPreview.Height:=self.h; -flaPreview.CreateWnd; -//displaySWF(); + SetWindowPos(frmMain.Handle, 0, 0, 0, self.w, self.h, SWP_SHOWWINDOW); + flaPreview.Left := 0; + flaPreview.Top := 0; + flaPreview.Width := self.w; + flaPreview.Height := self.h; + flaPreview.CreateWnd; + //displaySWF(); end; procedure TPipeThread.Execute(); -var pipe:cardinal; -numBytesRead:DWORD; -buffer:TBuf; -pipename:PAnsiChar; -len:integer; -cmd:integer; -written:cardinal; -val:cardinal; -vals:String; -vars:String; +var + f: Textfile; + pipe: cardinal; + buffer: TBuf; + pipename: PAnsiChar; + len: integer; + cmd: integer; + val: cardinal; + vals: string; + vars: string; const - CMD_PLAY = 1; - CMD_RESIZE = 2; - CMD_BGCOLOR = 3; - CMD_CURRENT_FRAME = 4; - CMD_TOTAL_FRAMES = 5; - CMD_PAUSE = 6; - CMD_RESUME = 7; - CMD_PLAYING = 8; - CMD_REWIND = 9; - CMD_GOTO = 10; - CMD_CALL = 11; - CMD_GETVARIABLE = 12; - CMD_SETVARIABLE = 13; + CMD_PLAY = 1; + CMD_RESIZE = 2; + CMD_BGCOLOR = 3; + CMD_CURRENT_FRAME = 4; + CMD_TOTAL_FRAMES = 5; + CMD_PAUSE = 6; + CMD_RESUME = 7; + CMD_PLAYING = 8; + CMD_REWIND = 9; + CMD_GOTO = 10; + CMD_CALL = 11; + CMD_GETVARIABLE = 12; + CMD_SETVARIABLE = 13; begin -pipename:=PAnsiChar('\\.\\pipe\ffdec_flashplayer_'+ParamStr(1)); -while (not self.Terminated) do -begin - pipe:=CreateFile(pipename,GENERIC_READ or GENERIC_WRITE, - FILE_SHARE_READ or FILE_SHARE_WRITE, - nil, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0 - ); - numBytesRead:= 0; - - repeat + AssignFile(f, 'c:\log\pipelog.txt'); + if FileExists('c:\log\pipelog.txt') = False then + Rewrite(f) + else begin - ReadFile(pipe,buffer,1,numBytesRead,nil); - cmd:=buffer[0]; - case cmd of - CMD_PLAY: - begin - ReadFile(pipe,buffer,1,numBytesRead,nil); - if(numBytesRead>0) then + Append(f); + end; + + try + pipename := PAnsiChar('\\.\\pipe\ffdec_flashplayer_' + ParamStr(1)); + begin + pipe := CreateFile(pipename, GENERIC_READ or GENERIC_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + + repeat + cmd := 0; + try + ReadPipe(pipe, buffer, 1); + cmd := buffer[0]; + case cmd of + CMD_PLAY: + begin + ReadPipe(pipe, buffer, 1); + len := buffer[0]; + ReadPipe(pipe, buffer, len); + self.flashFile := arrToStr(buffer, len); + try + Synchronize(displaySWF); + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_PLAY error: ' + E.Message); + Flush(f); + end; + end; + end; + CMD_RESIZE: + begin + ReadPipe(pipe, buffer, 4); + self.w := buffer[0] * 256 + buffer[1]; + self.h := buffer[2] * 256 + buffer[3]; + Synchronize(setPos); + end; + CMD_BGCOLOR: + begin + ReadPipe(pipe, buffer, 3); + self.bgColor := RGB(buffer[0], buffer[1], buffer[2]); + Synchronize(setBGColor); + end; + CMD_CURRENT_FRAME: + begin + val := 0; + try + if flaPreview.ReadyState = 4 then + val := flaPreview.CurrentFrame + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_CURRENT_FRAME error: ' + E.Message); + Flush(f); + end; + end; + buffer[0] := (val shr 8) mod 256; + buffer[1] := val mod 256; + WritePipe(pipe, buffer, 2); + end; + CMD_TOTAL_FRAMES: + begin + val := 0; + try + if flaPreview.ReadyState = 4 then + val := flaPreview.TotalFrames + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_TOTAL_FRAMES error: ' + E.Message); + Flush(f); + end; + end; + buffer[0] := (val shr 8) mod 256; + buffer[1] := val mod 256; + WritePipe(pipe, buffer, 2); + end; + CMD_PAUSE: + begin + try + flaPreview.Stop; + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_PAUSE error: ' + E.Message); + Flush(f); + end; + end; + end; + CMD_RESUME: + begin + try + flaPreview.Play; + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_RESUME error: ' + E.Message); + Flush(f); + end; + end; + end; + CMD_PLAYING: + begin + buffer[0] := 0; + try + if flaPreview.ReadyState = 4 then + if flaPreview.IsPlaying then + buffer[0] := 1; + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_PLAYING error: ' + E.Message); + Flush(f); + end; + end; + + WritePipe(pipe, buffer, 1); + end; + CMD_REWIND: + begin + try + flaPreview.Rewind; + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_REWIND error: ' + E.Message); + Flush(f); + end; + end; + end; + CMD_GOTO: + begin + ReadPipe(pipe, buffer, 2); + val := (buffer[0] shl 8) + buffer[1]; + try + flaPreview.GotoFrame(val); + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_GOTO error: ' + E.Message); + Flush(f); + end; + end; + end; + CMD_CALL: + begin + ReadPipe(pipe, buffer, 2); + val := (buffer[0] shl 8) + buffer[1]; + ReadPipe(pipe, buffer, val); + SetString(vals, PChar(Addr(buffer)), val); + vals := ''; + try + vals := flaPreview.CallFunction(vals); + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_CALL error: ' + E.Message); + Flush(f); + end; + end; + val := length(vals); + buffer[0] := (val shr 8) mod 256; + buffer[1] := val mod 256; + WritePipe(pipe, buffer, 2); + Move(vals[1], buffer, val); + WritePipe(pipe, buffer, val); + end; + CMD_GETVARIABLE: + begin + ReadPipe(pipe, buffer, 2); + val := (buffer[0] shl 8) + buffer[1]; + ReadPipe(pipe, buffer, val); + SetString(vals, PChar(Addr(buffer)), val); + vals := ''; + try + vals := flaPreview.GetVariable(vals); + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_GETVARIABLE error: ' + E.Message); + Flush(f); + end; + end; + val := length(vals); + buffer[0] := (val shr 8) mod 256; + buffer[1] := val mod 256; + WritePipe(pipe, buffer, 2); + Move(vals[1], buffer, val); + WritePipe(pipe, buffer, val); + end; + CMD_SETVARIABLE: + begin + ReadPipe(pipe, buffer, 2); + val := (buffer[0] shl 8) + buffer[1]; + ReadPipe(pipe, buffer, val); + SetString(vars, PChar(Addr(buffer)), val); + + ReadPipe(pipe, buffer, 2); + val := (buffer[0] shl 8) + buffer[1]; + ReadPipe(pipe, buffer, val); + SetString(vals, PChar(Addr(buffer)), val); + + try + flaPreview.SetVariable(vars, vals); + except + on E: Exception do + begin + freeSWF(); + Writeln(f, 'CMD_SETVARIABLE error: ' + E.Message); + Flush(f); + end; + end; + end; + end; + except + on E: Exception do begin - len:=buffer[0]; - ReadFile(pipe,buffer,len,numBytesRead,nil); - self.flashFile:=arrToStr(buffer,numBytesRead); - Synchronize(displaySWF); + freeSWF(); + Writeln(f, 'FATAL ERROR: ' + E.Message + ' cmd: ' + IntToStr(cmd)); + Flush(f); end; end; - CMD_RESIZE: - begin - ReadFile(pipe,buffer,4,numBytesRead,nil); - self.w:=buffer[0]*256+buffer[1]; - self.h:=buffer[2]*256+buffer[3]; - Synchronize(setPos); - end; - CMD_BGCOLOR: - begin - ReadFile(pipe,buffer,3,numBytesRead,nil); - self.bgColor := RGB(buffer[0],buffer[1],buffer[2]); - Synchronize(setBGColor); - end; - CMD_CURRENT_FRAME: - begin - if flaPreview.ReadyState = 4 then - val:=flaPreview.CurrentFrame - else - val:=0; - buffer[0]:=(val shr 8) mod 256; - buffer[1]:=val mod 256; - WriteFile(pipe,buffer,2,written,nil); - end; - CMD_TOTAL_FRAMES: - begin - if flaPreview.ReadyState = 4 then - val:=flaPreview.TotalFrames - else - val:=0; - buffer[0]:=(val shr 8) mod 256; - buffer[1]:=val mod 256; - WriteFile(pipe,buffer,2,written,nil); - end; - CMD_PAUSE: - begin - flaPreview.Stop; - end; - CMD_RESUME: - begin - flaPreview.Play; - end; - CMD_PLAYING: - begin - buffer[0]:=0; - if flaPreview.ReadyState = 4 then - if flaPreview.IsPlaying then - buffer[0]:=1; - - - WriteFile(pipe,buffer,1,written,nil); - end; - CMD_REWIND: - begin - flaPreview.Rewind; - end; - CMD_GOTO: - begin - ReadFile(pipe,buffer,2,numBytesRead,nil); - val := (buffer[0] shl 8) + buffer[1]; - flaPreview.GotoFrame(val); - end; - CMD_CALL: - begin - ReadFile(pipe,buffer,2,numBytesRead,nil); - val := (buffer[0] shl 8) + buffer[1]; - ReadFile(pipe,buffer,val,numBytesRead,nil); - SetString(vals, PChar(Addr(buffer)), val); - vals:=flaPreview.CallFunction(vals); - val:=length(vals); - buffer[0]:=(val shr 8) mod 256; - buffer[1]:=val mod 256; - WriteFile(pipe,buffer,2,written,nil); - Move(vals[1], buffer, val); - WriteFile(pipe,buffer,val,written,nil); - end; - CMD_GETVARIABLE: - begin - ReadFile(pipe,buffer,2,numBytesRead,nil); - val := (buffer[0] shl 8) + buffer[1]; - ReadFile(pipe,buffer,val,numBytesRead,nil); - SetString(vals, PChar(Addr(buffer)), val); - vals:=flaPreview.GetVariable(vals); - val:=length(vals); - buffer[0]:=(val shr 8) mod 256; - buffer[1]:=val mod 256; - WriteFile(pipe,buffer,2,written,nil); - Move(vals[1], buffer, val); - WriteFile(pipe,buffer,val,written,nil); - end; - CMD_SETVARIABLE: - begin - ReadFile(pipe,buffer,2,numBytesRead,nil); - val := (buffer[0] shl 8) + buffer[1]; - ReadFile(pipe,buffer,val,numBytesRead,nil); - SetString(vars, PChar(Addr(buffer)), val); - - ReadFile(pipe,buffer,2,numBytesRead,nil); - val := (buffer[0] shl 8) + buffer[1]; - ReadFile(pipe,buffer,val,numBytesRead,nil); - SetString(vals, PChar(Addr(buffer)), val); - - flaPreview.SetVariable(vars,vals); - - end; - end; - end - until numBytesRead<=0; - CloseHandle(pipe); - - -end; + until False; + CloseHandle(pipe); + end; + except + on E: Exception do + begin + end; + end; end; procedure TfrmMain.FormActivate(Sender: TObject); begin - - - -if(ParamCount>=2) then + if (ParamCount >= 2) then begin - flaPreview.Parent := frmMain; + flaPreview.Parent := frmMain; - ShowWindow(Application.Handle, SW_HIDE) ; - SetWindowLong(Application.Handle, GWL_EXSTYLE, getWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW) ; + ShowWindow(Application.Handle, SW_HIDE); + SetWindowLong(Application.Handle, GWL_EXSTYLE, + getWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW); ShowWindow(Application.Handle, SW_SHOW); - SetForegroundWindow(HWND(strtoint(ParamStr(2)))); - frmMain.Caption:='FlashPlayerWindow_'+ParamStr(2); - Application.Title:='FlashPlayerWindow_'+ParamStr(2); - target:=HWND(strtoint(ParamStr(1))); + SetForegroundWindow(HWND(StrToInt(ParamStr(2)))); + frmMain.Caption := 'FlashPlayerWindow_' + ParamStr(2); + Application.Title := 'FlashPlayerWindow_' + ParamStr(2); + target := HWND(StrToInt(ParamStr(1))); SetWindowLong(frmMain.Handle, GWL_STYLE, 0); ShowWindow(frmMain.Handle, SW_SHOW); - frmMain.Left:=0; - frmMain.Top:=0; - windows.SetParent(frmMain.Handle,target); + frmMain.Left := 0; + frmMain.Top := 0; + Windows.SetParent(frmMain.Handle, target); - t:=TPipeThread.Create(true); + t := TPipeThread.Create(True); t.Resume; end; end; procedure TfrmMain.FormCreate(Sender: TObject); begin - if(ParamCount>=2) then - begin - flaPreview := TMySWF.Create(frmMain); - flaPreview.AllowScriptAccess := 'always'; - flaPreview.BackgroundColor:=-1; + if (ParamCount >= 2) then + begin + flaPreview := TMySWF.Create(frmMain); + flaPreview.AllowScriptAccess := 'always'; + flaPreview.BackgroundColor := -1; end; end; procedure TfrmMain.FormDestroy(Sender: TObject); begin -t.Free; + t.Free; end; procedure TfrmMain.tmrWatchDogTimer(Sender: TObject); begin - if target<>0 then - begin + if target <> 0 then + begin if not IsWindow(target) then begin Application.Terminate; end; - end; + end; end; end. diff --git a/trunk/libsrc/Swf2Exe/uMain.pas b/trunk/libsrc/Swf2Exe/uMain.pas index fa5a3537a..178fbec17 100644 --- a/trunk/libsrc/Swf2Exe/uMain.pas +++ b/trunk/libsrc/Swf2Exe/uMain.pas @@ -20,17 +20,18 @@ type type TMySWF = class(TShockwaveFlash) public - Procedure CreateWnd; override; + procedure CreateWnd; override; end; var - frmMain: TfrmMain; + frmMain: TfrmMain; flaPreview: TMySWF; + implementation {$R *.dfm} -Procedure TMySWF.CreateWnd; +procedure TMySWF.CreateWnd; begin inherited; end; @@ -40,13 +41,13 @@ const exeSize = 470016; var stream: TFileStream; - buffer: array of Byte; - tempFile: array[0..MAX_PATH - 1] of Char; - tempPath: array[0..MAX_PATH - 1] of Char; - flashVarData : TVarData; - width: Integer; - height: Integer; - scaleMode: Byte; + buffer: array of byte; + tempFile: array[0..MAX_PATH - 1] of char; + tempPath: array[0..MAX_PATH - 1] of char; + flashVarData: TVarData; + Width: integer; + Height: integer; + scaleMode: byte; begin flaPreview := TMySWF.Create(frmMain); flaPreview.Parent := frmMain; @@ -54,14 +55,13 @@ begin flaPreview.Align := alClient; GetTempPath(MAX_PATH, TempPath); if GetTempFileName(TempPath, PAnsiChar('ffd'), 0, TempFile) = 0 then - raise Exception.Create( - 'GetTempFileName API failed. ' + SysErrorMessage(GetLastError) - ); + raise Exception.Create('GetTempFileName API failed. ' + + SysErrorMessage(GetLastError)); try stream := TFileStream.Create(ParamStr(0), fmOpenRead); stream.Seek(exeSize, soBeginning); - stream.Read(width, 4); - stream.Read(height, 4); + stream.Read(Width, 4); + stream.Read(Height, 4); stream.Read(scaleMode, 1); SetLength(buffer, stream.Size - exeSize); try @@ -70,12 +70,12 @@ begin stream.Free; end; except - width := 12800; - height := 9600; + Width := 12800; + Height := 9600; scaleMode := 3; end; - ClientWidth := width div 20; - ClientHeight := height div 20; + ClientWidth := Width div 20; + ClientHeight := Height div 20; stream := TFileStream.Create(tempFile, fmOpenWrite); try stream.Write(buffer[0], Length(buffer)); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java index ae24faff3..015e5ba2a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -42,7 +42,6 @@ import com.jpexs.decompiler.flash.gui.player.PlayerControls; import com.jpexs.decompiler.flash.gui.treenodes.SWFBundleNode; import com.jpexs.decompiler.flash.gui.treenodes.SWFNode; import com.jpexs.decompiler.flash.helpers.Freed; -import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag; @@ -144,7 +143,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -163,7 +161,6 @@ import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JColorChooser; -import javax.swing.JEditorPane; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/TagTree.java b/trunk/src/com/jpexs/decompiler/flash/gui/TagTree.java index 6c9c185bd..346c41c98 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/TagTree.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/TagTree.java @@ -57,9 +57,7 @@ import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.flash.treenodes.TreeNode; import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; import java.awt.Font; -import java.awt.FontMetrics; import java.awt.Graphics; import java.util.ArrayList; import java.util.List; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java index 76aa7e772..b2135ff76 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/generictageditors/StringEditor.java @@ -18,8 +18,6 @@ package com.jpexs.decompiler.flash.gui.generictageditors; import java.awt.Color; import java.lang.reflect.Field; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.JTextArea; /** diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index f8bc82f6c..aba6ada3d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.gui.player; import com.jpexs.decompiler.flash.gui.FlashUnsupportedException; +import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.utf8.Utf8Helper; import com.sun.jna.Native; import com.sun.jna.Platform; @@ -35,8 +36,12 @@ import java.awt.Panel; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.io.File; -import java.util.ArrayList; -import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -47,8 +52,9 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private boolean executed = false; private String flash; private HANDLE pipe; - private static final List processes = new ArrayList<>(); - private static final List pipes = new ArrayList<>(); + private HANDLE process; + private WinDef.HWND hwnd; + private WinDef.HWND hwndFrame; private Component frame; private boolean stopped = true; private static final int CMD_PLAY = 1; @@ -64,22 +70,22 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private static final int CMD_CALL = 11; private static final int CMD_GETVARIABLE = 12; private static final int CMD_SETVARIABLE = 13; + private static final int PIPE_TIMEOUT_MS = 1000; private int frameRate; public boolean specialPlayback = false; private boolean specialPlaying = false; public synchronized String getVariable(String name) { if (pipe != null) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_GETVARIABLE}, 1, ibr, null); + writeToPipe(new byte[]{CMD_GETVARIABLE}); int nameLen = name.getBytes().length; - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}, 2, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, name.getBytes(), nameLen, ibr, null); + writeToPipe(new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}); + writeToPipe(name.getBytes()); byte res[] = new byte[2]; - if (Kernel32.INSTANCE.ReadFile(pipe, res, 2, ibr, null)) { + if (readFromPipe(res)) { int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff); res = new byte[retLen]; - if (Kernel32.INSTANCE.ReadFile(pipe, res, retLen, ibr, null)) { + if (readFromPipe(res)) { String ret = new String(res, 0, retLen); return ret; } else { @@ -94,31 +100,29 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { public synchronized void setVariable(String name, String value) { if (pipe != null) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_SETVARIABLE}, 1, ibr, null); + writeToPipe(new byte[]{CMD_SETVARIABLE}); int nameLen = name.getBytes().length; - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}, 2, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, name.getBytes(), nameLen, ibr, null); + writeToPipe(new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}); + writeToPipe(name.getBytes()); int valLen = value.getBytes().length; - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((valLen >> 8) & 0xff), (byte) (valLen & 0xff)}, 2, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, value.getBytes(), valLen, ibr, null); + writeToPipe(new byte[]{(byte) ((valLen >> 8) & 0xff), (byte) (valLen & 0xff)}); + writeToPipe(value.getBytes()); } } public synchronized String call(String callString) { if (pipe != null) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_CALL}, 1, ibr, null); + writeToPipe(new byte[]{CMD_CALL}); int callLen = callString.getBytes().length; - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((callLen >> 8) & 0xff), (byte) (callLen & 0xff)}, 2, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, callString.getBytes(), callLen, ibr, null); + writeToPipe(new byte[]{(byte) ((callLen >> 8) & 0xff), (byte) (callLen & 0xff)}); + writeToPipe(callString.getBytes()); byte res[] = new byte[2]; - if (Kernel32.INSTANCE.ReadFile(pipe, res, 2, ibr, null)) { + if (readFromPipe(res)) { int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff); res = new byte[retLen]; - if (Kernel32.INSTANCE.ReadFile(pipe, res, retLen, ibr, null)) { + if (readFromPipe(res)) { String ret = new String(res, 0, retLen); return ret; } else { @@ -133,19 +137,17 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private synchronized void resize() { if (pipe != null) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_RESIZE}, 1, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{ + writeToPipe(new byte[]{CMD_RESIZE}); + writeToPipe(new byte[]{ (byte) (getWidth() / 256), (byte) (getWidth() % 256), - (byte) (getHeight() / 256), (byte) (getHeight() % 256),}, 4, ibr, null); + (byte) (getHeight() / 256), (byte) (getHeight() % 256),}); } } private int __getCurrentFrame() { byte[] res = new byte[2]; - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_CURRENT_FRAME}, 1, ibr, null); - if (Kernel32.INSTANCE.ReadFile(pipe, res, res.length, ibr, null)) { + writeToPipe(new byte[]{CMD_CURRENT_FRAME}); + if (readFromPipe(res)) { return ((res[0] & 0xff) << 8) + (res[1] & 0xff); } else { return 0; @@ -175,9 +177,8 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } } byte[] res = new byte[2]; - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_TOTAL_FRAMES}, 1, ibr, null); - if (Kernel32.INSTANCE.ReadFile(pipe, res, res.length, ibr, null)) { + writeToPipe(new byte[]{CMD_TOTAL_FRAMES}); + if (readFromPipe(res)) { return ((res[0] & 0xff) << 8) + (res[1] & 0xff); } else { return 0; @@ -186,9 +187,8 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { @Override public synchronized void setBackground(Color color) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_BGCOLOR}, 1, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}, 3, ibr, null); + writeToPipe(new byte[]{CMD_BGCOLOR}); + writeToPipe(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); } public FlashPlayerPanel(Component frame) { @@ -216,9 +216,28 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } }); } - private WinDef.HWND hwndFrame; - private void execute() { + private synchronized void execute() { + if (!executed) { + hwnd = new WinDef.HWND(); + hwnd.setPointer(Native.getComponentPointer(this)); + + hwndFrame = new WinDef.HWND(); + hwndFrame.setPointer(Native.getComponentPointer(frame)); + + startFlashPlayer(); + + executed = true; + } + } + + private void restartFlashPlayer() { + Kernel32.INSTANCE.TerminateProcess(process, 0); + Kernel32.INSTANCE.CloseHandle(pipe); + startFlashPlayer(); + } + + private void startFlashPlayer() { String path = Utf8Helper.urlDecode(FlashPlayerPanel.class.getProtectionDomain().getCodeSource().getLocation().getPath()); String appDir = new File(path).getParentFile().getAbsolutePath(); if (!appDir.endsWith("\\")) { @@ -230,13 +249,8 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { return; } - WinDef.HWND hwnd = new WinDef.HWND(); - hwnd.setPointer(Native.getComponentPointer(this)); - - hwndFrame = new WinDef.HWND(); - hwndFrame.setPointer(Native.getComponentPointer(frame)); - - pipe = Kernel32.INSTANCE.CreateNamedPipe("\\\\.\\pipe\\ffdec_flashplayer_" + hwnd.getPointer().hashCode(), Kernel32.PIPE_ACCESS_DUPLEX, Kernel32.PIPE_TYPE_BYTE, 1, 0, 0, 0, null); + String pipeName = "\\\\.\\pipe\\ffdec_flashplayer_" + hwnd.getPointer().hashCode(); + pipe = Kernel32.INSTANCE.CreateNamedPipe(pipeName, Kernel32.PIPE_ACCESS_DUPLEX, Kernel32.PIPE_TYPE_BYTE, 1, 0, 0, 0, null); SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO(); sei.fMask = 0x00000040; @@ -244,13 +258,11 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { sei.lpParameters = new WString(hwnd.getPointer().hashCode() + " " + hwndFrame.getPointer().hashCode()); sei.nShow = WinUser.SW_NORMAL; Shell32.INSTANCE.ShellExecuteEx(sei); - processes.add(sei.hProcess); + process = sei.hProcess; Kernel32.INSTANCE.ConnectNamedPipe(pipe, null); - pipes.add(pipe); - executed = true; } - + public synchronized void stopSWF() { displaySWF("-", null, 1); stopped = true; @@ -264,25 +276,15 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { this.flash = flash; repaint(); this.frameRate = frameRate; - if (!executed) { - execute(); - /* - //How about commenting this out? Will it work? Let's try... - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - Logger.getLogger(FlashPlayerPanel.class.getName()).log(Level.SEVERE, null, ex); - }*/ - } + execute(); if (bgColor != null) { setBackground(bgColor); } resize(); if (pipe != null) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_PLAY}, 1, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) flash.getBytes().length}, 1, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, flash.getBytes(), flash.getBytes().length, ibr, null); + writeToPipe(new byte[]{CMD_PLAY}); + writeToPipe(new byte[]{(byte) flash.getBytes().length}); + writeToPipe(flash.getBytes()); } stopped = false; specialPlaying = false; @@ -292,18 +294,25 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } } + @Override + protected void finalize() throws Throwable { + super.finalize(); + Kernel32.INSTANCE.CloseHandle(pipe); + Kernel32.INSTANCE.TerminateProcess(process, 0); + } + public static void unload() { - if (Platform.isWindows()) { + /*if (Platform.isWindows()) { for (int i = 0; i < processes.size(); i++) { Kernel32.INSTANCE.CloseHandle(pipes.get(i)); Kernel32.INSTANCE.TerminateProcess(processes.get(i), 0); } - } + }*/ } @Override public void paint(Graphics g) { - if ((!executed) && flash != null) { + if (flash != null) { execute(); } super.paint(g); @@ -311,8 +320,7 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private int specialPosition = 0; private synchronized void __pause() { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_PAUSE}, 1, ibr, null); + writeToPipe(new byte[]{CMD_PAUSE}); } @Override @@ -339,13 +347,11 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { return; } - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_REWIND}, 1, ibr, null); + writeToPipe(new byte[]{CMD_REWIND}); } private synchronized void __play() { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_RESUME}, 1, ibr, null); + writeToPipe(new byte[]{CMD_RESUME}); } @Override @@ -366,10 +372,9 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { if (specialPlayback) { return specialPlaying; } - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_PLAYING}, 1, ibr, null); + writeToPipe(new byte[]{CMD_PLAYING}); byte[] res = new byte[1]; - if (Kernel32.INSTANCE.ReadFile(pipe, res, res.length, ibr, null)) { + if (readFromPipe(res)) { return res[0] == 1; } else { return false; @@ -377,9 +382,8 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } private synchronized void __gotoFrame(int frame) { - IntByReference ibr = new IntByReference(); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_GOTO}, 1, ibr, null); - Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((frame >> 8) & 0xff), (byte) (frame & 0xff)}, 2, ibr, null); + writeToPipe(new byte[]{CMD_GOTO}); + writeToPipe(new byte[]{(byte) ((frame >> 8) & 0xff), (byte) (frame & 0xff)}); } @Override @@ -409,4 +413,64 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { public boolean isLoaded() { return !isStopped(); } + + private synchronized boolean writeToPipe(final byte[] data) { + final IntByReference ibr = new IntByReference(); + int result = -1; + try { + result = CancellableWorker.call(new Callable() { + @Override + public Integer call() throws Exception { + boolean result = Kernel32.INSTANCE.WriteFile(pipe, data, data.length, ibr, null); + if (!result) { + return Kernel32.INSTANCE.GetLastError(); + } + if (ibr.getValue() != data.length) { + return -1; + } + return 0; + } + }, PIPE_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException ex) { + // ignore + } + if (result != 0) { + if (result == Kernel32.ERROR_NO_DATA || result == -1) { + restartFlashPlayer(); + } else { + // System.out.println("pipe write failed. datalength: " + data.length + " error:" + result); + } + } + return result == 0; + } + + private synchronized boolean readFromPipe(final byte[] res) { + final IntByReference ibr = new IntByReference(); + int result = -1; + try { + result = CancellableWorker.call(new Callable() { + @Override + public Integer call() throws Exception { + boolean result = Kernel32.INSTANCE.ReadFile(pipe, res, res.length, ibr, null); + if (!result) { + return Kernel32.INSTANCE.GetLastError(); + } + if (ibr.getValue() != res.length) { + return -1; + } + return 0; + } + }, PIPE_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException ex) { + // ignore + } + if (result != 0) { + if (result == Kernel32.ERROR_BROKEN_PIPE || result == -1) { + restartFlashPlayer(); + } else { + // System.out.println("pipe read failed. result: " + result + " datalength: " + res.length + " received: " + ibr.getValue() + " error: " + result); + } + } + return result == 0; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java index 39f29092c..219d74083 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineBodyPanel.java @@ -16,8 +16,6 @@ */ package com.jpexs.decompiler.flash.gui.timeline; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Timeline; import java.awt.Color; @@ -56,7 +54,7 @@ public class TimelineBodyPanel extends JPanel implements MouseListener { public static final int borderLinesLength = 2; public static final float fontSize = 10.0f; - private List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); public Point cursor = null; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineDepthPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineDepthPanel.java index 68a158b5f..24e83d988 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineDepthPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineDepthPanel.java @@ -29,7 +29,7 @@ import javax.swing.JPanel; */ public class TimelineDepthPanel extends JPanel { - private int maxDepth; + private final int maxDepth; public static final int padding = 5; public static final float fontSize = 10.0f; private int scrollOffset = 0; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java index 71a725c4c..64b93bf0c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelinePanel.java @@ -17,19 +17,12 @@ package com.jpexs.decompiler.flash.gui.timeline; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.timeline.Timeline; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Container; import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineTimePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineTimePanel.java index 22110568f..832dfa0cb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineTimePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/timeline/TimelineTimePanel.java @@ -39,7 +39,7 @@ public class TimelineTimePanel extends JPanel implements MouseListener { public float fontSize = 10.0f; private int scrollOffset = 0; private int selectedFrame = -1; - private List listeners = new ArrayList<>(); + private final List listeners = new ArrayList<>(); public TimelineTimePanel() { Dimension dim = new Dimension(Integer.MAX_VALUE, TimelinePanel.FRAME_HEIGHT); diff --git a/trunk/src/com/jpexs/helpers/SerializableImage.java b/trunk/src/com/jpexs/helpers/SerializableImage.java index a31ff6ac5..f8da37615 100644 --- a/trunk/src/com/jpexs/helpers/SerializableImage.java +++ b/trunk/src/com/jpexs/helpers/SerializableImage.java @@ -74,9 +74,11 @@ public class SerializableImage implements Serializable { @Override protected Object clone() throws CloneNotSupportedException { - SerializableImage image = new SerializableImage(); - image.image = this.image; - return image; + SerializableImage retImage = new SerializableImage(); + retImage.image = image; + retImage.bounds = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), + bounds.getWidth(), bounds.getHeight()); + return retImage; } public Graphics getGraphics() { @@ -125,10 +127,12 @@ public class SerializableImage implements Serializable { } private void writeObject(ObjectOutputStream out) throws IOException { + out.writeObject(bounds); ImageIO.write(image, "png", out); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + bounds = (Rectangle2D) in.readObject(); image = ImageIO.read(in); } }