AS3 Error 2038 on Windows only - actionscript-3

hope someone can help me with this!
I've written a simple online 3d editor in Flash - it's about to go out to a selection of clients but the file uploader has a bit of a glitch which has only just reared its ugly head. Using FileReference to upload media to https page, it works like a dream on OSX which is what it was built on, but on Windows it's returning Error 2038 on every browser. Has anyone encountered this before?
Any help much appreciated!
public class CustomFileReferenceList extends FileReferenceList {
private var uploadURL:URLRequest;
private var pendingFiles:Array;
public static var length:int = 0;
public static var arrLen:int = 0;
public function CustomFileReferenceList() {
uploadURL = new URLRequest();
uploadURL.url = "https://___";
var rqd:URLVariables = new URLVariables();
uploadURL.method = URLRequestMethod.POST;
rqd.sessionId = Main.sessionId;
uploadURL.data = rqd;
initializeListListeners();
}
private function initializeListListeners():void {
addEventListener(Event.SELECT, selectHandler);
addEventListener(Event.CANCEL, cancelHandler);
}
private function doOnComplete():void {
//var event:Event = new Event(Uploader.LIST_COMPLETE);
//dispatchEvent(event);
enter code here
}
private function addPendingFile(file:FileReference):void {
pendingFiles.push(file);
file.addEventListener(Event.OPEN, openHandler,false,0,true);
file.addEventListener(Event.COMPLETE, completeHandler,false,0,true);
file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler,false,0,true);
file.addEventListener(ProgressEvent.PROGRESS, progressHandler,false,0,true);
file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler,false,0,true);
file.upload(uploadURL);
}
private function removePendingFile(file:FileReference):void {
for (var i:uint; i < pendingFiles.length; i++) {
if (pendingFiles[i].name == file.name) {
pendingFiles.splice(i, 1);
if (pendingFiles.length == 0) {
doOnComplete();
}
return;
}
}
}
private function selectHandler(event:Event):void {
arrLen = length = fileList.length;
pendingFiles = new Array();
var file:FileReference;
for (var i:uint = 0; i < fileList.length; i++) {
file = FileReference(fileList[i]);
addPendingFile(file);
}
}
private function cancelHandler(event:Event):void {
//var file:FileReference = FileReference(event.target);
}
private function openHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function progressHandler(event:ProgressEvent):void {
var file:FileReference = FileReference(event.target);
}
private function completeHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
length--;
removePendingFile(file);
}
private function httpErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function ioErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
private function securityErrorHandler(event:Event):void {
var file:FileReference = FileReference(event.target);
}
}

After trying just about every solution, the other web dev found it worked ok minus fancy url names i.e referencing ourserver/thepage.php instead of ourserver/service. Absolutely crazy.

I have today this issue, in my case, I was be trace of the length of the source (url/nativePath) and the length of destin; I was found that the length of the destin url is up to 256 characters.
To solve this, I was be changed the destin point (with simbolic link or network drive)
Example:
// MAC remote path
var mSt:String = "file:////MacBook-Pro-de-Jaime.local/Seagate/netShared/transport-machines/SoftDepot/";
// Windows Remote Drive (\\MacBook-Pro-...\transport-machines)
// Remote MAC as Windows Drive N
var mSt:String = "file:///N:/SoftDepot/";
Voila, the new name reduces several characers.

Related

Actionscript 3 Video loop

I want to have embed video in flash game and have it looped. Is there a way to do it? As my code or more likely .seek or .resume dont give any effect? Am I using wrong commands or?
[Embed(source = "fast.flv", mimeType = "application/octet-stream")]
public var bytes:Class;
public var vidNS:NetStream
public var video:Video = new Video(1280, 720);
public var ns:NetStream;
public function Main() {
Doit();
}
private function Doit():void{
addChild(video);
var vidNC:NetConnection = new NetConnection(); vidNC.connect(null);
vidNS = new NetStream(vidNC);
var metaListener :Object = new Object(); metaListener = { onMetaData: process_Metadata };
vidNS.client = metaListener;
vidNS.addEventListener(NetStatusEvent.NET_STATUS, videoStatusHandler);
vidNS.play(null);
var file:ByteArray = new bytes();
vidNS.appendBytes(file);
video.attachNetStream(vidNS);
}
function process_Metadata (in_Data :Object):void
{
trace("duration is : " + in_Data.duration );
}
function videoStatusHandler (event:NetStatusEvent):void
{
if (event.info.code == "NetStream.Buffer.Empty")
{
trace('loop')
vidNS.seek(0); vidNS.resume();
}
}
You can loop by just simply re-feeding the bytes to the decoder (NetStream)
It's possible that you also need to involve the option RESET_BEGIN:
yourNS.appendBytesAction( NetStreamAppendBytesAction.RESET_BEGIN );
Try setting your code like below:
[Embed(source = "fast.flv", mimeType = "application/octet-stream")]
public var bytes:Class;
public var vidNS:NetStream;
public var video:Video = new Video(1280, 720);
public var ns:NetStream;
//# declare these vars outside of a function for global access
public var file:ByteArray = new bytes();
public var vidNC:NetConnection;
public var metaListener :Object;
public function Main()
{
Doit();
}
private function Doit():void
{
addChild(video);
vidNC = new NetConnection(); vidNC.connect(null);
vidNS = new NetStream(vidNC);
metaListener new Object(); metaListener = { onMetaData: process_Metadata };
vidNS.client = metaListener;
vidNS.addEventListener(NetStatusEvent.NET_STATUS, videoStatusHandler);
vidNS.play(null);
//var file:ByteArray = new bytes();
vidNS.appendBytes(file); //# feed video bytes to decoder
video.attachNetStream(vidNS);
}
function process_Metadata (in_Data :Object):void
{
trace("duration is : " + in_Data.duration );
}
function videoStatusHandler (event:NetStatusEvent):void
{
if (event.info.code == "NetStream.Buffer.Empty")
{
trace('now doing: looping...')
//# there is no timeline ".seek" in appendBytes mode, use ".seek" to clear the buffer for a new re-feed
vidNS.seek(0); //clears the current buffer (video data is removed)
vidNS.appendBytesAction( NetStreamAppendBytesAction.RESET_BEGIN ); //re-set timestamps for decoder
vidNS.appendBytes(file); //re-feed video bytes to decoder
}
}
So Thanks to VC. One i ended up with this code:
[Embed(source="1.flv", mimeType="application/octet-stream")]
public var bytes:Class;
public var vidNS:NetStream;
public var video:Video = new Video(1280, 720);
public var file:ByteArray = new bytes();
public var vidNC:NetConnection;
public var metaListener :Object;
public function Main()
{
Doit();
}
private function Doit():void
{
addChild(video);
vidNC = new NetConnection(); vidNC.connect(null);
vidNS = new NetStream(vidNC);
metaListener new Object(); metaListener = { onMetaData: process_Metadata };
vidNS.client = metaListener;
vidNS.play(null);
vidNS.appendBytes(file);
video.attachNetStream(vidNS);
}
function process_Metadata (in_Data :Object):void
{
trace("loop ");
vidNS.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
vidNS.appendBytes(file);
}
Its working like it should, but i'm not sure if thats the right way of doing it ^^.

Why does my proprietary file format fail to unarchive?

I've got a proprietary file format that works as an archive. It takes a folder full of files and packs them into a single file with no compression - the first X bytes of the files are dedicated to the "Table of contents" - the file paths, their size in bytes and their location (byte index) in the archive file. the remaining bytes are for the actual data of each file.
This format works and has been working for several years except in a few cases I am trying to debug. There are some cases where the files fail to unarchive properly In my experience this is typically on laptops which I presume have 5400 rpm hard drives. But sometimes it fail on SSD hard drives (like a Surface Book) Also the failure is not consistent. If I were to unarchive the same file 10 times on a "problem" machine it might only fail 1 or 2 times or not at all in some cases.
In the language that I am unarchiving this format (as3), the file stream reader has property 'readAhead' - which as the docs indicate is 'The minimum amount of data to read from disk when reading files asynchronously' . Could this value be affecting my unarchiving? My initial value for this was '8192' which I have now changed to 8192/4 to test on some new machines. Anyone have any thoughts on this? Is the readAhead value irrelevant?
I realize this is vague. I'm not looking for a specific solution just want to get some feedback from people who have more experience on how I could better diagnose and resolve this issue.
Here is the class in question. I've tried to remove anything unrelated to what I'm asking about:
/**
* ...
* #author Phil
*/
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class Archive extends EventDispatcher
{
public static const UNARCHIVING_COMPLETE:String = "unarchivingComplete";
public static const UNARCHIVING_PROGRESS:String = "unarchivingProgress";
public static const UNARCHIVE_CANCEL:String = "unarchiveCancel";
public static const ENDIAN:String = Endian.LITTLE_ENDIAN;
private var _inputFile:File;
private var _outputFile:File;
private var _inputStream:FileStream;
private var _outputStream:FileStream;
private var _files:Vector.<ArchiveItem>;
private var _readAheadValue:uint = 8192 / 4;
private var _maxTableSize:uint = 40960 * 30;
private var _tableData:ByteArray;
private var _curArchiveItem:ArchiveItem;
private var _currentArchiveItemBytesWritten:uint;
private var _pointerPosition:uint = 0;
private var _tableSize:uint = 0;
private var _totalSize:uint = 0;
private var _totalFiles:uint = 0;
public function Archive()
{
}
public function readArchive(archive:File, dest:File):void
{
_inputFile = archive;
_outputFile = dest;
createReadStream();
createTableData();
_inputStream.openAsync( _inputFile, FileMode.READ );
}
public function destroy():void
{
killStreams();
_inputFile = null;
_outputFile = null;
}
public function cancel():void
{
killStreams();
}
private function killStreams():void
{
killInStream();
killOutStream();
}
private function killInStream():void
{
if (!_inputStream) return;
_inputStream.removeEventListener(Event.COMPLETE, onFileReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onFileReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.CLOSE, onInputClosed);
_inputStream.removeEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
_inputStream.close();
_inputStream = null;
}
private function killOutStream():void
{
if (!_outputStream) return;
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.removeEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.close();
_outputStream = null;
}
private function createTableData():void
{
_files = new Vector.<ArchiveItem>();
_tableData = new ByteArray();
_tableData.endian = ENDIAN;
}
private function createReadStream():void
{
_inputStream = new FileStream();
_inputStream.endian = ENDIAN;
_inputStream.readAhead = _readAheadValue;
_inputStream.addEventListener(Event.CLOSE, onInputClosed);
_inputStream.addEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
}
private function onErrorReadingArchive(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function onArhiveReadComplete(e:Event):void
{
if (_tableData.length < _maxTableSize)
{
onTableReadProgress( null, true);
}
}
private function onTableReadProgress(e:ProgressEvent, force:Boolean = false):void
{
if (_tableData.length < _maxTableSize && force == false)
{
_inputStream.readBytes( _tableData,_tableData.length );
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
populateTable( _tableData );
}
return;
if (_inputStream.bytesAvailable < _maxTableSize && force == false)
{
return;
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
var ba:ByteArray = new ByteArray();
ba.endian = ENDIAN;
_inputStream.readBytes(ba);
populateTable( ba );
}
}
private function populateTable(tableData:ByteArray):void
{
var a:ArchiveItem;
var offset:uint = 0;
var size:uint = 0;
var fileName:String;
if (tableData is ByteArray)
{
tableData.position = 0;
}
for (;;)
{
offset = tableData.readUnsignedInt();
size = tableData.readUnsignedInt();
fileName = tableData.readUTF();
if (fileName == "endTable")
{
_tableSize = tableData.position;
_totalFiles = _files.length;
_totalSize = _inputFile.size;
completeTableRead();
break;
}
a = new ArchiveItem();
a.filename = fileName;
a.offset = offset;
a.size = size;
_files.push(a);
}
}
private function completeTableRead():void
{
createFileOutputStream();
_inputStream.readAhead = _readAheadValue;
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.addEventListener(Event.COMPLETE, onArchiveReadProgress);
writeNextArchiveItemToFile();
}
private function onInputClosed(e:Event):void
{
completeUnarchiving();
}
private function completeUnarchiving():void
{
killStreams();
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function createFileOutputStream():void
{
_outputStream = new FileStream();
_outputStream.endian = ENDIAN;
_outputStream.addEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
}
private function onOutPutClosed(e:Event):void
{
completeUnarchiving();
}
private function onIOError(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function writeNextArchiveItemToFile():void
{
if (_files.length == 0)
{
endWriting();
return;
}
_curArchiveItem = _files.shift();
_currentArchiveItemBytesWritten = 0;
var dest:File = new File();
dest.nativePath = _outputFile.nativePath + File.separator + _curArchiveItem.filename;
_outputStream.open(dest, FileMode.WRITE);
movePointer();
}
private function endWriting():void
{
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArchiveReadProgress);
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.close();
_inputStream.close();
}
private function onOutputStreamCloseOnCompelte(e:Event):void
{
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function movePointer():void
{
_inputStream.position = _tableSize + _curArchiveItem.offset;
_pointerPosition = _inputStream.position;
if (_curArchiveItem.size == 0)
{
writeNextArchiveItemToFile();
}
}
private function onArchiveReadProgress(e:Event):void
{
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
return;
}
writeBytesToDisk();
}
private function writeBytesToDisk():void
{
var bytes:ByteArray = new ByteArray();
var bytesRemaining:uint = _curArchiveItem.size - _currentArchiveItemBytesWritten;
var bytesToWrite:uint = _inputStream.bytesAvailable;
if (bytesToWrite > bytesRemaining)
{
bytesToWrite = bytesRemaining;
}
_inputStream.readBytes(bytes, 0, bytesToWrite);
try {
_outputStream.writeBytes(bytes, 0, bytes.length); //This throws an error on large files.
}catch (e:Error)
{
dispatchEvent( new Event(Event.CANCEL) );
return;
}
_currentArchiveItemBytesWritten += bytes.length;
_pointerPosition = _inputStream.position;
dispatchEvent( new Event(UNARCHIVING_PROGRESS) );
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
}
}
}
}
class ArchiveItem
{
public var offset:uint;
public var size:uint;
public var filename:String;
public function ArchiveItem()
{
}
}
This was too long for comments..
Just my personal opinion but I think you've over-cooked a simple task. Your usage of .readAhead is confusing. For un-archive part why not have..
(1) On startup your app creates & fills an Object with entries parsed from table of contents (myself I'd just make & update 3 arrays noting file Names, Sizes and also the Indices within the archive file).
(2) For extracting say the 5th file in archive you just check dest_Name = fileNames[4]; for expected output name String, then also note expected dest_Size = size[4]; integer (length to extract).
(3) Now just read the archive file (on disk) and get that 5th file saved.
Archive_Stream.openAsync( URL_Archive_File, FileMode.READ );
Archive_Stream.position = dest_indexInArchive[4]; //starting index
The above would read bytes into a temp_BA which can then be saved (when READ is complete, the handler function does a WRITE to disk of that single extracted file). Now you can use temp_BA.clear(); to reset and clear it for a different file (or just reclaim memory used).

Dynamic Object Name in AS3

I have this code in my MXML project, I want to get dynamic Stream connection for different and dynamic usernames.
private var inStream:NetStream;
private function listenStream(user:String):void
{
this["inStream"+user] = new NetStream(connection);
this["inStream"+user].play(user);
}
private function closeStream(user:String):void
{
//clear stream listener
this["inStream"+user].close();
}
But this code is not worked, How can i build dynamic object names in ActionScript3?
Thanks alot
Try Dictionary
import flash.utils.Dictionary
private var streamDict:Dictionary = new Dictionary();
private function listenStream(user:String):void
{
var key:String = getKey(user);
var lastStream:NetStream = streamDict[key] as NetStream;
if (lastStream)
{
//close the last stream or do sth else
}
else
{
streamDict[key] = new NetStream(connection);
streamDict[key].play(user);
}
}
private function closeStream(user:String):void
{
var key:String = getKey(user);
//clear stream listener
var stream:NetStream = streamDict[key] as NetStream ;
if (stream)
{
stream.close();
}
//delete the stream
streamDict[key] = null;
delete streamDict[key];
}
private function getKey(user:String):String
{
return "inStream" + user;
}

Add complete contact object from Facebook to SqLite

I can't add name and image from Facebook contacts to SqLite, becouse adding is inside in loop and loader start when Event is Complete. Fllowing code adds data to the database, but in the name of the object is the last person out of the loop. Any thoughts? Thanks!
private var person:PersonVO;
protected function handleFriendsLoad(response:Object, fail:Object):void
{
if (fail) { return }
var friends:Array = response as Array;
var l:uint=friends.length;
for (var i:uint=0;i<l;i++) {
var friend:Object = friends[i];
FacebookDesktop.api('/'+friend.id, loadData);
}
}
private function loadData(object:Object, fail:Object):void
{
if (fail) { return; }
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageToByteArray);
loader.load(new URLRequest(FacebookDesktop.getImageUrl(object.id, 'large')));
person = new PersonVO()
person.name = object.first_name;
}
private function imageToByteArray(event:Event):void
{
var wczytaj:Loader = (event.target as LoaderInfo).loader;
var image:Bitmap = Bitmap(wczytaj.content);
var encoderJpeg:JPEGEncoder = new JPEGEncoder();
var byteArray:ByteArray = encoderJpeg.encode(image.bitmapData);
person.image= byteArray;
insert(person);
}
private function insert(person:PersonVO):void
{
dbStatement.text = "INSERT INTO person (name,image) values(:name,:jpeg)";
dbStatement.parameters[":name"] = person.name;
dbStatement.parameters[":jpeg"] = person.image;
dbStatement.execute();
}
Extend Loader class functionality:
dynamic class DynamicLoader extends Loader{}
Then store whatever you want in instances of DynamicLoader:
private function loadData(object:Object, fail:Object):void
{
if (fail) { return; }
var person:PersonVO = new PersonVO();
person.name = object.first_name;
var loader:DynamicLoader = new DynamicLoader();
loader.person = person;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageToByteArray);
loader.load(new URLRequest(FacebookDesktop.getImageUrl(object.id, 'large')));
}
private function imageToByteArray(event:Event):void
{
var wczytaj:DynamicLoader = (event.target as LoaderInfo).loader as DynamicLoader;
var image:Bitmap = Bitmap(wczytaj.content);
var encoderJpeg:JPEGEncoder = new JPEGEncoder();
var byteArray:ByteArray = encoderJpeg.encode(image.bitmapData);
var person:PersonVO = wczytaj.person;
person.image= byteArray;
insert(person);
}
I have not used private var person:PersonVO;. So if you are not using it in the other methods of your class, you could remove it completely.

AS3 object array to class

I am new and having an issue with the use of classes in as3.
I have created an array of objects in my main timeline
function badPlayer()
{
var bads:Array = new Array();
for (var i=0; i<5; i++)
{
var mc = new bman();
mc.name=["mc"+i];
bads.push(mc);
_backGround.addChild(mc);
mc.x = 100;
mc.y = 100;
trace (bads);
Baddies(_backGround.mc); //here I am trying to export mc to my class
}
}
Here is a snip-it from my class. My trace statement wont even output.
public class Baddies extends MovieClip
{
private var pistolSound:pistolShot = new pistolShot();
//private var mc = new mc();
private var _rotateSpeedMax:Number = 2;
private var _gravity:Number = .68;
private var _bulletSpeed:Number = 2;
private var _maxDistance:Number = 200;
private var _reloadSpeed:Number = 500; //milliseconds
private var _barrelLength:Number = 20;
private var _bulletSpread:Number = 5;
private var _isLoaded:Boolean = true;
private var _isFiring:Boolean = true;
private var _endX:Number;
private var _endY:Number;
private var _startX:Number;
private var _startY:Number;
private var _reloadTimer:Timer;
private var _bullets:Array = [];
private var _gun:MovieClip;
private var _enemy:MovieClip;
private var _yx:Number;
private var _yy:Number;
private var _pcos:Number;
private var _psin:Number;
private var _trueRotation:Number;
public function Baddies()
{
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
Basically I am trying to create several bad guys (bman) and have the same code apply to each of them. I have also tried to change the linkage name of bman to Baddies with no success.
There are a few thing that are very wrong with this code.
Baddies(_backGround.mc); //here I am trying to export mc to my class
This is a typecast, as already stated in the comments. By the way Baddies isn't a good name, because it plural. You probably want to create a new bad guy, which would be done with this line:
var baddie = new Baddies();
Now your constructor uses the stage variable. This won't work because the object isn't on the stage, therefore stage is null (it may works if you drag and drop an instance to the stage in the editor). So before using the stage you actually need to add the object to the stage:
public function Baddies() {
trace("new baddie created");
}
public function init(mc:MovieClip) {
mc.addChild(this); // display this baddie
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
And in the badPlayer function:
var baddie = new Baddies();
baddie.init(_backGround);