Loading an image from outter resources flash - actionscript-3

After a week of trying different methods, my last resort is to ask you guys about my problem with ActionScript Loader.
I cannot load an image from the URL using Loader as it works on my another application. I simply don't know where is the difference in the code. I cannot even debug the content of Loader object because simply trying to peek what's in there throws an exception.
My code is:
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, onLoadedBytes);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, passEvent);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, passEvent);
urlLoader.load(new URLRequest(url));
Normal loader:
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, passEvent);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, passEvent);
loader.load(new URLRequest(url), new LoaderContext(true));
Loading related methods:
private function onLoadedBytes(e:Event):void
{
var ba:ByteArray = e.target.data;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
loader.loadBytes(ba);
}
private function onImageLoaded(e:Event):void
{
_bitmapData = e.target.content.bitmapData;
dispatchEvent(new Event(Event.COMPLETE));
}
Any idea how to fix it? The domain I try to load an image from is VK Games (http://vk.com/playfreegames) and the image is app-game related.
I've searched the stack for an answer, but none of the solutions presented solved my case.

It's a security issue. From the docs: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html
"If the loaded content is an image, its data cannot be accessed by a SWF file outside of the security sandbox, unless the domain of that SWF file was included in a URL policy file at the origin domain of the image."
If you listen to the security events, you'll probably see it giving an error. Loader works because you're just accessing the image, so it's fine, however URLLoader in BINARY mode won't as you're trying to access the pixel data, hence the security error. If you tried to access the pixel data through the Loader, you'll probably get the same error.
Either just load it without accessing the BitmapData behind (includes applying filters etc), or use a cross domain file

If I remember right, having SWF file on server A and images on server B requires a crossdomain.xml file on server B, in order to allow the swf to load the images.
http://kb2.adobe.com/cps/142/tn_14213.html
--
I would recommend to use a library for loading like LoaderMax or Hydotics/Queloader...
greensock com/loadermax/
github com/hydrotik/QueueLoader/wiki

Related

Adobe Air loading external swf with allowDomain('*') inside

What i have
Large amount of swfs without it's sources (so i couldn't modify its)
What i need
To load and play this swfs with my AIR app.
The problem
The problem is that this swfs seems having
Security.allowDomain('*')
in their source, so they would throw
SecurityError: Error #3207: Application-sandbox content cannot access
this feature.
after i load it. I know that Air doesn't need to use this line, but instead of ignoring or warning on it my full app would stop to executing after loading one of this swfs. If only i could try/catch this string, but as i said i don't have an source of that swfs, so the only thing i could do is to modify my AIR app.
What i tried
What i already tried is to catch all errors inside loader by doning
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loaderIOErrorHandler);
private function loaderIOErrorHandler(e:IOErrorEvent):void {
e.preventDefault();
}
but it seems it isn't catch errors inside loader at all
Update
I couldn't share one of this swfs, but here is simulation i made that reproduce problem https://www.dropbox.com/s/0spbdzijfpboi47/problematicSwf.swf?dl=0
Here it's init code
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
Security.allowDomain('*');
tf = new TextField();
tf.text = 'Me loaded!';
addChild(tf);
}
As you could see it is crashing on allowDomain inside loaded swf.
And here is how i load it
var ctx:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest(path), ctx);
This is a typical security restriction but it's a very strict one and it's purpose is to make sure the served swf will never be used outside of what it was made for in the first place.
So the short answer to your problem is this: externally loaded swf that are sandboxed with "Security.allowDomain('*');" will not allow a sandboxed AIR app to interact with them in anyway. Instead those swf will be able to interact with the parent AIR app under restrictions via a sandbox bridge.
If truly you cannot modify those swf then you will never be able to add them to a display list in a AIR app or call any of their methods. A sandbox bridge will also be of no use to you.
It's not the answer you want to hear I bet but it's the only one you'll get.

AS3: Cannot access a property or method of a null object reference at $iinit while loading external swf

I have two swfs, that works perfect separately, but when i try to load one to other, it shows me "Cannot access a property or method of a null object reference at Creator$iinit".
First SWF is login screen, second is register screen. I load them in this way:
var requestA:URLRequest = new URLRequest("Creator.swf");
var loader:Loader = new Loader();
loader.load(requestA);
addChild(loader);
I have no idea whats wrong. Please, help.
Most likely you're trying to access something that is not available immediately on load and init - you'll need to add some code in the Creator.swf like:
// Somewhere in the first lines of code
addEventListener(Event.ADDED_TO_STAGE, this.ready);
function ready(e:Event) {
removeEventListener(Event.ADDED_TO_STAGE, this.ready);
// ** Do other initialization stuff here
}
What's happening is that you're trying to access the stage or objects before things are ready to accept them.

Loader.load and Loader.loadBytes differences

I'm loading as2 swf into AIR application. It works properly when loaded from file. But when loaded from bytes, it is broken in some way (it reacts to mouse, but some elements are inactive)
var bytes:ByteArray = ... //loaded from resources
var loader:Loader = new Loader();
var context:LoaderContext = new LoaderContext(false);
context.allowCodeImport = true; //this is neccessary
// Method 1 - blocks some scripts in loaded SWF
//context.applicationDomain = new ApplicationDomain();
// (application domain has no effect with as2 swf)
//context.securityDomain = SecurityDomain.currentDomain; //gives error 2114: securityDomain must be null
loader.loadBytes(bytes, context);
// Method 2 - loads properly
//loader.load(new URLRequest(file.url));
So why not just load it from file? My resources are protected with encryption and I can't dump them to disk - they must still be protected.
What tricks may exist to load from bytes properly?
There is similar question, but in my case as2 causes more problems.
AS2 and AS3 use different runtimes (bytecode is different) so you won't be able to properly execute any AS2 bytecode in the AS3 runtime. you are basically injecting AS2 code into your AS3 application, so it ain't gonna work :/
According the the documentation for LoaderContext you should only use the applicationDomain property only when loading ActionScript 3.0 SWFs. Try dropping that parameter (or setting it to null) and see what happens.
It seems that old SWF movies (AS1 and AS2, which require AVM1) loaded into an AIR app with load get put in their own domains, but those loaded with loadBytes share a domain. So if you have multiple AVM1 SWFs loaded with loadBytes their _global properties will clobber each other. This affects the Flash MX UI components (ca. 2002).
I can't be the only one trying to package ancient Flash files in AIR apps, so I figure this info may be useful to someone.

loading as2 in as3 from different domain

I'm trying to load swf like this :
var _mcl:Loader= new Loader();
var loader_context:LoaderContext= new LoaderContext();
loader_context.securityDomain= SecurityDomain.currentDomain;
_mcl.load(new URLRequest(p_url), loader_context);
_mcl.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImageComplete);
_mcl.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadImageError);
_mcl.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadImageError);
but the problem is that some of the swf are in AS2 and their script don't excute (a simple stop() on the last frame is not executed and the movie loops)
If I remove
loader_context.securityDomain= SecurityDomain.currentDomain;
it works, the AS2 files scripts are executed but flash throws a security error for the swf that come from a different domain
So I'm wondering if there is a way in an AS3 file to load AS2 swf from another domain ?
thanks
provided you have access , wouldn't a crossdomain policy file solve the problem?

Can an AS2 swf be loaded into an AS3 swf? How can I add this to the stage and interact with it from As3 swf?

I am trying to load a swf written in AS2 into an AS3 swf - using Loader class and listening for Event.COMPLETE. in my onCompleteHandler function i want to add this to the stage so Im trying -
addChild(evt.currentTarget.content)
... but I get the following error message:
Error #2180: It is illegal to move AVM1 content (AS1 or AS2) to a different part of the displayList when it has been loaded into AVM2 (AS3) content.
The AS2 swwf has a lot of code and I really dont want to have to migrate to AS3 if I can avoid it. Anybody know if this is possible or know of a differnt way to add the loaded swf to the stage. How do I then go about calling functions in the loaded swf?
Here is a code snippet -
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
var request:URLRequest = new URLRequest("testLoadSwf.swf");
loader.load(request);
function onCompleteHandler(evt:Event) {
addChild(evt.currentTarget.content);
}
Thanks all.
The only really effective way to do this is by using LocalConnection. AS2 and AS3 can't communicate much with each other. If you still have access to the AS2 file's source, you can expose some functions with LocalConnection. There's also a neat helper class by Grant Skinner called SWFBridge that takes some of the groundwork out of doing this, it's available here: http://www.gskinner.com/blog/archives/2007/07/swfbridge_easie.html
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
var request:URLRequest = new URLRequest("testLoadSwf.swf");
loader.load(request);
function onCompleteHandler(evt:Event) {
//addChild(evt.currentTarget.content);
}
addChild(loader)