Esempio n. 1
0
        /// <summary>
        /// Generates a script that binds a class to a clip.
        /// </summary>
        /// <param name="spr">The sprite to create the class for.</param>
        public void GenerateClipClassBindingScript(Sprite spr)
        {
            Namespace nsEmptyPackage = this.CreateNamespace(Namespace.NamespaceKind.Package, string.Empty);
            Namespace nsFlashEvents  = this.CreateNamespace(Namespace.NamespaceKind.Package, "flash.events");
            Namespace nsFlashDisplay = this.CreateNamespace(Namespace.NamespaceKind.Package, "flash.display");

            Multiname mnObject                 = this.CreateMultiname(Multiname.MultinameKind.QName, "Object", nsEmptyPackage, null);
            Multiname mnEventDispatcher        = this.CreateMultiname(Multiname.MultinameKind.QName, "EventDispatcher", nsFlashEvents, null);
            Multiname mnDisplayObject          = this.CreateMultiname(Multiname.MultinameKind.QName, "DisplayObject", nsFlashDisplay, null);
            Multiname mnInteractiveObject      = this.CreateMultiname(Multiname.MultinameKind.QName, "InteractiveObject", nsFlashDisplay, null);
            Multiname mnDisplayObjectContainer = this.CreateMultiname(Multiname.MultinameKind.QName, "DisplayObjectContainer", nsFlashDisplay, null);
            Multiname mnSprite                 = this.CreateMultiname(Multiname.MultinameKind.QName, "Sprite", nsFlashDisplay, null);
            Multiname mnMovieClip              = this.CreateMultiname(Multiname.MultinameKind.QName, "MovieClip", nsFlashDisplay, null);

            Multiname sprQName     = null;
            Multiname sprMultiname = null;

            if (spr.Class.Name.Kind == Multiname.MultinameKind.Multiname)
            {
                sprMultiname = spr.Class.Name;

                /* ISSUE 5: Convert a multiname to a QName of the form:
                 * mn QName "MyClassName"; ns Package "com.mypackage"; set *
                 */
                throw new SWFModellerException(
                          SWFModellerError.UnimplementedFeature,
                          "Unsupported sprite class name kind in class binding script generation: " + spr.Class.Name.Kind.ToString());
            }
            else if (spr.Class.Name.Kind == Multiname.MultinameKind.QName)
            {
                sprQName = spr.Class.Name;

                /* Convert to form:
                 * mn Multiname "MyClassName"; ns *; set {ns Package "com.mypackage"}
                 */
                sprMultiname = this.CreateMultiname(
                    Multiname.MultinameKind.Multiname,
                    sprQName.Name,
                    nsEmptyPackage,
                    this.CreateNamespaceSet(new Namespace[] { sprQName.NS }));
            }
            else
            {
                /* ISSUE 73 */
                throw new SWFModellerException(
                          SWFModellerError.UnimplementedFeature,
                          "Unsupported sprite class name kind in class binding script generation: " + spr.Class.Name.Kind.ToString());
            }

            Method bindingMethod = this.CreateMethod(spr.Class.Name.Name + "BindingScript.abc", 2, 1, 1, 9,

                                                     /* 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. */

                                                     /* Line */
                                                     /*  1 */ this.Op(Opcode.Mnemonics.GetLocal0),
                                                     /*  2 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /*  3 */ this.Op(Opcode.Mnemonics.FindPropStrict, sprMultiname),
                                                     /*  4 */ this.Op(Opcode.Mnemonics.GetLex, mnObject),
                                                     /*  5 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /*  6 */ this.Op(Opcode.Mnemonics.GetLex, mnEventDispatcher),
                                                     /*  7 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /*  8 */ this.Op(Opcode.Mnemonics.GetLex, mnDisplayObject),
                                                     /*  9 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /* 10 */ this.Op(Opcode.Mnemonics.GetLex, mnInteractiveObject),
                                                     /* 11 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /* 12 */ this.Op(Opcode.Mnemonics.GetLex, mnDisplayObjectContainer),
                                                     /* 13 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /* 14 */ this.Op(Opcode.Mnemonics.GetLex, mnSprite),
                                                     /* 15 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /* 16 */ this.Op(Opcode.Mnemonics.GetLex, mnMovieClip),
                                                     /* 17 */ this.Op(Opcode.Mnemonics.PushScope),
                                                     /* 18 */ this.Op(Opcode.Mnemonics.GetLex, mnMovieClip),
                                                     /* 19 */ this.Op(Opcode.Mnemonics.NewClass, spr.Class),
                                                     /* 20 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 21 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 22 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 23 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 24 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 25 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 26 */ this.Op(Opcode.Mnemonics.PopScope),
                                                     /* 27 */ this.Op(Opcode.Mnemonics.InitProperty, sprQName),
                                                     /* 28 */ this.Op(Opcode.Mnemonics.ReturnVoid));

            Trait classTrait = new ClassTrait()
            {
                As3class = (AS3ClassDef)spr.Class,
                Kind     = TraitKind.Class,
                Name     = sprQName
            };

            bindingMethod.AddTrait(classTrait);

            Script bindScript = new Script()
            {
                Method = bindingMethod,
            };

            bindScript.AddTrait(classTrait);

            this.scripts.Insert(0, bindScript); /* Insert at the start to make sure any timeline script is last. */
        }
Esempio n. 2
0
        /// <summary>
        /// Read in a trait, which are like object properties.
        /// </summary>
        /// <returns>A trait.</returns>
        private Trait ReadTrait()
        {
            Trait     t         = null;
            Multiname traitName = this.code.GetMultiname((int)this.abcdtr.ReadU30());
            int       traitCode = this.abcdtr.ReadUI8();
            TraitKind kind      = (TraitKind)(traitCode & 0xF);

            switch (kind)
            {
            case TraitKind.Slot:
            case TraitKind.Const:
                SlotTrait st = new SlotTrait();
                st.Name = traitName;
                st.Kind = kind;

                st.SlotID   = this.abcdtr.ReadU30();
                st.TypeName = this.code.GetMultiname((int)this.abcdtr.ReadU30());

                uint vindex = this.abcdtr.ReadU30();

                if (vindex != 0)
                {
                    st.ValKind = (ConstantKind)this.abcdtr.ReadUI8();
                    switch (st.ValKind)
                    {
                    case ConstantKind.ConInt:
                        st.Val = this.code.IntConsts[vindex];
                        break;

                    case ConstantKind.ConUInt:
                        st.Val = this.code.UIntConsts[vindex];
                        break;

                    case ConstantKind.ConDouble:
                        st.Val = this.code.DoubleConsts[vindex];
                        break;

                    case ConstantKind.ConUtf8:
                        st.Val = this.code.StringConsts[vindex];
                        break;

                    case ConstantKind.ConTrue:
                    case ConstantKind.ConFalse:
                    case ConstantKind.ConNull:
                    case ConstantKind.ConUndefined:
                        break;

                    case ConstantKind.ConNamespace:
                    case ConstantKind.ConPackageNamespace:
                    case ConstantKind.ConPackageInternalNs:
                    case ConstantKind.ConProtectedNamespace:
                    case ConstantKind.ConExplicitNamespace:
                    case ConstantKind.ConStaticProtectedNs:
                    case ConstantKind.ConPrivateNs:
                        st.Val = this.code.GetNamespace((int)vindex);
                        break;

                    default:
                        throw new SWFModellerException(
                                  SWFModellerError.Internal,
                                  "Unsupported constant kind: " + st.ValKind.ToString());
                    }
                }

                t = st;
                break;

            case TraitKind.Class:
                ClassTrait ct = new ClassTrait();
                ct.Name = traitName;
                ct.Kind = kind;

                ct.SlotID = this.abcdtr.ReadU30();
                this.LateResolutions.Add(ct, (int)this.abcdtr.ReadU30());     /* We'll resolve the class ref later. */

                t = ct;
                break;

            case TraitKind.Function:
                FunctionTrait ft = new FunctionTrait();
                ft.Name = traitName;
                ft.Kind = kind;

                ft.SlotID = this.abcdtr.ReadU30();
                ft.Fn     = this.code.GetMethod((int)this.abcdtr.ReadU30());

                t = ft;
                break;

            case TraitKind.Method:
            case TraitKind.Getter:
            case TraitKind.Setter:
            default:
                MethodTrait mt = new MethodTrait();
                mt.Name = traitName;
                mt.Kind = kind;

                uint dispID = this.abcdtr.ReadU30();
                if (dispID != 0)
                {
                    mt.OverriddenMethod = this.code.GetMethod((int)dispID);
                }

                mt.Fn = this.code.GetMethod((int)this.abcdtr.ReadU30());

                t = mt;
                break;
            }

            return(t);
        }
Esempio n. 3
0
        public ASTrait(ABCFile abc, FlashReader reader)
            : this(abc)
        {
            TypeIndex = reader.Read7BitEncodedInt();
            byte trueKind = reader.ReadByte();

            var traitType = (TraitType)(trueKind & 0xF);
            Attributes = (TraitAttributes)(trueKind >> 4);
            #region Trait Reading
            switch (traitType)
            {
            case TraitType.Slot:
            case TraitType.Constant:
            {
                Data = new SlotConstantTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Method:
            case TraitType.Getter:
            case TraitType.Setter:
            {
                Data = new MethodGetterSetterTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };

                ((MethodGetterSetterTrait)Data).Method.ObjName = ObjName;
                break;
            }

            case TraitType.Class:
            {
                Data = new ClassTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Function:
            {
                Data = new FunctionTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            default:
                throw new Exception($"Invalid {nameof(ASTrait)} type: " + traitType);
            }
            #endregion

            if ((Attributes & TraitAttributes.Metadata) != 0)
            {
                MetadataIndices.Capacity = reader.Read7BitEncodedInt();
            }

            for (int i = 0; i < MetadataIndices.Capacity; i++)
            {
                MetadataIndices.Add(reader.Read7BitEncodedInt());
            }
        }
Esempio n. 4
0
        private void WriteTraitInfo(ABCDataTypeWriter writer, Trait t)
        {
            writer.WriteU30Packed((uint)this.MultinameID(t.Name));
            writer.WriteUI8((uint)t.Kind);

            switch (t.Kind)
            {
            case TraitKind.Slot:
            case TraitKind.Const:
                SlotTrait st = (SlotTrait)t;
                writer.WriteU30Packed(st.SlotID);
                writer.WriteU30Packed((uint)this.MultinameID(st.TypeName));

                if (st.Val == null)
                {
                    writer.WriteU30Packed(0);
                }
                else
                {
                    switch (st.ValKind)
                    {
                    case ConstantKind.ConInt:
                        writer.WriteU30Packed((uint)this.intMarshal.GetIDFor((int)st.Val));
                        break;

                    case ConstantKind.ConUInt:
                        writer.WriteU30Packed((uint)this.uintMarshal.GetIDFor((uint)st.Val));
                        break;

                    case ConstantKind.ConDouble:
                        writer.WriteU30Packed((uint)this.doubleMarshal.GetIDFor((ulong)st.Val));
                        break;

                    case ConstantKind.ConUtf8:
                        writer.WriteU30Packed((uint)this.stringMarshal.GetIDFor((string)st.Val));
                        break;

                    case ConstantKind.ConTrue:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(11);
                        break;

                    case ConstantKind.ConFalse:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(10);
                        break;

                    case ConstantKind.ConNull:
                        /* Through observation, this always gets set to 11, I do not know why. It
                         * seems though that it should be any non-zero number. */
                        writer.WriteU30Packed(12);
                        break;

                    case ConstantKind.ConUndefined:
                        /* Through observation, true, false and null all seem to have ignored but
                         * specific values. I haven't seen one for undefined, but I'm guessing it's
                         * 13. Really want to know what these number are. The don't seem to relate
                         * the string or multiname tables. */
                        writer.WriteU30Packed(13);
                        break;

                    case ConstantKind.ConNamespace:
                    case ConstantKind.ConPackageNamespace:
                    case ConstantKind.ConPackageInternalNs:
                    case ConstantKind.ConProtectedNamespace:
                    case ConstantKind.ConExplicitNamespace:
                    case ConstantKind.ConStaticProtectedNs:
                    case ConstantKind.ConPrivateNs:
                        writer.WriteU30Packed((uint)this.NamespaceID((Namespace)st.Val));
                        break;

                    default:
                        throw new SWFModellerException(
                                  SWFModellerError.Internal,
                                  "Unsupported constant type: " + st.ValKind.ToString());
                    }

                    writer.WriteUI8((uint)st.ValKind);
                }

                break;

            case TraitKind.Method:
            case TraitKind.Getter:
            case TraitKind.Setter:
                MethodTrait mt = (MethodTrait)t;
                if (mt.OverriddenMethod != null)
                {
                    writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(mt.OverriddenMethod));
                }
                else
                {
                    writer.WriteU30Packed(0);
                }

                writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(mt.Fn));
                break;

            case TraitKind.Class:
                ClassTrait ct = (ClassTrait)t;
                writer.WriteU30Packed((uint)ct.SlotID);
                writer.WriteU30Packed((uint)this.classMarshal.GetIDFor(ct.As3class));
                break;

            case TraitKind.Function:
                FunctionTrait ft = (FunctionTrait)t;
                writer.WriteU30Packed((uint)ft.SlotID);
                writer.WriteU30Packed((uint)this.methodMarshal.GetIDFor(ft.Fn));
                break;

            default:
                /* ISSUE 73 */
                throw new SWFModellerException(
                          SWFModellerError.UnimplementedFeature,
                          "Unsupported trait kind: " + t.Kind.ToString());
            }
        }