Posts tagged with “tips”

May 25, 10

Embedding Private Keys in SWF files

I've recently came across the new online SWF, Zend, and Java decomplier at showmycode.com that allows you to almost "view the source" of the SWF file online. If you had some important data stored in your SWF (such as API keys or passwords) you may not wish them being exposed.
The easiest (and therefore naïve) way to hide them* would be to store them in external text files and embed in the SWF.

[Embed(source="api_key.txt", mimeType="application/octet-stream")]
private const API_KEY:Class;

// ...

var myAPI_KEY:String = String(new API_KEY());

Then you can create an instance and cast it to String, like shown above.

The asset class extends mx.core.ByteArrayAsset and its byte content is not revealed by most decompilers.

*Of course, this "solution" does not offer any serious protection, you can still decompress the SWF and view the keys in the hex editor. You could scramble/hash them a bit to make the hacker's job harder but it's still possible to extract them.

12:46 PM | | 2 Comments | Tags: , ,
February 11, 10

Including imports

Do you remember the #include "filename.as" AS2 directive? It was often used to include predefined prototype functions in AS2. Since using prototypes become obsolete in AS3 (in favour of the inheritance) the include in often underused.

For example, Darron Shall suggests using include directive to mimic multiple inheritance. Recently, I had been given a glimpse of brain damage enlightenment and I started using it again in AS3 for including all project specific libs only. If you want to pass me the hammer now, please read on.

How?

Using wildcards (like import flash.display.*) is often considered a bad practice (or laziness) as we don't know what classes/packages are actually being imported. So we are left with typing all import directives for every class we write. Very commonly we use the same shared functionality (either a framework or built-in classes) in the SWF. The idea is that instead of having to import the same classes in every project class, we can have a list of them in a file, i.e.:

import flash.display.Bitmap;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.setTimeout;
import gs.TweenLite;

and then stop worrying anymore about what needs to be imported.

All you need to do is to place include "../../imports.as"; where your import directives would normally live. I've personally chosen to put it in the same location as the source directory.

package net.blog2t
{
    include "../../imports.as";

    public class Banner extends Sprite
    {
    }
}

Then you can do it for every project specific class you add.

If you're on OS X and using Textmate, you can use the shortcut – F5 key to sort lines and remove duplicated entries.

06:00 PM | | 2 Comments | Tags: , , ,
July 30, 09

Pulling the quotes with CSS

Never thought I was ever gonna blog about the CSS, but this time it's an exception – couldn't find the solution on the web, yet it turned out to be very simple – CSS pullquotes.

Most of the solutions that I found were based on using background elements for quote characters, the problem with this is that the closing quotes are not aligned with the last letter of the quote. So I've tried :before and :after CSS pseudo selectors to inject quotes and it worked fine with Safari4/FF3 but older browsers were ignoring postion: absolute setting on them. No positioning, no joy.

I took the path of the least resistance and used <span> tags to mark the quotes, and here's the result:

...This is just a simple example to show how to style the blockquote element with pullquotes. Happy birthday Mum!


The HTML looks like this:

<blockquote>
   <span class="open">“</span>...This is just a simple example to show how to style the blockquote element with pullquotes.<span class="close">”</span>
</blockquote>

And the CSS:

blockquote {
    font-family: Arial, _sans;
    position: relative;
    text-indent: 15px;
    font-size: 14px;
    line-height: 1.3;
    display: block;
    width: 295px;
    margin: 0;
    }
blockquote span {
    /* Define custom font for quotes here */
    font-family: Georgia, _serif;
    text-indent: 0;
    font-size: 50px;
    position: absolute;
    color: #fc0;
    }
blockquote .open {
    /* May need to adjust the position depending on the font type/size */
    top: -15px;
    left: -5px;
    }
blockquote .close {
    /* May need to adjust the position depending on the font type/size */
    margin-left: 0px;
    /* Alternatively use padding-top */
    margin-top: -5px;
    }
01:10 PM | | 0 Comments | Tags: ,
June 12, 09

The end of anonymous clicks (but don't be afraid)

Recently Google has enabled events tracking for all Analytics accounts – that opens a whole new world for the click hunters – just imagine how useful it might be for usability testing – you can find out if anyone is actually interacting with the new interface that took you 3 weeks to develop.
The official Google Analytics for Flash guide covers pretty much everything what you need to know to set it up for your SWFs and it's all easy peasy when you've got ga.js handy on your HTML page.

But what if you want to give your SWF away (by providing the embed code that links to your SWF) and still be able to track the referrer? You don't know who will be embedding your SWF thus you can't tell if the ga.js will be available.

Fortunately Google covers that matter as well – all you need to do is to import the whole AnalyticsTracker class (which is 100% compatible with the latest ga.js tracking code – at least that's what Google says) available at http://code.google.com/p/gaforflash, set the MODE to AS3 and stop worrying about any Analytics specific Javascript on the HTML page.

All pretty. The only thing is that there's no (direct) way of getting the referrer URL of the SWF that generated the event into your stats, so you won't know who had embedded your file. You could check loaderInfo.url but this will ONLY return the SWF's host location aka your site address and that's no use.

How to get the URL of a page that embeds my SWF then?
There's a simple trick – the page URL is stored in window.location.href and you can use ExternalInterface to get that out. It's actually pretty easy.

Let's go with the example code:

import com.google.analytics.AnalyticsTracker;
import com.google.analytics.GATracker;

const TRACKING_CODE:String = "UA-XXXXXXX-X";
const MODE:String = "AS3";
const DEBUG:Boolean = false;

var GAtracker:AnalyticsTracker;
var referrer:String;

GAtracker = new GATracker(this, TRACKING_CODE, MODE, DEBUG);

if (ExternalInterface.available)
{
    try
    {
        referrer = ExternalInterface.call("window.location.href.toString");
        if (referrer && referrer.indexOf("file:/") != -1) referrer = "localhost";
        if (!referrer) referrer = "unknown";    
    }
    catch (error:SecurityError)
    {
        trace("A SecurityError occurred: " + error.message);
    }
    catch (error:Error)
    {
        trace("An Error occurred: " + error.message);
    }

} else {
    trace("External interface is not available.");
}

As we don't use any Javascript we have to set the tracking code in AS3 along with the MODE set as AS3. Also, there's built-in debugger in the GATracker library which might be actually pretty handy.

Castles in the sand... box
Then we'll try to get the referrer URL – it's important to set <param name="allowscriptaccess" value="always" /> on the <object> tag, and the attribute for the <embed> tag allowscriptaccess="always" in your embed code to allow ExternalInterface access Javascript, otherwise Flash Player will spit out this SecurityError: A SecurityError occurred: Error #2060: Security sandbox violation: ExternalInterface caller [your SWF's host address] cannot access [the URL of the site where your SWF is embedded on].
We can catch it (which we do) but ain't get no URL then.

Got ya, how do I get to track events?
Easy tiger! For example, if you want to track the event of user pressing the video play button to start playback, just fire up this line:

GAtracker.trackEvent("Video", "Play: " + referrer, fileURL);

Where fileURL is the video file URL.

And finally...
Make sure you deploy your SWF on the live site, nothing gets tracked when the SWF is tested in Flash IDE or the local file system as Google explains:

Currently, Flash tracking is available for any Flash content embedded in a web page. Tracking of data sent from Adobe Air, Shockwave, or via the Flash IDE (e.g. using Test Movie) is not supported at this time.

Oh, well.

Any example/demo?
Sure, try to embed the code below on your blog (i.e. as a private post) to see how it works.

<object width="400" height="300" type="application/x-shockwave-flash">
    <param name="movie" value="http://play.blog2t.net/files/event-tracking/tracker.swf" />
    <param name="allowscriptaccess" value="always" />
    <embed
        type="application/x-shockwave-flash"
        width="400" height="300"
        allowscriptaccess="always"
        src="http://play.blog2t.net/files/event-tracking/tracker.swf"
    />
</object>
06:27 PM | | 1 Comment | Tags: , , ,
June 05, 09

Using SWFAddress exclusively with jQuery

I've just spent an hour today trying to work out why SWFAddress was not picking up any events from the browser (i.e. back button click).

It turned out that by default it [SWFAddress] relies on SWFObject, UFO or AC_FL_RunContent but it's not supporting jQuery, which I was using to embed my SWF (precisely with jQuery Flash plugin).

I posted a comment on Asual's blog and I got a quick answer by Rostislav:

@Og2t
You just need to use SWFAddress.addId(flashObjectId) in order to use the library with any Flash embedding script.

Thanks a million! Again and over again, RTFM! SWFAddress is awesome, I am just a moron [*sighs].

Make sure you read this great article on how to use SWFAddress by Greg MacWilliam aka bigmac.

12:30 AM | | 2 Comments | Tags: , , ,
Next → Page 1 of 2