Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of a SWF with the same defaults as the
        /// Flash IDE.
        /// </summary>
        /// <param name="ctx">An optional object intended solely to give error messages
        /// some context.</param>
        /// <param name="generateScripts">True if you want to generate the default
        /// timeline scripts.</param>
        public SWF(SWFContext ctx, bool generateScripts)
        {
            this.Context = ctx;

            this.FrameWidth  = DefaultFrameWidth;
            this.FrameHeight = DefaultFrameHeight;
            this.Fps         = DefaultFPS;

            this.dictionary = new Dictionary <string, ICharacter>();

            this.scripts = new List <DoABC>();

            this.fonts = new List <SWFFont>();

            this.BackgroundColor = defaultBGColour;

            /* ISSUE 30: This list is read when the swf is written, but we never
             * add to it. We should add to it on instruction from swiffotron xml
             * attributes, and also when we infer that a read sprite should be
             * exported based on its position in the source SWF relative to its first
             * use. */
            this.exportOnFirstFrame = new List <Sprite>();

            this.clipClassMap = new Dictionary <AS3ClassDef, Timeline>();

            if (generateScripts)
            {
                this.GenerateTimelineScripts();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of a SWF with the same defaults as the
        /// Flash IDE.
        /// </summary>
        /// <param name="ctx">An optional object intended solely to give error messages
        /// some context.</param>
        /// <param name="generateScripts">True if you want to generate the default
        /// timeline scripts.</param>
        public SWF(SWFContext ctx, bool generateScripts)
        {
            this.Context = ctx;

            this.FrameWidth = DefaultFrameWidth;
            this.FrameHeight = DefaultFrameHeight;
            this.Fps = DefaultFPS;

            this.dictionary = new Dictionary<string, ICharacter>();

            this.scripts = new List<DoABC>();

            this.fonts = new List<SWFFont>();

            this.BackgroundColor = defaultBGColour;

            /* ISSUE 30: This list is read when the swf is written, but we never
             * add to it. We should add to it on instruction from swiffotron xml
             * attributes, and also when we infer that a read sprite should be
             * exported based on its position in the source SWF relative to its first
             * use. */
            this.exportOnFirstFrame = new List<Sprite>();

            this.clipClassMap = new Dictionary<AS3ClassDef, Timeline>();

            if (generateScripts)
            {
                this.GenerateTimelineScripts();
            }
        }
Exemplo n.º 3
0
        public void OnLoadAbc(bool lazyInit, SWFContext ctx, string abcName, int doAbcCount, byte[] bytecode)
        {
            string abcDir = TestDir + @"\abc\";

            Directory.CreateDirectory(abcDir);

            string name = ctx.Name + "." + abcName + doAbcCount + abcName + ".abc";

            using (FileStream fs = new FileStream(abcDir + name, FileMode.Create))
            {
                fs.Write(bytecode, 0, bytecode.Length);
            }

            StringBuilder abcReadLog = new StringBuilder();

            AbcCode code = new AbcReader().Read(bytecode, abcReadLog);

            StringBuilder abcd = new StringBuilder();

            code.ToStringModelView(0, abcd);
            byte[] dasmBytes = new ASCIIEncoding().GetBytes(abcd.ToString());

            using (FileStream fs = new FileStream(abcDir + name + ".txt", FileMode.Create))
            {
                fs.Write(dasmBytes, 0, dasmBytes.Length);
            }

            byte[] abcReadLogBytes = new ASCIIEncoding().GetBytes(abcReadLog.ToString());
            using (FileStream fs = new FileStream(abcDir + name + ".abcread.txt", FileMode.Create))
            {
                fs.Write(abcReadLogBytes, 0, abcReadLogBytes.Length);
            }
        }
Exemplo n.º 4
0
        public void OnLoadAbc(bool lazyInit, SWFContext ctx, string abcName, int doAbcCount, byte[] bytecode)
        {
            StringBuilder readLog = new StringBuilder();
            new AbcReader().Read(bytecode, readLog);

            using (FileStream modelOut = new FileStream(ctx.Name + ".ABCREAD" + "." + doAbcCount + ".txt", FileMode.Create))
            {
                byte[] ascii = new ASCIIEncoding().GetBytes(readLog.ToString());
                modelOut.Write(ascii, 0, ascii.Length);
            }
        }
Exemplo n.º 5
0
        public void OnLoadAbc(bool lazyInit, SWFContext ctx, string abcName, int doAbcCount, byte[] bytecode)
        {
            StringBuilder readLog = new StringBuilder();

            new AbcReader().Read(bytecode, readLog);

            using (FileStream modelOut = new FileStream(ctx.Name + ".ABCREAD" + "." + doAbcCount + ".txt", FileMode.Create))
            {
                byte[] ascii = new ASCIIEncoding().GetBytes(readLog.ToString());
                modelOut.Write(ascii, 0, ascii.Length);
            }
        }
Exemplo n.º 6
0
        public void OnLoadAbc(bool lazyInit, SWFContext ctx, string abcName, int doAbcCount, byte[] bytecode)
        {
            string abcDir = this.TestDir + @"\abc\";

            Directory.CreateDirectory(abcDir);

            string name = ctx.Name + "." + abcName + doAbcCount + abcName + ".abc";

            using (FileStream fs = new FileStream(abcDir + name, FileMode.Create))
            {
                fs.Write(bytecode, 0, bytecode.Length);
            }

            StringBuilder readLog = new StringBuilder();
            AbcCode       code    = null;

            try
            {
                code = new AbcReader().Read(bytecode, readLog);
            }
            catch (Exception e)
            {
                readLog.Append(e.Message);
                throw;
            }
            finally
            {
                using (FileStream fs = new FileStream(abcDir + name + ".readlog.txt", FileMode.Create))
                {
                    byte[] readLogBytes = new ASCIIEncoding().GetBytes(readLog.ToString());
                    fs.Write(readLogBytes, 0, readLogBytes.Length);
                }
            }

            StringBuilder abcd = new StringBuilder();

            code.ToStringModelView(0, abcd);
            byte[] dasmBytes = new ASCIIEncoding().GetBytes(abcd.ToString());

            using (FileStream fs = new FileStream(abcDir + name + ".txt", FileMode.Create))
            {
                fs.Write(dasmBytes, 0, dasmBytes.Length);
            }
        }
Exemplo n.º 7
0
        private void ReadHeader(SWFContext ctx)
        {
            int sig = this.sdtr.ReadUI24();

            if (sig != SIG_COMPRESSED && sig != SIG_UNCOMPRESSED)
            {
                throw new SWFModellerException(
                          SWFModellerError.SWFParsing,
                          @"Not a SWF file", ctx);
            }

            bool compressed = sig == SIG_COMPRESSED;

            this.version = this.sdtr.ReadUI8();
            if (this.version < 9)
            {
                throw new SWFModellerException(
                          SWFModellerError.SWFParsing,
                          @"Only SWF 9+ is supported (Found " + this.version + ")", ctx);
            }
#if DEBUG
            this.Log("SWF version = " + this.version);
#endif
            this.fileLen = this.sdtr.ReadUI32();

            if (compressed)
            {
                this.sdtr.SwitchToDeflateMode(this.fileLen);
            }

            this.frameSize = this.sdtr.ReadRect();

            this.fps = this.sdtr.ReadFIXED8();

            this.frameCount = this.sdtr.ReadUI16();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Merges some code into this code.
        /// </summary>
        /// <param name="abc">The code to merge into this object. Once merged, you should
        /// discard 'abc'.</param>
        internal void Merge(DoABC abc, SWFContext ctx)
        {
            /* Because we want everything to be object references... */

            AbcCode abcCode  = abc.Code; /* This is a kludge to force initial parsing of the abc data, if not done already */
            AbcCode thisCode = this.Code;

            abc.Disassemble(); /* This ensures that the code is disassembled into mergable form */
            this.Disassemble();

            foreach (AS3ClassDef clazz in abc.Code.Classes)
            {
                AS3ClassDef classCollision = thisCode.GetClassByQName(clazz.Name.QualifiedName);
                if (classCollision != null)
                {
                    throw new SWFModellerException(
                              SWFModellerError.CodeMerge,
                              "Class name collision on " + clazz.Name,
                              ctx.Sentinel("ClassNameCollision"));
                }

                thisCode.AddClass(clazz);
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Initializes a new instance of an exception without an error message
 /// </summary>
 /// <param name="error">The error code.</param>
 public SWFModellerException(SWFModellerError error, SWFContext ctx)
     : base(error.ToString() + "; " + ctx.ToString())
 {
     this.Error = error;
     this.Sentinel = ctx.ToString();
 }
Exemplo n.º 10
0
        /// <summary>
        /// Factory method for a new timeline class.
        /// </summary>
        /// <param name="abc">The abc code to create the class within.</param>
        /// <param name="packageName">Name of the fla. You can make this up, since you probably don't have
        /// a fla.</param>
        /// <param name="className">Name of the class.</param>
        /// <returns>A bew timeline class.</returns>
        private static AS3ClassDef GenerateTimelineClass(AbcCode abc, string qClassName, SWFContext ctx)
        {
            int splitPos = qClassName.LastIndexOf('.');

            if (splitPos < 0)
            {
                throw new SWFModellerException(SWFModellerError.CodeMerge,
                                               "A generated timeline class must have a package name.",
                                               ctx.Sentinel("TimelineDefaultPackage"));
            }

            string packageName = qClassName.Substring(0, splitPos);
            string className   = qClassName.Substring(splitPos + 1);

            /* Class name: */
            Namespace flaNS = abc.CreateNamespace(Namespace.NamespaceKind.Package, packageName);
            Multiname classMultinameName = abc.CreateMultiname(Multiname.MultinameKind.QName, className, flaNS, null);

            /* Superclass: */
            Namespace nsFlashDisplay = abc.CreateNamespace(Namespace.NamespaceKind.Package, "flash.display");
            Multiname mnMovieClip    = abc.CreateMultiname(Multiname.MultinameKind.QName, "MovieClip", nsFlashDisplay, null);

            AS3ClassDef newClass = abc.CreateClass();

            newClass.Name      = classMultinameName;
            newClass.Supername = mnMovieClip;

            Namespace protectedNS = abc.CreateNamespace(Namespace.NamespaceKind.Protected, packageName + ":" + className);

            newClass.ProtectedNS = protectedNS;

            newClass.Cinit = abc.CreateMethod(className + "Constructor.abc", 1, 1, 9, 10,

                                              /* The above magic numbers come from the numbers generated by IDE versions of this function.
                                               * I have no real ideal about how I'd work them out for myself, which would obviously be
                                               * more ideal. */

                                              /* AFAICT, this is always generated by the IDE because the abc file format
                                               * doesn't allow for classes with no static initialiser. It doesn't seem
                                               * to actually do anything. */

                                              abc.Op(Opcode.Mnemonics.GetLocal0),
                                              abc.Op(Opcode.Mnemonics.PushScope),
                                              abc.Op(Opcode.Mnemonics.ReturnVoid));

            newClass.Iinit = abc.CreateMethod(className + "ClassInit.abc", 1, 1, 10, 11,

                                              /* The above magic numbers come from the numbers generated by IDE versions of this function.
                                               * I have no real ideal about how I'd work them out for myself, which would obviously be
                                               * more ideal. */

                                              abc.Op(Opcode.Mnemonics.GetLocal0),
                                              abc.Op(Opcode.Mnemonics.PushScope),
                                              abc.Op(Opcode.Mnemonics.GetLocal0),
                                              abc.Op(Opcode.Mnemonics.ConstructSuper, 0U),

                                              abc.Op(Opcode.Mnemonics.ReturnVoid));

            return(newClass);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Factory method for a new timeline class.
        /// </summary>
        /// <param name="abc">The abc code to create the class within.</param>
        /// <param name="packageName">Name of the fla. You can make this up, since you probably don't have
        /// a fla.</param>
        /// <param name="className">Name of the class.</param>
        /// <returns>A bew timeline class.</returns>
        private static AS3ClassDef GenerateTimelineClass(AbcCode abc, string qClassName, SWFContext ctx)
        {
            int splitPos = qClassName.LastIndexOf('.');
            if (splitPos < 0)
            {
                throw new SWFModellerException(SWFModellerError.CodeMerge,
                        "A generated timeline class must have a package name.",
                        ctx.Sentinel("TimelineDefaultPackage"));
            }

            string packageName = qClassName.Substring(0, splitPos);
            string className = qClassName.Substring(splitPos + 1);

            /* Class name: */
            Namespace flaNS = abc.CreateNamespace(Namespace.NamespaceKind.Package, packageName);
            Multiname classMultinameName = abc.CreateMultiname(Multiname.MultinameKind.QName, className, flaNS, null);

            /* Superclass: */
            Namespace nsFlashDisplay = abc.CreateNamespace(Namespace.NamespaceKind.Package, "flash.display");
            Multiname mnMovieClip = abc.CreateMultiname(Multiname.MultinameKind.QName, "MovieClip", nsFlashDisplay, null);

            AS3ClassDef newClass = abc.CreateClass();

            newClass.Name = classMultinameName;
            newClass.Supername = mnMovieClip;

            Namespace protectedNS = abc.CreateNamespace(Namespace.NamespaceKind.Protected, packageName + ":" + className);

            newClass.ProtectedNS = protectedNS;

            newClass.Cinit = abc.CreateMethod(className + "Constructor.abc", 1, 1, 9, 10,

                /* The above magic numbers come from the numbers generated by IDE versions of this function.
                 * I have no real ideal about how I'd work them out for myself, which would obviously be
                 * more ideal. */

                /* AFAICT, this is always generated by the IDE because the abc file format
                 * doesn't allow for classes with no static initialiser. It doesn't seem
                 * to actually do anything. */

                abc.Op(Opcode.Mnemonics.GetLocal0),
                abc.Op(Opcode.Mnemonics.PushScope),
                abc.Op(Opcode.Mnemonics.ReturnVoid));

            newClass.Iinit = abc.CreateMethod(className + "ClassInit.abc", 1, 1, 10, 11,

                /* The above magic numbers come from the numbers generated by IDE versions of this function.
                 * I have no real ideal about how I'd work them out for myself, which would obviously be
                 * more ideal. */

                abc.Op(Opcode.Mnemonics.GetLocal0),
                abc.Op(Opcode.Mnemonics.PushScope),
                abc.Op(Opcode.Mnemonics.GetLocal0),
                abc.Op(Opcode.Mnemonics.ConstructSuper, 0U),

                abc.Op(Opcode.Mnemonics.ReturnVoid));

            return newClass;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Reads a SWF from the stream.
        /// </summary>
        /// <returns>A parsed SWF object</returns>
        public SWF ReadSWF(SWFContext ctx)
        {
            #if DEBUG
            this.MarkDumpOffset("Start of file");
            #endif

            this.jpegTable = null;

            this.sceneNotes = new List<FrameNote>();
            this.frameLabelNotes = new List<FrameNote>();

            this.ReadHeader(ctx);

            this.fontDict = new Dictionary<int, SWFFont>();

            this.frameCursor = 1;

            bool as3 = false;
            if (this.version >= 8)
            {
            #if DEBUG
                this.MarkDumpOffset("Start of file attributes tag");
            #endif
                this.ReadFileAttributesTag(out as3);
            }

            if (!as3)
            {
                throw new SWFModellerException(
                        SWFModellerError.SWFParsing,
                        @"AS2 and under is not supported.", ctx);
            }

            this.swf = new SWF(ctx, false);
            this.swf.FrameWidth = this.frameSize.Width;
            this.swf.FrameHeight = this.frameSize.Height;
            this.swf.Fps = this.fps;
            this.swf.FrameCount = this.frameCount;

            this.currentTimeline = this.swf;

            bool hasMore = true;
            do
            {
                hasMore = this.ReadTag();
            }
            while (hasMore);

            foreach (FrameNote note in this.sceneNotes)
            {
                this.swf.GetFrame((int)note.frame).SceneName = note.note;
            }

            foreach (FrameNote note in this.frameLabelNotes)
            {
                this.swf.GetFrame((int)note.frame).Label = note.note;
            }

            foreach (string className in this.LateClassResolutions.Keys)
            {
                swf.MapClassnameToClip(className, this.LateClassResolutions[className]);
            }

            return this.swf;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Merges some code into this code.
        /// </summary>
        /// <param name="abc">The code to merge into this object. Once merged, you should
        /// discard 'abc'.</param>
        internal void Merge(DoABC abc, SWFContext ctx)
        {
            /* Because we want everything to be object references... */

            AbcCode abcCode = abc.Code; /* This is a kludge to force initial parsing of the abc data, if not done already */
            AbcCode thisCode = this.Code;

            abc.Disassemble(); /* This ensures that the code is disassembled into mergable form */
            this.Disassemble();

            foreach (AS3ClassDef clazz in abc.Code.Classes)
            {
                AS3ClassDef classCollision = thisCode.GetClassByQName(clazz.Name.QualifiedName);
                if (classCollision != null)
                {
                    throw new SWFModellerException(
                            SWFModellerError.CodeMerge,
                            "Class name collision on " + clazz.Name,
                            ctx.Sentinel("ClassNameCollision"));
                }

                thisCode.AddClass(clazz);
            }
        }
Exemplo n.º 14
0
        private void ReadHeader(SWFContext ctx)
        {
            int sig = this.sdtr.ReadUI24();
            if (sig != SIG_COMPRESSED && sig != SIG_UNCOMPRESSED)
            {
                throw new SWFModellerException(
                        SWFModellerError.SWFParsing,
                        @"Not a SWF file", ctx);
            }

            bool compressed = sig == SIG_COMPRESSED;

            this.version = this.sdtr.ReadUI8();
            if (this.version < 9)
            {
                throw new SWFModellerException(
                        SWFModellerError.SWFParsing,
                        @"Only SWF 9+ is supported (Found " + this.version +")", ctx);
            }
            #if DEBUG
            this.Log("SWF version = " + this.version);
            #endif
            this.fileLen = this.sdtr.ReadUI32();

            if (compressed)
            {
                this.sdtr.SwitchToDeflateMode(this.fileLen);
            }

            this.frameSize = this.sdtr.ReadRect();

            this.fps = this.sdtr.ReadFIXED8();

            this.frameCount = this.sdtr.ReadUI16();
        }
Exemplo n.º 15
0
        public void OnLoadAbc(bool lazyInit, SWFContext ctx, string abcName, int doAbcCount, byte[] bytecode)
        {
            string abcDir = this.TestDir + @"\abc\";
            Directory.CreateDirectory(abcDir);

            string name = ctx.Name + "." + abcName + doAbcCount + abcName + ".abc";

            using (FileStream fs = new FileStream(abcDir + name, FileMode.Create))
            {
                fs.Write(bytecode, 0, bytecode.Length);
            }

            StringBuilder readLog = new StringBuilder();
            AbcCode code = null;

            try
            {
                code = new AbcReader().Read(bytecode, readLog);
            }
            catch (Exception e)
            {
                readLog.Append(e.Message);
                throw;
            }
            finally
            {
                using (FileStream fs = new FileStream(abcDir + name + ".readlog.txt", FileMode.Create))
                {
                    byte[] readLogBytes = new ASCIIEncoding().GetBytes(readLog.ToString());
                    fs.Write(readLogBytes, 0, readLogBytes.Length);
                }
            }

            StringBuilder abcd = new StringBuilder();
            code.ToStringModelView(0, abcd);
            byte[] dasmBytes = new ASCIIEncoding().GetBytes(abcd.ToString());

            using (FileStream fs = new FileStream(abcDir + name + ".txt", FileMode.Create))
            {
                fs.Write(dasmBytes, 0, dasmBytes.Length);
            }
        }
Exemplo n.º 16
0
 /// <summary>
 /// Initializes a new instance of an exception without an error message
 /// </summary>
 /// <param name="error">The error code.</param>
 public SWFModellerException(SWFModellerError error, SWFContext ctx)
     : base(error.ToString() + "; " + ctx.ToString())
 {
     this.Error    = error;
     this.Sentinel = ctx.ToString();
 }
Exemplo n.º 17
0
        /// <summary>
        /// Reads a SWF from the stream.
        /// </summary>
        /// <returns>A parsed SWF object</returns>
        public SWF ReadSWF(SWFContext ctx)
        {
#if DEBUG
            this.MarkDumpOffset("Start of file");
#endif

            this.jpegTable = null;

            this.sceneNotes      = new List <FrameNote>();
            this.frameLabelNotes = new List <FrameNote>();

            this.ReadHeader(ctx);

            this.fontDict = new Dictionary <int, SWFFont>();

            this.frameCursor = 1;

            bool as3 = false;
            if (this.version >= 8)
            {
#if DEBUG
                this.MarkDumpOffset("Start of file attributes tag");
#endif
                this.ReadFileAttributesTag(out as3);
            }

            if (!as3)
            {
                throw new SWFModellerException(
                          SWFModellerError.SWFParsing,
                          @"AS2 and under is not supported.", ctx);
            }

            this.swf             = new SWF(ctx, false);
            this.swf.FrameWidth  = this.frameSize.Width;
            this.swf.FrameHeight = this.frameSize.Height;
            this.swf.Fps         = this.fps;
            this.swf.FrameCount  = this.frameCount;

            this.currentTimeline = this.swf;

            bool hasMore = true;
            do
            {
                hasMore = this.ReadTag();
            }while (hasMore);

            foreach (FrameNote note in this.sceneNotes)
            {
                this.swf.GetFrame((int)note.frame).SceneName = note.note;
            }

            foreach (FrameNote note in this.frameLabelNotes)
            {
                this.swf.GetFrame((int)note.frame).Label = note.note;
            }

            foreach (string className in this.LateClassResolutions.Keys)
            {
                swf.MapClassnameToClip(className, this.LateClassResolutions[className]);
            }

            return(this.swf);
        }