AS3 Write to File - actionscript-3

The following code only reads files rather than writing to them. I'm using Flash Player not Air and the code must save the data to an external website so FileReference and FileStream won't work.
var Update:URLRequest = new URLRequest("http://freememegames.com/wp-content/uploads/highscore.txt");
var Score:URLVariables = new URLVariables();
var Load:URLLoader = new URLLoader();
Update.method = URLRequestMethod.POST;
Score.Name = "Jack";
Score.Value = "100";
Update.data = Score;
Load.load(Update);
Load.addEventListener(Event.COMPLETE, Complete);
function Complete(e:Event):void {
scores.text = String(e.target.data);
}

You're going to have to send this data to PHP, and then have PHP write it into your text file. Just so you know though, what you're trying to do is prone to hacking, and you'll want to introduce server-side security to thwart people manipulating scores.

Related

Running-order of nested function-calls delayed/altered due to URLloader in AS3?

First of all: English is not my first language. ;-)
I am compiling the following code:
var sqldata:String;
function sql(saveorload,sqlstring) {
var sqlloader = new URLLoader();
var sqlrequest = new URLRequest("http://***/sql.php");
sqlrequest.method = URLRequestMethod.POST;
sqlloader.addEventListener(Event.COMPLETE, sqldonetrace);
var variables:URLVariables = new URLVariables();
variables.sqlm = saveorload;
variables.sqlq = sqlstring;
sqlrequest.data = variables;
sqlloader.load(sqlrequest);
}
function sqldonetrace(e:Event) {
sqldata = e.target.data;
}
sql("1","SELECT * FROM songs WHERE `flag2` LIKE '0'");
trace (sqldata);
So, here comes the problem:
"sqldata" is traced as "null". AS3 seems to run "sql", then "trace" and then "sqldone", but i would need sql -> sqldone -> trace...
I can't put the trace-command in the sqldone-function because it is stored as *.as and loaded at different points in my .swf and not always followed by only a trace-command.
Any Ideas/hints/flaws in script?
Actionscript is, by design, an event driven language. It also guarantees that the code executes in a single thread i.e. if a function call starts, no other(new call) actionscript code would execute until the first call finishes.
That being said, what you should have is to pass a complete handler to sql(...).
function sql(saveorload:String, sqlstring:String, completeHandler:Function):void
{
var sqlloader = new URLLoader();
var sqlrequest = new URLRequest("http://***/sql.php");
sqlrequest.method = URLRequestMethod.POST;
sqlloader.addEventListener(Event.COMPLETE, completeHandler);//tell urlloader to use the complete handler passed in parameters
var variables:URLVariables = new URLVariables();
variables.sqlm = saveorload;
variables.sqlq = sqlstring;
sqlrequest.data = variables;
sqlloader.load(sqlrequest);
}
And then use it from some other place like:
sql("1","SELECT * FROM songs WHERE `flag2` LIKE '0'", sqldonetrace);
function sqldonetrace(e:Event)
{
var sqldata:String = e.target.data;
trace (sqldata);
}
Also, I think you should check for error events from urlloader. Pass another parameter to sql as errorHandler

General security issue about passing parameters to flex application

First of all - my English is bad so I hope you'll understand my problem :)
I'm new to the concept of developing web application with flex and I need your advice on how to keep it secure and what will be the best way to do it.
I'm using red5 recorder (http://www.red5-recorder.com/) To enable users to record a short video about themselves. My application will save a single video, and only for registered users - The user can overwrite previews recorded video (If that exists).
My issue - I will pass a variable to the swf object in the html (generated with php), with encrypt value of the current logged-in user ID (stored in the session). The application use the ID to create the video file and associate it with the current user (video_10.flv, video_193.flv, ...).
It is a simple and basic validation but I don't know what are the possible risks. Are there any other ways to implement and verify the current logged-in user with flex like Ajax request to the server?
EDIT - problem solved. Thank you
I have found an answer to my problem with this code:
private function completeHandler(evt:Event):void {
var username:String = evt.target.data.username;
var email:String = evt.target.data.email;
trace ('username is ' + username);
trace ('email is ' + email);
}
var request:URLRequest = new URLRequest();
var data:URLVariables = new URLVariables();
var loader:URLLoader = new URLLoader();
request.url = "http://example.com/page.php";
request.method = URLRequestMethod.POST;
data.ACTION = "VIDEO"
request.data = data;
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);

How can we call a server side script? whether in a document class or sub-class?

while working with a server side script (php or aspx) which returns some data(from the database) can we call it in a sub-class or do we have to make the calls in the document class itself?
You can make it in either place, but I prefer it being in a sub class that specifically handles interation with web services, to better organize my code. URLRequest + URLLoader are the classes I use for such tasks.
Use this method below to load a php file in the same directory as the SWF files on your server:
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("test.php");
request.method = URLRequestMethod.GET;
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);
function completeHandler(evt:Event) {
instancename1.text = evt.target.data.symbol_1;// or trace()
instancename2.text = evt.target.data.symbol_2;
Below is a simple php Test script:
<?php
$returnVars['symbol_1'] = "item1";
$returnVars['symbol_2'] = "item2";
$returnString = http_build_query($returnVars);
echo $returnString;
?>

AS3 ByteArray " The supplied index is out of bounds" Error

I'm working on an application and I need to save an AS3 object to a db.
Here's what I'm doing:
private function getComplete(e:Event)
{
var getVars:URLVariables = new URLVariables(unescape(e.target.data));
var _saveData_obj = readObjectFromStringBytes( getVars.saveData);
// do something with the save data....
}
public function SaveGame() {
var _save_data:Object = _puzzle.dataForSaving;
var _serialized_string = escape(serializeToString(_save_data));
var _round_time = Math.round( _elapsed_time);
var _token = MD5.hash( _id +
_difficulty +
"mysomewhatsecretstringhere" +
_round_time );
var request:URLRequest =
new URLRequest( _home + 'savegame.php' );
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.saveData = _serialized_string;
variables.time = _round_time;
variables.id = _id;
variables.dif = _difficulty;
variables.token = _token;
request.data = variables;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, postComplete);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public function LoadGame() {
var request:URLRequest =
new URLRequest( _home + 'loadgame.php?id='+_id+"&dif="+_difficulty);
request.method = URLRequestMethod.GET;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, getComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, netError);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public static function serializeToString(value:Object):String{
if(value==null){
throw new Error("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
trace ("Saved: "+bytes.length);
var be:String = Base64.encodeByteArray(bytes);
return be;
}
public static function readObjectFromStringBytes(value:String):Object {
var result:ByteArray=Base64.decodeToByteArray( value) as ByteArray;
result.position = 0;
var the_obj:Object = result.readObject();
return the_obj
}
The problem is that I keep getting a "The supplied index is out of bounds" error when I try to read the object from the Base64 string.... I checked if the saved string and the loaded string are the same. Tried to save the Base64 string to a shared object and retrieve it - that works fine ... the only problem is when I save and load to/from the server.
Can you guys help me? What am I doing wrong?
Thanks.
try using ba.writeMultiByte(string, 'utf-8') and ba.readMultiByte(ba.bytesAvailable, 'utf-8') without converting to object
Ok, so it looks like we've come to a series of steps you can take to debug what's going on.
(In save game) make sure that unescape( variables ).saveData == _puzzle.dataForSaving. If this does not work, then your issue is with either escape or unescape. I have to admit
I am suspicious here, you should never need to escape data for a POST once it has been Base64 encoded (as3crypto's Base 64 encoding will return only one of these characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=. Those are all legit in a POST) and your URLLoader should take care of making it a legit request, so I have difficulty seeing the need.
It is more consistent (and more expected) to have escape and unescape both accept strings as parameters and return strings.
Instead of storing to the database and then retrieving, store to $_SESSION (or, if possible, just echo the value back). This will eliminate PHP as a possible culprit.
In PHP, make sure that $_POST['saveData'] == /* whatever you echo */. If it isn't, then you have a DB encoding issue. You need to make sure that whatever encoding is used in MySQL is the same as the one used in AS.
As an aside, when working with AS, you'll often find it easier to use $_REQUEST instead of $_POST or $_GET. Since the requests are more or less abstracted, the URLRequests of AS don't really need to worry about being RESTful, and it is a heck of a lot easier to work with than exclusively using POSTs.

Trouble with DataEvent.UPLOAD_COMPLETE_DATA not firing

I am having some trouble with an AS3 script to upload data to the server via PHP and then return some values from the PHP upload script. I am using the FileReference.upload() function, and the files are being successfully uploaded, but the eventListener I attached to the DataEvent.UPLOAD_COMPLETE_DATA event is not triggering. Is there something I can do on the PHP end of things to manually trigger this event when the file is done uploading?
as3:
private function onFileLoaded(event:Event):void {
//var _fileReference:FileReference = event.target as FileReference;
//var data:ByteArray = fileReference["data"];
//var filename:String = fileReference.name;
var urlRequest:URLRequest = new URLRequest("http://www.arttoframes.com/canvasSystems/uploadImage.php");
urlRequest.method = URLRequestMethod.POST;
fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete);
fileReference.upload(urlRequest);
}
private function onFileLoadError(event:Event):void {
fileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
fileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
}
private function onUploadComplete(event:Event):void {
trace("ok");
fileReference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
var thumbReferenceName = fileReference.name.substr(0,fileReference.name.indexOf("."))+"_thumb"+fileReference.name.substr(fileReference.name.indexOf("."),4)+"?nocache=" + new Date().getTime()
var urlRequest:URLRequest = new URLRequest("http://www.arttoframes.com/canvasSystems/uploads/Thumbnails/"+thumbReferenceName);
var urlLoader:Loader = new Loader ();
urlLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onDownloadComplete);
//urlLoader.load(urlRequest);
}
So this is a long standing bug that Adobe claims they've fixed, but at least in Flex 3 lots of people claim they can reproduce it even after Adobe says they've fixed it. And that's including yours truly.
https://bugs.adobe.com/jira/browse/FP-1419
I'd employ a work around monitoring the progress directly and when all of it has uploaded manually dispatch the event or just do your work there. There are several work arounds you can try reading the comments in Jira.