Category: Flash

  • Anti-blogspam: MTGotoAndComment Deployment Methods?

    It’s too early to declare victory over blogspam utilzing a SWF form to pass a hidden variable to Perl via MTGotoAndComment’s Flash form. However, it’s been just about 24 hours since my initial deployment, and I’ve received no blogspam in the hundreds like usually happens in a 24 hour period.

    I’m risking underestimating my enemy by assuming they will not be able to solve the SWF form riddle by Sunday evening, so without another gerund use, I’m curious what forms of deployment people think is best, specifically, how the SWF is written and loaded.

    1. Create a AS2, Flash Player 7.0.53.0 version of MTGotoAndComment’s Flash form, and hand off with the necessarey Perl code (3 lines) to be added to lib/App/Comments.pm.
    2. Same as above, except create an AS1, Flash Player 6.0.0.0 version.
    3. Same as above, except create an AS1, Flash Player 6.0.79.0 version.
    4. Create an AS2, Flash Player 7.0.53.0, FP 6.0.79.0 version, a 6.0.0.0 version, and a loader movie to detect version, and load as necessarey.

    The reason I like #1 is I don’t get paid for this jazz, and it’s pure benevolence for my fellow man that I even spend time fighting off this evil. It’s quick, it works on all platforms & browsers (win, mac, linux, solaris, ie, safari, mozilla), and takes advantage of Flash Player 7’s speed of runtime, and speed to create content. If there is a bug found, it’s pretty quick for me to fix and re-deploy a new version.

    The reason I like #2 is so I can target the most amount of users, and I don’t have to code any Flash; I just rig the cab file in the HTML to point to that version #, and utilize St

  • Flash Remoting in AS2: RelayResponder2

    Flash MX 2004 with ActionScript v2.0 introduced enhanced syntax checking. For example, if you have a function in your class, and you mispell it, the compiler will throw an error, helping you easily find and correct the answer so your code will run as expected.

    The AS2 classes for Flash Remoting do not take advantage of this fact for RelayResponders. I fixed that. Instead of passing in strings for your result and fault functions, you can pass in the functions themselves, much like you do for the first format setInterval, or when utilizing the Delegate class.

    What’s different from the original (mx.rpc.RelayResponder)? Only that the __onResult and __onFault functions are now datatyped as Function vs. String, and called via Function.call(scope, param) vs. scope[string](param).

    import mx.rpc.Responder;

    class mx.rpc.RelayResponder2 extends Object implements Responder {

    private var __obj:Object;
    private var __onFault:Function; private var __onResult:Function;

    function RelayResponder2( resp:Object, resultFunc:Function, faultFunc:Function ) {
    super();
    __obj = resp;
    __onFault = faultFunc;
    __onResult = resultFunc;
    }

    function onFault( fault:mx.rpc.FaultEvent ):Void{
    __onFault.call(__obj, fault);
    }

    function onResult( result:mx.rpc.ResultEvent ):Void {
    __onResult.call(__obj, result);
    }
    }
  • Flash Date to MySQL Date String

    Was doing some AMFPHP work with Flash & MySQL Saturday, and doing your typical data massaging/conversion that one does in the imperfect world of webservices. I needed to have a Flash Date object stored in MySQL and have it come back out again to be usable for the DateField component in Flash. Since the MySQL Date colum type is easily created as a String, it was only a matter of going back to a Flash Date.

    Maybe if someone’s bored, they can add the mask required to have this functionality in Darron’s DateFormat class.

    GOTCHA: The Date object in Flash returns a 0 based month value. So, December is 11, not 12.

    Example:

    a = new Date();
    trace(a); // Tue Dec 7 07:33:08 GMT-0500 2004
    s = getFormatFromDate(a);
    trace(s); // 2004-11-07 07:33:08
    d = getDateFromFormat(s);
    trace(d); // Tue Dec 7 07:33:08 GMT-0500 2004
    
    function getFormatFromDate(d:Date):String
    {
    var year:Number = d.getFullYear();
    var month:Number = d.getMonth();
    var day:Number = d.getDate();
    var hour:Number = d.getHours();
    var minutes:Number = d.getMinutes();
    var seconds:Number = d.getSeconds();

    var s:String = "";
    if(year < 1000)
    {
    if(year < 100)
    {
    if(year < 10)
    {
    if(year < 1)
    {
    s += "0000-";
    }
    else
    {
    s += "000" + year.toString() + "-";
    }
    }
    else
    {
    s += "00" + year.toString() + "-";
    }
    }
    else
    {
    s += "0" + year.toString() + "-";
    }
    }
    else
    {
    s += year.toString() + "-";
    }

    if(month < 10)
    {
    s += "0" + month.toString() + "-";
    }
    else
    {
    s += month.toString() + "-";
    }

    if(day < 10)
    {
    s += "0" + day.toString() + " ";
    }
    else
    {
    s += day.toString() + " ";
    }

    if(hour < 10)
    {
    s += "0" + hour.toString() + ":";
    }
    else
    {
    s += hour.toString() + ":";
    }

    if(minutes < 10)
    {
    s += "0" + minutes.toString() + ":"
    }
    else
    {
    s += minutes.toString() + ":";
    }

    if(seconds < 10)
    {
    s += "0" + seconds.toString();
    }
    else
    {
    s += seconds.toString();
    }

    return s;
    }

    function getDateFromFormat(s:String):Date
    {
    var a:Array = s.split(" ");
    var theDate:String = a[0];
    var theTime:String = a[1];

    var dateArray:Array = theDate.split("-");
    var year:Number = parseInt(dateArray[0]);
    var month:Number = parseInt(dateArray[1]);
    var day:Number = parseInt(dateArray[2]);

    var timeArray:Array = theTime.split(":");
    var hour:Number = parseInt(timeArray[0]);
    var minutes:Number = parseInt(timeArray[1]);
    var seconds:Number = parseInt(timeArray[2]);

    var d:Date = new Date(year, month, day, hour, minutes, seconds);
    return d;
    }
  • Collection & Iterator and Class(cast)

    I learned how to utilize the Collection and Iterator patterns yesterday, thanks to Dan, the Java head (head of Java) at my job. I had previously asked Kenny B awhile ago, and he had explained it just as thoroughly, but typecasting to interfaces was a fuzzy subject, as was why one would do such a thing.

    Additionally, so satisfy Google keyword searchs for said topic since the ones I found were pathetic, I hope to create a new tutorial this weekend on AMFPHP and utilizing the mx.utils.Collection, mx.utils.CollectionImpl, mx.utils.Iterator, and mx.utils.IteratorImpl. Contrary to the docs, the whole dragging of an SWC file to get the classes file to work doesn’t work; I tried. You have to get the files from the AS2 Remoting Source files download, as mentioned at Rich-Internet.

    The only roadblock I’m having with them is I can’t get my authoring component to work. The code itself works beautifully, and I’m overjoyed at how neat Collections and Iterators are; you can do a crapload more than one could do using arrays and looping through them with far less code. However, following the docs to the T, I still couldn’t get my component properties inspector to show anything. If you know, let me know.

    Secondly, something I saw in Moock’s book and in the docs which baffles me is the whole:

    var value:Class = Class(something);

    Now, I know do this to avoid a type-mismatch error:

    var i:Number = 1;
    var o = String(i);
    var str:String = new String(o);
    trace(str); // 1
    trace(typeof(str)); // object
    trace(str instanceof String); // true

    The conversion of i to a string via using the String class constructor makes sense, as does Number (although, I recommend parseInt). But when the docs do like:

    var button:ButtonC = ButtonC(someObj);

    That's weird... it doesn't work. In the example they give for CompactDisk, the constructor does not do any initialization at all. Maybe it works in other languages but you cannot assume that doing the above will work like an attachMovie initialization object, and simply set the class's member variables to the value passed in; it only works for Intrinsic classes OR ones you've specifically wrote yourself. By Intrinsic, I mean:

    s = String(num);
    num = Number(s);
    d = new Date(2004);
    a = new Array("mic", "check");

    But if you make a class CompactDisc, and don't do squat with your constructor, passing in an object into CompactDisc will NOT return a valid object. My example didnt' work till I did this myself:

    function MyCollectionDataConstructor()
    {
    if(arguments[0] != null)
    {
    for(var p in arguments[0])
    {
    this[p] = arguments[0][p];
    }
    }
    }

    When I did that, she worked like a charm. My guess is, in Java or some other language, this just works:

    var val:NewClass = NewClass(o);

    Where o is some object with data, not of class NewClass, and by doing the above it returns a converted instance or something... whatever man, not in Flash. Do the above, and you get the same effect, though.